# https://www.robotstxt.org/robotstxt.html User-agent: * # Block API and server-side routes — bots should never hit these Disallow: /api/ # Block auth flows — no indexable content and avoids crawl budget waste Disallow: /auth/ # Block parameterised finder URLs (/finder?q=dress etc.) — search result pages # have no unique value and waste crawl budget. /finder itself stays indexable. Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no # Allow everything else — product, outfit, feed, finder, and static pages are all indexable Allow: / Sitemap: https://hypsh.com/sitemap.xml # --------------------------------------------------------------------------- # AI crawlers — training bots blocked, retrieval/search bots allowed. # # Training bots scrape content to build AI models — we get no citation value # from them. Retrieval bots are what actually surfaces the site in ChatGPT # Shopping, Perplexity, Claude, etc. — blocking them removes us from AI answers. # # Note: Bytespider ignores robots.txt ~90% of the time; block at WAF/edge too. # # Content-Signal (https://contentsignals.org, IETF draft-romm-aipref-contentsignals) # states the same policy as a machine-readable usage preference, for crawlers that # read it instead of (or as well as) matching their own user-agent group: # search=yes search index + links/snippets # ai-input=yes retrieval / grounding for AI answers (the citations we want) # ai-train=no training or fine-tuning models # It is repeated in every allowed group for the same reason the Disallow lines # are: a crawler reads only its own most specific group (RFC 9309). # --------------------------------------------------------------------------- # -- Block: training scrapers (no citation benefit) -- User-agent: GPTBot Disallow: / User-agent: ClaudeBot Disallow: / User-agent: Google-Extended Disallow: / User-agent: CCBot Disallow: / User-agent: Bytespider Disallow: / User-agent: Meta-ExternalAgent Disallow: / # -- Allow: retrieval and search indexing bots (these drive AI citations) -- # # Each group repeats the wildcard group's Disallow lines on purpose. A crawler # obeys only the SINGLE most specific group that matches it (RFC 9309) — named # groups replace the `*` group, they do not extend it. Omitting /finder? here # would hand these bots the unbounded ?q= permutation space that line 10 exists # to keep out. check_prerender_bots.py asserts this holds. User-agent: OAI-SearchBot Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: ChatGPT-User Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: Claude-User Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: Claude-SearchBot Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: PerplexityBot Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: Perplexity-User Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: Amazonbot Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no # Note: Meta-ExternalFetcher (retrieval) is the counterpart to # Meta-ExternalAgent (training, blocked above) — they are different bots. User-agent: Meta-ExternalFetcher Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: MistralAI-User Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: DuckAssistBot Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no User-agent: Google-CloudVertexBot Allow: / Disallow: /api/ Disallow: /auth/ Disallow: /finder? Content-Signal: search=yes, ai-input=yes, ai-train=no # These four were already permitted by the `User-agent: *` / `Allow: /` rule # above; they are named explicitly so this file and the nginx prerender map in # tools/nginx-prerender.conf.snippet can be diffed against each other. A bot # allowed here but absent there is told to crawl and then served an empty SPA # shell, which is the failure this pairing exists to make visible.