SaaS Pricing Pages: Making Prices Readable to AI Crawlers
99Visibility Research · Updated October 21, 2026 · 8 min read
Short answer
Most AI crawlers download your pricing page but don't run its JavaScript. If plan names, prices or limits only appear after a script loads, or after a monthly or annual toggle fires, the crawlers behind ChatGPT search, Claude and Perplexity may see an empty table. Fix it by putting every plan, price and limit in the initial HTML, keeping one canonical pricing page, and checking the raw HTML after every pricing change.
Key takeaways
- Vercel found that ChatGPT and Claude crawlers fetch JavaScript files but don't execute them, so client-rendered prices can be invisible to them.
- A pricing toggle that injects the second set of prices with JavaScript hides those prices from non-rendering crawlers.
- Server-render every plan name, price, billing period and limit, for both monthly and annual billing, in the first HTML response.
- Keep one canonical pricing page and remove old or contradicting prices elsewhere on your site.
- Re-check the raw HTML after every pricing change and every front-end release, because a redesign can silently undo the fix.
Why AI crawlers miss prices on SaaS pricing pages
Most AI crawlers read the HTML your server sends and stop there. Vercel's crawler study found that ChatGPT and Claude crawlers do fetch JavaScript files (11.50% and 23.84% of their requests) but don't execute them, so they can't read client-side rendered content. Independent re-testing reported in June 2026 found the same for GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, PerplexityBot, Meta-ExternalAgent and Bytespider.
Googlebot is the exception. It renders JavaScript, so a client-rendered pricing table can look fine in Google and still be blank to every other AI crawler.
This matters for pricing more than almost any other page. A price is a specific fact, and a fetchable sentence stating it gives an engine something it can quote. The 252,000-trial factorial study (arXiv 2605.25517) found that including explicit price information helped consistently in its simulated setup. When the crawler sees no price, the engine fills the gap from somewhere else: an old review, a competitor's comparison page, or what the model learned before its knowledge cutoff.
The fix is access, not optimization. Server rendering doesn't make an engine choose you. It makes your prices exist in the copy of the page the engine can read.
The patterns that hide prices
These are the common ways SaaS pricing pages hide numbers from non-rendering crawlers. Check your page against each one.
- Billing toggles. The page ships monthly prices in the HTML, then a script swaps in annual prices when the toggle flips. The crawler only ever sees one set, or neither if both come from JavaScript.
- Client-fetched pricing tables. The table is an empty container that a script fills from an API or a CMS. The raw HTML holds a spinner or a skeleton.
- Currency and region switchers. Prices load after the script detects location. The default HTML often contains no number at all.
- Seat sliders and calculators. The price appears only after the visitor moves a slider. Nothing static says what one seat costs.
- Feature limits in tabs or accordions. Keyword caps, seat counts and usage limits load on click. Plan names survive, the limits that differentiate them don't.
- Accidental suppression. A
data-nosnippetattribute or anosnippetrobots meta tag inherited from a template. Bing documents that content markeddata-nosnippetis excluded from snippets and AI summaries, and Google documents the same controls.
A toggle itself is fine. The problem is a toggle whose hidden state only exists after JavaScript runs. If both price sets are in the HTML and CSS controls which one shows, crawlers can read both.
How to server-render plan names, prices and limits
Work through these steps on your live pricing URL. You'll need a terminal or a browser with JavaScript turned off, and access to whoever owns the front end.
- Fetch the raw HTML. Request the page without running JavaScript, for example with
curlor with JavaScript disabled in your browser. Save the response. - Search it for every number. Look for each plan name, each monthly price, each annual price, the billing period, and each limit (seats, projects, keywords, usage). Write down what's missing.
- Render both billing states in the HTML. Output monthly and annual prices in the initial response. Use CSS or a hidden attribute to control which one the visitor sees. Don't fetch the second set on click.
- Server-render the table. Use server-side rendering, static generation or prerendering for the pricing component. Vercel notes that data embedded in the initial HTML response may still be indexed, but plain text is the safest target.
- Write one plain sentence per plan. Add a short line such as "Starter costs $49 per month and includes 25 projects." in visible text. This hypothetical line is the kind of fact an engine can lift whole.
- Set a default currency in the HTML. If you localize prices, ship your primary currency in the raw response and swap it client-side only for visitors who need another one.
- Remove accidental suppression. Delete any
data-nosnippet,nosnippet,max-snippet:0ornoindexon the pricing page unless you put it there on purpose. - Confirm crawler access. Check that robots.txt allows the retrieval bots, and that your CDN or firewall doesn't return a 403 to them. A minimal allow looks like this:
User-agent: OAI-SearchBot
Allow: /pricing
User-agent: PerplexityBot
Allow: /pricing
User-agent: Claude-SearchBot
Allow: /pricing
Remember that GPTBot governs training only. OpenAI states that each bot setting is independent, so allowing GPTBot doesn't put you in ChatGPT search. If you're weighing blocking bots to stop wrong prices, read whether to block AI crawlers from your pricing page first. A firewall can block a crawler that robots.txt allows, and the AI Crawler Checker requests a page as each AI crawler and shows which ones get turned away.
- Re-fetch and diff. Repeat step 1 and confirm every number from step 2 is now in the raw HTML.
Keep one canonical pricing page
Crawlers can only quote what they find, and they find a lot more than your pricing page. Old launch posts, help articles, comparison pages and partner pages often carry prices from two plan changes ago. When those pages disagree with /pricing, you've given engines a choice of facts.
Do this:
- Pick one URL as the source of truth for prices, usually
/pricing. - Find every other page on your site that states a price or a plan limit. The free check for contradicting facts on your own site is one way to surface them.
- Replace hard-coded prices elsewhere with a link to the canonical page, or update them from the same data source.
- Redirect retired pricing URLs (old plan pages, regional duplicates) to the canonical page instead of leaving them live.
- Keep plan names identical everywhere. "Growth" on the pricing page and "Team" in the docs reads as two products.
If you're unsure whether to publish prices at all, the trade-offs are covered in should I publish my prices so AI answers get them right. The short version: an engine can't quote a price you never state.
Pricing page checklist
Run this list before you ship any pricing change.
- Every plan name appears in the raw HTML.
- Every monthly price appears in the raw HTML.
- Every annual price appears in the raw HTML, not only after the toggle.
- The billing period is written next to each price (per month, per year, per seat).
- Key limits for each plan are in the raw HTML, not behind a tab or accordion that loads on click.
- A default currency is in the raw HTML.
- Each plan has one plain sentence stating its price and main limit.
- No
data-nosnippet,nosnippet,max-snippet:0ornoindexon the pricing content by accident. - robots.txt allows OAI-SearchBot, PerplexityBot and Claude-SearchBot on the pricing URL.
- The CDN or firewall returns 200, not 403 or a challenge page, to those crawlers.
- No other page on your site states a different price or limit.
- Retired pricing URLs redirect to the canonical page.
On structured data: Google says it isn't required for generative AI search, and Ahrefs' matched test of 1,885 pages found adding schema produced no major uplift in AI citations. Existing markup does no harm. It just isn't the fix here.
What good and bad results look like
Good
The raw HTML, fetched with no JavaScript, reads like a plain price list. You can find every plan, both billing prices and the main limits with a text search. Each AI crawler gets a 200 response with that same HTML. No other page on your site contradicts it.
When you later ask AI assistants what you charge, answers that cite your site match the page. Answers that don't cite you may still be wrong, and that points to third-party sources or old model knowledge rather than your page.
Bad
- The raw HTML shows plan names but prices read as "$--" or an empty element.
- Only monthly prices exist in the HTML, so AI answers quote monthly figures as if they were the only option.
- The pricing page is correct but a two-year-old blog post states the old price.
- robots.txt allows the crawler but the firewall serves a challenge page.
If AI answers stay wrong after the page passes, work through fixing AI answers that get your pricing wrong, which covers third-party sources and correction routes.
How often to repeat it, and what it won't fix
Re-run the raw HTML fetch and the checklist:
- After every price or plan change.
- After every front-end release that touches the pricing component, since a redesign can move prices back into client-side code without anyone noticing.
- After any CDN, firewall or bot-management change. Cloudflare's new defaults from 2026-09-15 block Training and Agent crawlers on ad-displaying pages for some customers, a change a site can receive without editing anything.
- Once a month as a routine check, even when nothing shipped.
Be clear about the limits. This work controls access, the first gate. It doesn't control which pages an engine retrieves for a given question, or what the model writes. Answers given without live search come from what the model learned before its knowledge cutoff, and nothing you change today reaches those until a future model is trained. Retrieval is also per query and at each platform's discretion as of October 2026.
To see where you stand, the free checker on this site shows whether AI answers name you for up to three buyer questions. For SaaS-specific prompts and access issues, see AI visibility for SaaS.
Frequently asked questions
Does Google have the same problem with client-rendered pricing?
Less so. Googlebot renders JavaScript, so Google can usually read a client-rendered pricing table. Google AI Overviews and AI Mode draw on pages that are indexed and eligible to show a snippet, with no extra technical requirements. The risk sits with other AI crawlers, which tested studies found don't execute JavaScript. A page can look perfect in Google and be blank to ChatGPT search and Perplexity crawlers.
Should I show annual prices only, to keep the page simple?
Show whatever billing options you actually sell, and put all of them in the raw HTML. If you hide monthly prices behind a toggle that loads them with JavaScript, non-rendering crawlers only see the annual figures and AI answers may quote those as your only price. Writing the billing period next to each number avoids answers that mix up per-month and per-year costs.
Will adding pricing schema get my prices into AI answers?
There's no evidence it will. Google says structured data isn't required for generative AI search, and Ahrefs' matched test of 1,885 pages found adding schema produced no major uplift in AI citations, with AI Overviews citations falling 4.6%. Existing markup does no harm. The fix that holds up is plain, server-rendered text stating each price.
How fast will ChatGPT pick up my corrected prices?
Nobody outside OpenAI can give you a timeline. Answers that use live search can reflect the fixed page once OAI-SearchBot can fetch it, but ChatGPT decides per question whether to search. Answers given without search come from the model's training data and won't change until a newer model ships. For the full correction route, see [ChatGPT keeps getting my pricing wrong](/questions/chatgpt-gets-my-pricing-wrong).
Should I block AI crawlers from my pricing page if they keep quoting old prices?
Usually not. Blocking OAI-SearchBot removes the page from ChatGPT search answers, so engines lose your correct prices and rely more on third-party pages and old model knowledge. Blocking GPTBot only affects training use, not search. The better move is to make the current prices readable in raw HTML and remove stale prices from the rest of your site.
Sources
This page is AI-assisted. It was written from a verified evidence base and checked against our editorial policy. Engine behaviour changes often; facts are as of October 21, 2026.