Technical SEO
JavaScript SEO: the difference between what you see and what gets indexed
Google renders JavaScript, but on a deferred queue and with no guarantee of completeness — and most other crawlers, including every major AI crawler, do not render at all. If your content only exists after execution, you are betting your visibility on one consumer being patient and every other consumer being irrelevant.
The one test that settles it
View the page source. Not the Elements panel — the actual source the server returned. If the body is a container div and a script tag, your content does not exist until JavaScript runs.
Then compare word counts. On the previous version of this site, view-source contained 73 words while the rendered page contained over 800. Everything a buyer needed to read lived inside a 343 KB JavaScript bundle, and everything that could not execute that bundle saw a paragraph apologising for requiring JavaScript.
curl -s https://example.com/ \
| sed -e 's/<script[^>]*>.*<\/script>//g' -e 's/<[^>]*>/ /g' \
| tr -s ' \n' ' ' | wc -w
# Compare that number with what you see on screen.
# A large gap is the whole problem, stated in one integer.What each rendering mode costs you
| Mode | Googlebot | AI crawlers | When it is fine |
|---|---|---|---|
| Client-side (CSR) | Rendered, but deferred and never guaranteed | Sees nothing | Logged-in application screens that should not be indexed anyway |
| Server-side (SSR) | Full content on first fetch | Full content | Content that changes per request or per user |
| Static generation (SSG) | Full content on first fetch | Full content | Anything that is the same for every visitor — most marketing sites |
| Hybrid / islands | Full content, interactive parts hydrate | Full content | Mostly static pages with a few interactive components |
The AI crawler problem is not the same problem
Discussions of JavaScript SEO usually stop at "Google renders it eventually", which was a defensible position when Google was the only consumer that mattered. It no longer is.
GPTBot, ClaudeBot, PerplexityBot, Applebot and CCBot fetch HTML and read it. They do not run your bundle and wait. A client-rendered site is not merely slower to index for these consumers — it is empty. When a prospective client pastes your URL into an assistant and asks whether you are any good, that is the fetch that decides the answer.
Fixing it without rewriting everything
- If the site is mostly static content, move to a static generator. This is the cheapest and most complete fix, and it removes the runtime entirely.
- If content is dynamic, add server-side rendering for the routes that need to rank, and leave the application shell alone.
- If neither is possible short-term, prerender the important routes to static HTML at build time as a stopgap.
- Whatever you choose, verify with view-source afterwards. The number of "fixed" sites where the fix was never deployed to production is not small.
This site took the first option: a React single-page application became statically generated pages. Framework JavaScript on content pages went from 343 KB to zero, and crawlable body text went from 73 words to a full document.
Things that still break under SSR
- Content behind an interaction — tabs and accordions that only fetch on click
- Infinite scroll with no paginated URLs behind it
- Links implemented as onclick handlers instead of anchor elements with href attributes
- Blocked JavaScript or CSS in robots.txt, which prevents rendering even where rendering is available
- Content injected after a timer, which finishes after the render budget has been spent
Questions people ask about this
- Does Google penalise JavaScript sites?
- No penalty exists. The cost is delay and incompleteness — rendering is queued, and anything that fails during rendering is simply missing from the index with no error message anywhere.
- Is React bad for SEO?
- React is fine. Client-only rendering is the problem. React with server rendering or static generation indexes exactly as well as anything else; the framework is not the variable.
- How do I check what Google specifically rendered?
- Search Console → URL Inspection → Test Live URL → View Crawled Page. That is Google telling you what it actually received, which beats any third-party simulation.
Who wrote this
Anas Bin Masud builds e-commerce sites and does technical SEO for businesses in the UK, Canada and Pakistan — fifteen live client sites, six of them stores taking real payments. The examples in these guides come from those builds and from the audit that rebuilt this site, not from a content brief. More about how I work, or read the case studies.