The rule, for your team's review

Rule version 0.1, draft of 21 October 2026, prepared by AnswerShare. Nothing here is deployed. Your team reviews, edits, merges and deploys it.

What we propose, and why

We propose a Next.js rewrite rule in next.config.js, in the beforeFiles phase, that sends page requests from named AI crawlers to AnswerShare as an external rewrite. We are not proposing middleware, and the rule does not go in vercel.json.

How it decides

  1. User agent only. The rule reads the request's User-Agent header. It never looks at IP addresses or networks.
  2. Named AI crawlers in. A request is routed only if its user agent contains one of the AI crawler names in the list below. The list comes from AnswerShare's canonical crawler classification, the AI_BOTS set in src/bot-classification.ts of our shared library (aryah-shared), at commit b43382d of 2 October 2026. Changes reach you only as pull requests.
  3. Search crawlers out, always. The rule refuses any user agent that contains a search crawler's name, even one that also contains an AI name. That list is our SEARCH_BOTS set from the same file: Googlebot in all its variants, Google-InspectionTool (Search Console's inspection tool), Bingbot, Applebot, DuckDuckBot, YandexBot, Baiduspider and PetalBot. Everyone else, including every person, gets your site untouched.
  4. Pages only. The rule skips Next.js internals (/_next/), /api/, /_vercel/, /.well-known/ and any path ending in a file extension: images, scripts, styles, icons, robots.txt, sitemap.xml and manifest.webmanifest. None of the 497 page addresses in your sitemap ends in a file extension, so every page is covered and every asset is excluded.
  5. Not in-app requests or form submissions. The rule also skips any request carrying the RSC header (Next.js in-app navigation data) or the Next-Action header (Next.js form submissions), and /api/ is excluded by path. We found no checkout, cart or account pages on www; the rental portal sign-up page is an ordinary page with a form.

    Question for HOLT: Does www have any other account, checkout or transaction paths we should exclude from the rule?

  6. English and Spanish alike. Next.js runs your existing language middleware first and this rule after it, so the rule covers English pages at / and Spanish pages under /es-US. We test both on the preview.

Matching is case-sensitive, because Next.js header patterns are. Each name matches as written in the list and in lower case, which covers the published user agent of every crawler on the list. A crawler that spells its name with some other capitalisation gets your normal page, which is the safe direction.

What reaches AnswerShare

Only requests that match the rule. Vercel forwards the crawler's request as it arrived: the page path and query, the crawler's user agent and its other request headers, plus Vercel's standard forwarding headers (x-forwarded-for, x-real-ip, x-forwarded-host, x-forwarded-proto), which carry the crawler's IP address. Requests from people and search crawlers never match, so nothing from them reaches us. This is the same description we gave in our answer to your question 13.

Every response we send back is marked Cache-Control: private, no-store. Vercel honours upstream cache headers on external rewrites, so it does not store the AI version, and an AI copy never sits in a cache where a visitor could get it.

If AnswerShare errors or times out

The rule points at an AnswerShare edge service that builds each response. Here is what an AI crawler gets in each case. In every case, people and search crawlers get your normal page, because their requests never reach us.

CaseWhat the AI crawler gets
NormalThe AI version of the page, status 200.
The page has no AI version yet (for example, a page you published minutes ago)Your normal page. Our edge service fetches it from your site and returns it unchanged. That fetch carries a pass-through header the rule excludes, so it cannot loop back to us.
Our content service fails or is slowYour normal page, the same way, once our time budget runs out [CONFIRM: time budget, proposed 2.5 seconds].
Your site is slow or down when our edge service fetches your pageStatus 502 from our edge service, if your page has not arrived within 10 seconds or the fetch fails.
Our edge service itself is down or unreachableAn error from Vercel, status 502 (ROUTER_EXTERNAL_TARGET_CONNECTION_ERROR). There is no fallback to your page in this case.
Our edge service accepts the connection but never answersVercel waits up to its 120-second limit for external rewrites, then returns 502 (ROUTER_EXTERNAL_TARGET_ERROR).

The last two cases are the cost of having no code on your visitors' requests. A crawler that gets an error retries later. The stop conditions in the plan call for a revert if failures pass 1% of AI-crawler requests in an hour or last 15 minutes.

The fall-back to your normal page in the second and third rows is built and running on our side. On 22 October 2026 we sent GPTBot requests for your home page and for /es-US to our edge service. Each got your own page back with status 200, marked Cache-Control: private, no-store and x-answershare-variant: passthrough, in under 2 seconds. We test it again on your preview (tests T14 and T15).

Blast radius of each failure

For each failure below: what your human layer gets (your visitors, plus Googlebot and the other search crawlers), what our layer gets (the AI crawlers on the list, and the records we keep), how the failure is detected, and how it is contained. Three things hold in every case.

The page has no AI version yet

Your human layerNo change. Visitors and search crawlers get your page as they do today, on every page, at its normal speed.
Our layerThe AI crawler gets your normal page, status 200, instead of the AI version. This affects that page only, until its AI version is published. The crawler waits slightly longer: 0.7 to 1.7 seconds for the whole round trip in our 22 October check. If the rule went live today this would apply to every page, English and Spanish: the AI versions are still in review and none is live. Today this leaves no record on our side.
Detected byThis is the designed behaviour, not an alarm. Each such response is marked x-answershare-variant: passthrough and x-answershare-passthrough-reason: miss.
Contained byThe fall-back, automatically, on each request. There is nothing to revert. It ends for a page when that page's AI version is published.

Our content service fails or is slow

Your human layerNo change.
Our layerThe AI crawler gets your normal page, status 200, instead of the AI version. It gets it at once if our content service errors, or after our time budget if the service is slow. This covers every page for as long as the fault lasts. Nothing is recorded on our side today.
Detected byOur every-minute uptime check, once your site is added to it (see the note below).
Contained byThe fall-back, automatically, on each request. We fix the cause on our side. If it is not fixed within the hour, the stop conditions call for a revert.

Your site is slow or down when our edge service fetches your page

Your human layerWhatever your site gives visitors at that moment. The rule adds nothing to it, because their requests never reach us.
Our layerThis happens only when a page also has no AI version, or our content service has failed. Our fall-back fetch then waits up to 10 seconds for your page. If your page has not arrived by then, or the fetch fails, the AI crawler gets status 502 from us instead of your slow page. Without the rule, it would have waited on your site directly. This lasts as long as your site is slow, and it leaves no record on our side today.
Detected byYour own monitoring of your site. Our check sees a 502 marked x-answershare-passthrough-reason: live-failed.
Contained byIt ends when your site recovers. There is nothing to revert.

Our edge service is down or unreachable

Your human layerNo change for visitors or search crawlers. Two side effects reach people:

(1) If FacebookExternalHit stays on the list, links to your pages shared on Facebook, Messenger or WhatsApp during the outage may appear without a title and image. This applies to pages Meta has not already stored a preview for. Removing that entry removes this effect.

(2) If you keep Rule 2, /llms.txt and /llms-full.txt return an error to everyone during the outage. Both return 404 today.
Our layerEvery AI-crawler page request gets Vercel's 502, on every page, English and Spanish, for as long as the outage lasts. That includes user-triggered fetchers such as ChatGPT-User, Claude-User and Perplexity-User: an assistant fetching your page for a person's question gets no page. Nothing reaches us, so we record nothing. Only your Vercel logs show these requests.
Detected byOur every-minute uptime check, once your site is added to it. It marks a check as down after 3 failures in a row, about 3 minutes.
Contained byA revert, which only your team can make, because the rule lives in your deployment. The stop conditions call for one when failures pass 1% of AI-crawler requests in an hour, or run 15 minutes in a row. Instant Rollback takes effect without a rebuild. We time it on the preview (test T18). Until the rollback lands, AI crawlers keep getting 502. People and search crawlers are unaffected throughout.

Our edge service accepts the connection but never answers

Your human layerThe same as the case above. Visitors and search crawlers see no change. Shared-link previews and the two optional files wait up to 120 seconds and then fail.
Our layerEach AI-crawler request waits up to Vercel's 120 seconds, then gets 502. Our edge service caps its own work at 2.5 seconds for the AI version plus 10 seconds for the fall-back. So this case arises only if the edge platform itself hangs. Nothing is recorded on our side.
Detected byThe same every-minute check. It counts a check as failed if no answer arrives within 15 seconds.
Contained byThe same revert as the case above.
Detection is not in place for your site yet. Our every-minute uptime check does not watch Texas First Rentals today. It also cannot yet send an AI crawler's user agent, so it would not see the failures above. Before the preview we add three checks of one of your pages, each run every minute: as GPTBot through your rule, as a browser, and as Googlebot. Until the rule is live, the GPTBot check goes straight to our edge service. Each check alerts after 3 failures in a row. Until then, the failure cases above depend on your Vercel logs and on the tests we run on the preview.

The alternative, if you prefer it. If HOLT would rather AI crawlers always fall back to your page, even when our edge service is down, the way to do that is a small Next.js middleware with a timeout: if we do not answer within 2.5 seconds, the request falls through to your normal page. That is the middleware design in our 8 October overview, with the credential kept in your environment variables as you asked. Its costs are the ones listed above: code on every page request, a credential in your environment variables, and upkeep across Next.js releases. We recommend the rule. We will provide the middleware for review if you choose it.

The snippet

For next.config.js. If your config is next.config.mjs or next.config.ts, the same object goes in your existing export. If you already have rewrites, keep them: a rewrites() that returns an array maps to afterFiles below.

// AnswerShare AI-crawler rule for www.texasfirstrentals.com (rule v0.1, test run)
// Crawler names: AnswerShare aryah-shared src/bot-classification.ts,
// AI_BOTS and SEARCH_BOTS at commit b43382d (2 October 2026).
// Matching is by user agent only. No IP or network lookups.
// To remove: delete this block and the answershareRewrites entry in rewrites().

const ANSWERSHARE_ORIGIN = 'https://customers.texasfirstrentals.production.answershare.com';

// AI crawlers and AI agents that get the AI version of a page.
const AI_CRAWLERS = [
  // OpenAI
  'GPTBot', 'OAI-SearchBot', 'ChatGPT-User', 'ChatGPT',
  // Anthropic
  'ClaudeBot', 'Claude-SearchBot', 'Claude-User', 'claude-web', 'anthropic-ai',
  // Perplexity
  'PerplexityBot', 'Perplexity-User',
  // Google AI agents: not search crawlers. Remove any you prefer.
  'Gemini-Deep-Research', 'Gemini-Research', 'Gemini-User', 'GeminiBot', 'Gemini-AI',
  'GoogleAgent-Mariner', 'GoogleAgent-URLContext', 'Google-CloudVertexBot',
  'GoogleOther', 'Google-Extended',
  // Apple: AI only. Plain Applebot is a search crawler and is excluded below.
  'Applebot-Extended',
  // Meta
  'Meta-ExternalAgent', 'FacebookExternalHit',
  // Others
  'Bytespider', 'Amazonbot', 'YouBot', 'Diffbot', 'CCBot', 'Cohere-AI',
  'DeepSeekBot', 'MistralAI-User', 'Qwen-Bot', 'GrokBot', 'xAI-Grok', 'Grok-DeepSearch',
  // AnswerShare's own measurement crawler
  'AnswerShareBot',
];

// Search crawlers always get your normal site, even if a user agent
// also contains a name from the list above.
const SEARCH_CRAWLERS = [
  'Googlebot', 'Googlebot-Image', 'Google-InspectionTool', 'Bingbot', 'Applebot',
  'DuckDuckBot', 'YandexBot', 'Baiduspider', 'PetalBot',
];

// Next.js anchors header patterns (^...$) and matches them case-sensitively.
// Each name matches as written above and in lower case.
// Names contain only letters, digits and hyphens, so no escaping is needed.
const uaPattern = (names) =>
  `.*(?:${[...new Set(names.flatMap((n) => [n, n.toLowerCase()]))].join('|')}).*`;

const answershareRewrites = [
  // Rule 1: page requests from a named AI crawler get the AI version of that page.
  {
    // Every page path except /_next/, /_vercel/, /api/, /.well-known/
    // and any path ending in a file extension (assets, robots.txt, sitemap.xml).
    source: '/:path((?!(?:_next|_vercel|api|\\.well-known)(?:/|$)|.*\\.[A-Za-z0-9]+$).*)',
    has: [{ type: 'header', key: 'user-agent', value: uaPattern(AI_CRAWLERS) }],
    missing: [
      { type: 'header', key: 'user-agent', value: uaPattern(SEARCH_CRAWLERS) },
      { type: 'header', key: 'rsc' },                       // in-app navigation data
      { type: 'header', key: 'next-action' },               // form submissions
      { type: 'header', key: 'x-answershare-passthrough' }, // our fall-back fetch; stops loops
    ],
    destination: `${ANSWERSHARE_ORIGIN}/:path`,
  },
  // Rule 2: two public files, identical for every visitor and crawler.
  // Both return 404 on your site today.
  { source: '/llms.txt', destination: `${ANSWERSHARE_ORIGIN}/llms.txt` },
  { source: '/llms-full.txt', destination: `${ANSWERSHARE_ORIGIN}/llms-full.txt` },
];

module.exports = {
  // ...your existing settings, unchanged...
  async rewrites() {
    return {
      beforeFiles: answershareRewrites,
      afterFiles: [], // your existing rewrites, if any
      fallback: [],
    };
  },
};

Requires Next.js 13.3 or later (for missing).

Question for HOLT: Which Next.js version does the site run?

Rule 2 is optional for the test run. It adds two files that do not exist today and serves them the same way to everyone, so it changes nothing that people or search engines currently get. If you would rather leave it out, delete those two lines. Vercel does not allow rewrites of /.well-known/, so any file we supply for that folder would be a static file you commit. We are not asking for one in the test run.

What your team does

Nothing goes live from these steps; they only prepare your preview.

  1. Put the rule in next.config.js.
    Click flow: your code repository for www.texasfirstrentals.com (GitHub, GitLab or Bitbucket, whichever you use) > the project root folder > next.config.js (or next.config.mjs / next.config.ts) > the rewrites() function > the "beforeFiles" list.
    Required state: the AnswerShare block from the attached rule file sits inside "beforeFiles". Keep your existing rewrites where they are (they stay in "afterFiles").
    You should see: a rewrites() function that returns beforeFiles, afterFiles and fallback, with the AnswerShare block first.
  2. Make sure vercel.json has no AnswerShare rule.
    Click flow: the same repository > the project root folder > vercel.json > the "rewrites" array.
    Required state: no entry whose destination contains answershare.com.
    You should see: either no vercel.json rewrites at all, or only your own.
  3. Put the change in its own deployment, so Instant Rollback removes only this.
    Click flow: your repository > create a branch > commit the next.config.js change > open a pull request.
    Required state: the pull request contains only the next.config.js change.
    You should see: Vercel adds a Preview deployment to the pull request.
  4. Open the Preview deployment so we can test it.
    Click flow: https://vercel.com/dashboard > your Texas First Rentals project > Deployments > the newest "Preview" row > Visit.
    Required state: the deployment status is Ready.
    You should see: your normal site in the browser. Nothing changes for a person visiting.
  5. Tell us the Preview address and how we get through Vercel Deployment Protection.
    Click flow: Vercel dashboard > your project > Settings > Deployment Protection.
    Required state: either "Protection Bypass for Automation" is enabled and you read the value to us on a call (never in email), or you allow our test server address for the preview.
    You should see: the setting shown as Enabled, with a bypass value you can reveal.

Revert in one step

One step: in Vercel, use Instant Rollback to return production to the deployment before the rule. It takes effect without a rebuild. Ship the rule in a deployment of its own so that a rollback removes nothing else.

Question for HOLT: Is Instant Rollback available on your Vercel plan, and will your team use it for this rollback?

Permanent: delete the AnswerShare block and the answershareRewrites entry, and deploy. Nothing else in your project depends on it, and there is nothing to clean up afterwards: no DNS record, no environment variable, no secret.

We rehearse both on the preview before go-live (test T18).

The crawler list, entry by entry

"User-triggered" means the crawler fetches a page because a person just asked an assistant something. "Crawler" means a background index or training crawl. We use this split for the user-intent share on measuring results. Entries marked "Review" are ones we suggest your team looks at.

Name in the ruleOperatorTypeNote
GPTBotOpenAICrawler
OAI-SearchBotOpenAIUser-triggeredChatGPT search.
ChatGPT-User, ChatGPTOpenAIUser-triggered"ChatGPT" also catches other ChatGPT fetchers.
ClaudeBotAnthropicCrawler
Claude-SearchBot, Claude-UserAnthropicUser-triggered
claude-web, anthropic-aiAnthropicCrawlerOlder names.
PerplexityBotPerplexityCrawler
Perplexity-UserPerplexityUser-triggered
Gemini-User, Gemini-Deep-ResearchGoogleUser-triggeredReview: Google AI agents, not search crawlers.
Gemini-Research, GeminiBot, Gemini-AIGoogleCrawlerReview: Google AI agents, not search crawlers.
GoogleAgent-Mariner, GoogleAgent-URLContextGoogleUser-triggeredReview. URLContext is the fetcher Gemini uses when a person hands it a URL.
Google-CloudVertexBotGoogleCrawlerReview. Vertex AI Agent Builder; no effect on Google Search.
GoogleOtherGoogleCrawlerReview. Google's general-purpose crawler outside Search.
Google-ExtendedGoogleCrawlerA robots.txt token. Google crawls with Googlebot, which is excluded, so this entry is not expected to match any request.
Applebot-ExtendedAppleCrawlerA robots.txt token. Apple crawls with Applebot, which is excluded, so this entry is not expected to match any request.
Meta-ExternalAgentMetaCrawler
FacebookExternalHitMetaCrawlerReview. Meta also uses this agent to build link previews when people share your pages on Facebook, Messenger or WhatsApp. If it stays, those previews are built from the AI version, and the AI versions we build today carry no Open Graph title, description or image (checked on the five sample pages). Remove this entry if you want shared links to keep your own preview.
BytespiderByteDanceCrawler
AmazonbotAmazonCrawler
YouBotYou.comUser-triggered
DiffbotDiffbotCrawler
CCBotCommon CrawlCrawler
Cohere-AICohereCrawler
DeepSeekBotDeepSeekCrawler
MistralAI-UserMistralUser-triggered
Qwen-BotAlibabaCrawler
GrokBot, xAI-Grok, Grok-DeepSearchxAICrawler
AnswerShareBotAnswerShareCrawlerOur own measurement crawler, so our scores read what AI crawlers read. Review: you may remove it, and our measurements would then read your normal page.
This rule is for review only. AnswerShare has not deployed it and does not deploy to your project. Open points are settled before the preview; the questions for your team are collected on the plan page.