JavaScript SEO

Borislav Donchev

Author

Borislav Donchev

CEO & Founder of Back2Rank
Recovers websites after Google penalties, hacker attacks and failed migrations. 150+ recovered sites and 70+ removed penalties over more than 7 years. He has worked on cases where the cause of a traffic loss was an external attack, not an internal mistake.

Check out more posts

JavaScript SEO is the work of making sure content that JavaScript builds can still be found by search engines. Google processes these pages in three stages: crawling, rendering, and indexing. The middle one is the part that surprises people, because it’s separate, queued, and happens later. This is a corner of technical SEO, the work of keeping a site readable by search engines, where the failures are quiet and the symptoms are delayed.

In plain English

Flat-pack furniture.

Some deliveries arrive assembled. You open the door, you see a chair, and there’s nothing to work out.

Others arrive as a flat box of parts and an instruction sheet. Everything needed to make the chair is in there. But until someone has the time to assemble it, the warehouse record says “box of parts”, because that’s what was actually delivered.

Google assembles the box. It just doesn’t always do it immediately, and if a piece is missing from the packaging, the chair never appears at all.

Why this matters for your site

A site built this way can look perfect to everyone who checks it and be substantially invisible to search engines for a period nobody can predict.

The problem is that the usual tests don’t catch it. The page loads in a browser. Colleagues see the content. Analytics records visits. Meanwhile the version Google stored may be the shell without the product description, the price, or the specification. A Vercel and MERJ study of more than 100,000 Googlebot fetches put the median gap between crawl and completed render at roughly 10 seconds, but the slowest 1% of pages waited around 18 hours, and addresses carrying query strings were slower still.

It also compounds. Links that only exist after JavaScript runs are links Google finds late, which delays the discovery of everything they point at.

How it actually works

Crawling. Googlebot takes an address from the crawl queue and checks robots.txt first. If the address is disallowed, it stops there. Google states that it won’t render JavaScript from blocked files or on blocked pages, so blocking a script folder removes the content that script would have produced.

Parsing. Google reads the response and extracts links from href attributes, adding them to the crawl queue. Links built from click handlers rather than real href attributes aren’t picked up at this stage.

The render queue. Google queues every page returning a 200 success code for rendering, unless a robots tag or header says not to index it. Google’s own description of the wait is that a page may stay in the queue for a few seconds, but that it can take longer than that.

Rendering. When resources allow, a headless Chromium, meaning a browser engine with no visible window, loads the page and runs its JavaScript. Google keeps this on a current release, so modern JavaScript features are supported.

Back to processing. The rendered HTML goes back for a second pass. Google extracts links again, this time including the ones that only existed after the scripts ran, and uses the rendered result for indexing, meaning storing the page in the database results are drawn from.

Two traps worth naming. Google says that when it encounters a noindex tag it may skip rendering entirely, so a script intended to remove that tag never executes. And Google’s rendering service caches aggressively and may ignore caching headers, which means it can render your page using last month’s JavaScript. Google’s fix for the second is content fingerprinting: put a hash of the file’s contents in the filename, so any change produces a new one.

Google isn’t the only reader. The same researchers found that AI crawlers behave differently: ChatGPT and Claude’s crawlers fetch JavaScript files but don’t execute them, so they can’t read client-side rendered content at all. Gemini is the exception, because it runs on Google’s infrastructure. For anything you want quoted in AI answers, client-side rendering isn’t a delay. It’s an absence.

What this looks like in practice

A retailer rebuilds as a single-page application, meaning a site that loads once and then swaps content in place rather than loading new pages.

The raw HTML for every product address is the same empty shell. All the product content arrives afterwards, from JavaScript. And the category navigation is built from buttons with click handlers rather than links with href attributes.

Google renders the pages eventually, so the site isn’t invisible. But discovery depends entirely on the sitemap, because there are no crawlable links for Googlebot to follow. Every product page waits on the render queue before its content exists for Google at all. And to the assistants that don’t render, the whole catalogue reads as empty shells.

Nothing here is broken. Every decision was reasonable for the application. None of them was made with the render queue in mind.

What people usually get wrong

“Google can’t read JavaScript.” It can, with a current browser engine. The risk is timing and configuration, not capability, and treating it as capability leads to the wrong fixes.

“We’ll noindex it now and switch it on with a script later.” Google may never run that script, because it may skip rendering once it sees the tag.

“We deployed the fix, so Google has it.” Not necessarily. Aggressive caching on Google’s side can leave it rendering old files unless filenames change with content.

“Blocking script files reduces crawl load.” It also stops Google rendering whatever those scripts produce, which is usually the content you wanted indexed.

What you can do about it

Run URL Inspection in Google Search Console on an important page and read the rendered HTML. If your product description, price, or main body text is missing from it, that’s the entire diagnosis.

Compare that against the raw source in your browser. The gap between the two is the amount of your site that depends on rendering, and the amount that’s invisible to everything except Google.

Make navigation from real links with href attributes, even in an application that intercepts the clicks. Both can be true at once.

For content where speed of discovery matters, news, products, listings, put the main content in the initial HTML through server-side rendering, meaning generating the page on the server before sending it.

Fingerprint your JavaScript and CSS filenames so a change always looks like a new file.

Watch responsiveness alongside this. Heavy client-side JavaScript is the most common cause of a poor Interaction to Next Paint score, one of the Core Web Vitals, the metrics measuring how a page feels to real visitors.

Words you will hear

Client-side rendering. Building the page in the visitor’s browser rather than on the server.

Server-side rendering. Building the page on the server so the HTML arrives complete.

Hydration. Attaching JavaScript behavior to HTML that was already delivered.

Render queue. The waiting list of pages Google has crawled but not yet rendered.

Single-page application. A site that loads once and swaps content in place.

For rendering, crawler and index, see How search works. For SERP, query and search console, see What is SEO?