JavaScript SEO

No Comments
Javascript seo

JavaScript SEO is the discipline of making sure content that depends on JavaScript still gets crawled, rendered, and indexed by search engines — and increasingly, seen by AI crawlers that don't execute JavaScript at all. The stakes are binary: content that only exists after script execution either survives the rendering pipeline or it's invisible, and you can lose an entire product catalog from the index without a single error message telling you so.

The two-wave reality

Googlebot doesn't see your page the way Chrome does — at least not immediately. First wave: the crawler fetches the raw HTML response and indexes what's there. Second wave: the page goes into a render queue for the Web Rendering Service, an evergreen-Chromium renderer that executes your JavaScript and produces the final DOM. Anything that only exists after that second wave — text fetched from an API, links built by a router, meta tags set by a framework — gets indexed late, or in messy cases, unreliably.

Google, to its credit, renders nearly everything eventually. The bigger 2026 problem is everyone else. Most AI crawlers — the bots feeding LLM training sets and answer engines — fetch raw HTML and leave. If your content strategy includes being cited by AI search, client-side-only content simply doesn't exist for that channel. The full rendering guide maps which crawlers execute JavaScript and which don't; the short version is that the raw HTML response is the only thing every consumer is guaranteed to see, and for many sites it's an empty shell nobody has looked at in years.

A diagnosis you can run in ten minutes

Stop guessing whether your JavaScript is an SEO problem. Run this on your most important template:

# 1. What every crawler gets, guaranteed:
curl -sL -A "Mozilla/5.0" https://example.com/products/widget | grep -c "Widget Pro 3000"

# 0 matches = the product name is NOT in the raw HTML.
# It only exists after JavaScript runs.

Then confirm what Google's renderer produces: Search Console → URL Inspection → Test live URL → View tested page. Search the rendered HTML for the same phrase. The four possible outcomes tell you everything:

  • In raw HTML and rendered HTML: healthy.
  • Missing from raw, present in rendered: Google will index it (eventually); non-rendering crawlers never see it.
  • Missing from both: broken for everyone — often a blocked resource, a timeout, or content behind an interaction.
  • In raw HTML but different after render: your JavaScript is overwriting server content — check for hydration mismatches or client-side redirects.

Rendering strategies ranked by risk

StrategyWhat the crawler receives on first fetchSEO riskTypical failure mode
Static HTML / SSGComplete contentMinimalStale content between builds
Server-side rendering (SSR)Complete content, then hydratedLowHydration errors replacing server HTML; slow TTFB under load
SSR with client-side routingComplete for entry page onlyModerateSubsequent routes have no server response; direct hits 404 or return the shell
Client-side rendering (CSR/SPA)Near-empty shell + JS bundleHighAll content deferred to second-wave rendering; invisible to non-rendering bots
Dynamic rendering (bot-only prerender)Prerendered snapshot for known botsModerate and risingGoogle now discourages it; UA lists rot; new AI crawlers aren't on the list
CSR with prerendering serviceCached snapshot, if the service firesModerateCache misses serve the shell; snapshots drift from live content

If you're picking a target state: real HTML in the server response, via SSR or static generation — the server-side rendering entry covers the implementation trade-offs, and prerendering is a stopgap with an exit strategy, not a destination.

How to check it on your own site

  1. curl your top templates (as above) and grep for a sentence of primary content, the title tag, and a known internal link. Raw HTML is ground truth for non-rendering crawlers.
  2. URL Inspection → View crawled page in Search Console for what Google actually rendered — screenshot, rendered HTML, and the console/resource errors that occurred during rendering. Check the "Page resources" list for blocked or failed files.
  3. In Chrome DevTools, toggle Disable JavaScript (Cmd+Shift+P → "Disable JavaScript") and reload. What survives is your no-JS reality. The View Rendered Source extension shows the raw-vs-rendered diff side by side.
  4. Verify robots.txt isn't blocking your JS or API endpoints — a disallowed script file can break rendering for the whole template while everything looks fine in a browser.
  5. Crawl the site twice in Screaming Frog — once text-only, once with JavaScript rendering — and diff word counts and internal links per template. Big deltas mark your exposure.

Common mistakes

  • Links that aren't links. <div onclick="router.push('/category')"> navigates fine for users and doesn't exist for crawlers. Fix: every internal navigation is an <a href>; let the router intercept the click.
  • Metadata set only client-side. Titles, canonicals, and robots meta injected by the framework after load can be picked up late or inconsistently — and a client-side noindex that appears post-render is a coin flip. Fix: critical meta tags belong in the server response, full stop.
  • Content behind interaction. Tabs, "load more" buttons, and infinite scroll that only fetch on user action never fire for a crawler that doesn't click or scroll. Fix: paginated URLs and server-rendered first batches.
  • Blocked resources. The JS bundle or the API it calls sits behind robots.txt disallow or requires cookies. Rendering "succeeds" and produces a skeleton. Fix: allow crawlers to fetch everything rendering needs, and confirm in the Page resources report.
  • Testing only in a browser. Your laptop has warm caches, cookies, and a logged-in session; Googlebot has none of that and a timeout budget. Fix: make curl and URL Inspection part of every release check for JS-heavy templates.

FAQ

Does Google index JavaScript content or not?

Yes — Google renders JavaScript at scale and does it well. The honest caveats: rendering is deferred (minutes to much longer), it can fail on blocked resources or timeouts, and Google is nearly alone in doing it. Build for the raw HTML and treat Google's rendering as the safety net, not the plan.

How long does the render queue delay indexing?

Usually minutes to hours; occasionally longer. For most sites the delay itself is harmless. It bites when you ship time-sensitive content, or when rendering fails silently and "delayed" quietly becomes "never" — which is why you verify with URL Inspection instead of assuming.

Is dynamic rendering still acceptable?

It works, but Google now explicitly calls it a workaround and recommends SSR, static rendering, or hydration instead. Its fatal flaw in 2026 is the user-agent list: every new AI crawler that isn't on it gets your empty shell.

Do AI crawlers run JavaScript?

Overwhelmingly, no. Most LLM and answer-engine bots fetch raw HTML only. If AI visibility matters to you, that's the strongest argument yet for server-rendered content — stronger than anything Google-specific.

My SPA ranks fine. Should I still care?

Check what it ranks with — often it's the homepage and a few server-cached pages carrying the site. Run the raw-vs-rendered diff on deep templates before deciding you're fine. Ranking despite an architecture isn't the same as ranking because of it.

Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.

About SEO ProCheck

Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.

Work With Me

Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.

Subscribe to our newsletter!

More from our blog