JavaScript SEO: what Google reads first

If your site is built with JavaScript, every page exists in two versions: the HTML your server sends, and the page the script assembles in the browser. Google can read the second one, but it gets the first one before anything else, and some rules in it are read before any rendering happens. For every page you want found in search, ask for a server response that already holds the title, the text and the canonical URL, and for both versions to say the same thing about indexing.

You won't see the problem on screen. Your browser runs the script, the page looks fine to you and to your agency, and it can still be missing from Google. It is one of the parts of technical SEO you can't judge by looking at your pages.

Two versions of every page, read at two different times

When a URL is requested, the server answers with an HTML document. On a static or server-rendered site, that document already holds the text, the title, the meta description and the canonical URL, the one a search engine should keep when a page has several URLs. On an app rendered in the browser, it is often a shell: a minimal head and a script that fetches the content and then writes it into the page.

Your visitors never see the difference, because their browser runs the script. Crawlers don't all run it, and not all at the same time.

Google describes three phases in its JavaScript SEO basics: crawling, rendering, then indexing. At the crawling stage it reads the server response. It then queues the pages that return a 200 status code for rendering, except the ones a robots rule tells it not to index. A page may sit in that queue for a few seconds, or longer. Whatever the script writes only exists for Google after rendering; whatever the server response said about the page, Google has already read.

Noindex, canonical, head: three defects you can't see

The noindex rule is the most sensitive one. Google states that when it finds noindex, it may skip rendering and JavaScript execution. A script that removes the rule once the page has loaded may therefore never run for Google: the page stays out of the index while it displays normally for every visitor. The other way around, a noindex added by the script is only seen by a crawler that runs the script, and the page says two opposite things depending on who reads it.

The canonical URL follows similar logic. Google accepts a canonical set by JavaScript, but asks you not to change it to a different value from the one in the original HTML. Its guide to canonical URLs adds that if you can't set it in the HTML source, you should leave it out there and set it only with JavaScript. Two different values are two signals that contradict each other.

The tags that speak to search engines belong in the page's head element. Google only accepts a canonical link there, and its page on valid page metadata explains that as soon as it meets an element that doesn't belong in the head, such as an image or an iframe, it assumes the head has ended and stops reading what follows. A component can also write these tags straight into the body. Either way, the meta description or the canonical still exists, with the right value, in a place where it no longer counts.

These defects usually follow a template: pages built on the same layout are affected, the others are fine. And a misplaced tag is still there and still correct, so a check that only looks for its presence finds it.

AI-built sites: one shell for every URL

Several tools that build a website from a prompt produce an app rendered in the browser. The server often returns the same document for every URL, with the same title and meta description, and the script then decides what to show. Google, which renders these pages, can see the content of each one. A crawler that stops at the server response sees a single page, repeated at every URL.

The same setup has a second effect. A URL that does not exist also receives the shared document with a success code, and it is the script that displays "page not found." Google calls this a soft 404, and offers two fixes: a JavaScript redirect to a URL that really returns 404, or a noindex rule added to error pages. The guide on what your site should return for a missing page explains why that code matters.

These tools often let other defects through, outside SEO. The guide to checking an AI-built website goes through them.

Ask for pages that work before any script runs

You can set these requirements without reading a line of code. Put them, in this order, to the person or agency that builds the site.

  1. List the pages that need to be found in search: the home page, your services, product pages, articles. A customer account or a dashboard behind a login isn't on that list, and can stay rendered in the browser.
  2. Ask, in writing, how those pages are rendered: on the server, as static pages generated ahead of time, or only in the browser. The requirements below depend on the answer.
  3. For those pages, require a server response that already holds the title, the meta description, the main text and the canonical URL. Server-side rendering and pre-rendering both do that, and Google recommends them. Dynamic rendering, which serves crawlers a pre-rendered version and visitors the app, is something Google now calls a workaround, not a long-term solution.
  4. Require that no page meant to be indexed carries a noindex rule in the HTML the server sends, not even temporarily, and that the script never changes the canonical URL written in that HTML.
  5. Require the canonical URL, the meta description and the language annotations to sit in the document's head, with no image or iframe placed before them.
  6. Have someone who didn't build the site check the result, at launch and after every redesign. These defects start in a template, and a component added later is enough to bring them back.

A noindex left in the template, a canonical rewritten by the script, an element misplaced at the top of the head: these are fixed in the template, once for every page that uses it, and they come first. When some pages are already correct, the right way to do it already exists somewhere in the site.

The job is a different size when the server returns the same shell for every URL. Getting the server to send each page's content and tags, through server-side rendering or pre-rendering, changes how the site is built: it needs planning, then a page-by-page check after launch.

Served and rendered, captured in the same visit

The audit reads pages in a browser, the way a visitor does. For the site's reference page, usually the home page, it also keeps the document the server returned before any script ran. Both versions come from the same visit: a second request could be served something else.

  • The canonical URL and the noindex rule, in each of the two versions. A canonical that only appears after the script, two different canonicals, or an indexing rule that changes from one version to the other counts as a defect.
  • The title, the main heading and the share of the text already present in the server response. They are recorded without counting as a defect: a page whose text arrives through the script can still be indexed.
  • Text present in the server response and missing from the displayed page. This is the same gap in the other direction: a crawler would read text no visitor ever sees, which Google's spam policies call cloaking when the intent is to mislead. Content meant for browsers without JavaScript and templates that never display are left out, and only a gap of significant size is kept. The report quotes extracts: it records a fact, not a judgment of intent, since a site can drop a block on load without hiding anything.
  • Where the tags sit, on every page in the sample. A canonical, a meta description or a language annotation rendered outside the head counts as a defect, and the report says how many pages are affected and how many are already correct. A title outside the head is not counted, since the browser reads it wherever it is, and structured data in the body is where it is allowed to be.
  • When the page is read. The audit waits until the page stops changing before reading it. A page still waiting for its own data, with its title still empty, is not judged on that shell: it is recorded as a page that fails to display in time.

If the server response could not be kept, the comparison is reported as not verifiable, never as passed. And it covers what each version contains: how long Google takes to render your pages, or how much crawling it gives the site, shows up in Google's own tools, not from the outside.

A store and a Webflow site: two versions that match

0%serve crawlers text that the page displayed to visitors does not show

This percentage covers about 20 websites we audited between August 14, 2026 and September 24, 2026, the ones where this point could be checked. Many were audited because a defect showed up quickly, so the figure describes our audits, not websites in general.

The two defects in the opposite direction, a tag that only appears after the script and a tag rendered outside the head, each remain an isolated case in our audits. The usual result is a site whose two versions match, and the report says that too.

The two published sample reports are two such cases, built in different ways. The B2B business website is built with Webflow: its tags and content are in the server response, before any script runs. On all 120 pages of the online store, the canonical URL sits in the head, and the report finds no gap between the served text and the rendered text. For both sites, what Google reads at crawl time is already what the visitor sees.

This site holds itself to the same standard. It is built as static pages: the title, description, canonical URL and language annotations of every page meant to be found are in the server response, with no dependency on the script. That is one way to build a site among others; an app rendered in the browser can be indexed too, as long as it gets the points above right.

By , Z29K · updated October 30, 2026

Read next

Soft 404: what it means and what to fix

A soft 404 is an error page sent with a 200 code. Why it hides your dead links, how Google treats 404 and 410, and what to ask your developer to change.

Read the guide →

Check an AI-built website: what to look for

Your AI-built site looks fine in the preview. What to get checked, what to fix first and what needs a developer: indexing, exposed keys, trackers, hosting.

Read the guide →

Redirect chains: fix them at the source

Your site redirects to HTTPS in two or three hops? Why a 301 redirect should take one, and what to ask your developer so the chain gets fixed at the source.

Read the guide →