User-agent: * Allow: / # Block internal/admin/test routes Disallow: /Admin Disallow: /dashboard Disallow: /TestTracking Disallow: /TestAPI Disallow: /TestStandardAPI Disallow: /Diagnostics Disallow: /VPSTest Disallow: /Architecture Disallow: /ComingSoon Disallow: /auth/ Disallow: /api/ Disallow: /profile/ Disallow: /Profile Disallow: /productsearch Disallow: /connect-extension Disallow: /extension/ Disallow: /stores/amazon Disallow: /stores/temu Disallow: /*?page= Disallow: /*?sort= # Googlebot executes JS and indexes the RENDERED DOM, not the HTML we ship. # Every public page below hydrates and re-fetches its own content from these # read-only endpoints. While they were blocked, the client-side catch branch # overwrote good prerendered content with an error state — that is what put #

Error

under HTTP 200 on the 12 legal pages. Prerendering fixes the # HTML we serve; these Allow rules fix what the crawler ends up with. They are # two different halves of the same problem, and fixing only one leaves the bug. # # Longest match wins, so each rule below overrides "Disallow: /api/" above. # Everything not listed stays blocked. Two deliberate absences: # /api/legal/consent* per-user consent state, not page content # /api/top-products admin-only (clicks.routes.js:45 wraps it in adminAuth, # prod answers 401) and read by components/admin/ClickAnalytics.jsx # alone — no public page renders from it, so allowing it # would advertise an admin path and still serve a crawler # nothing. Every rule below was re-verified against prod # on 2026-08-05: all answer 200 unauthenticated. Allow: /api/legal/cookies-policy/ Allow: /api/legal/privacy-policy/ Allow: /api/legal/terms-of-service/ Allow: /api/legal/disclaimer/ Allow: /api/deals Allow: /api/videos Allow: /api/promo-codes Allow: /api/featured-products Allow: /api/hybrid-search/ # Path-based i18n: the router mounts every route under /ru and /he as well, so # each private route above is reachable under those prefixes too. Without these # the locale-prefixed copies stay crawlable (GSC flagged /ru/dashboard and # /ru/Profile) — the rules above are plain prefixes and do not cover them. Disallow: /ru/Admin Disallow: /ru/dashboard Disallow: /ru/TestTracking Disallow: /ru/TestAPI Disallow: /ru/TestStandardAPI Disallow: /ru/Diagnostics Disallow: /ru/VPSTest Disallow: /ru/Architecture Disallow: /ru/ComingSoon Disallow: /ru/auth/ Disallow: /ru/profile/ Disallow: /ru/Profile Disallow: /ru/productsearch Disallow: /ru/connect-extension Disallow: /ru/extension/ Disallow: /ru/stores/amazon Disallow: /ru/stores/temu Disallow: /he/Admin Disallow: /he/dashboard Disallow: /he/TestTracking Disallow: /he/TestAPI Disallow: /he/TestStandardAPI Disallow: /he/Diagnostics Disallow: /he/VPSTest Disallow: /he/Architecture Disallow: /he/ComingSoon Disallow: /he/auth/ Disallow: /he/profile/ Disallow: /he/Profile Disallow: /he/productsearch Disallow: /he/connect-extension Disallow: /he/extension/ Disallow: /he/stores/amazon Disallow: /he/stores/temu # /recovery/verify is allowed by nginx but not prerendered, so it falls through # to the SPA fallback and serves the HOME page's static HTML — canonical and the # whole hreflang cluster pointing at "/". That is what produced the "hreflang # conflicts within page source code" findings. It is a transactional page that # must keep working, so it is blocked from crawling rather than redirected. # (Dead aliases in the same situation — /cookie-policy, /referral-program — are # 301'd in nginx instead: a removed page needs a redirect, not a crawl block.) Disallow: /recovery/verify Disallow: /ru/recovery/verify Disallow: /he/recovery/verify Sitemap: https://cashbackpro.org/sitemap.xml