JavaScript SEO: Rendering and Indexing Basics

JavaScript SEO makes sure that the content, links, and metadata of a JavaScript-based website are reachable for search engines even though they only come into being in the browser. Google can execute JavaScript. Whether a page is indexed completely, correctly, and on time, however, depends on three factors: how the page is rendered, which signals are already in the first HTML, and whether errors such as soft 404s or blocked resources lurk in the code. This guide explains how Google processes the pages, compares the rendering strategies, names the most common sources of error, and shows how to check after a relaunch or a sudden ranking loss whether JavaScript is the cause.

Making JavaScript pages visible to Google

SEYBOLD ONE combines technical SEO with data-driven strategies to specifically check rendering problems and possible causes of ranking losses.

Get a free consultation

What JavaScript SEO covers

Google itself describes JavaScript SEO as the optimization of JavaScript-powered web applications for Google Search and dedicates its own documentation to the topic, the JavaScript SEO basics. The discipline is a sub-area of technical SEO. It mainly concerns websites based on frameworks such as React, Vue, or Angular, single-page applications, shops with product lists loaded on the client side, and all pages whose main content, internal linking, or meta information is created or changed by JavaScript.

At its core it comes down to one question: does what Googlebot sees after rendering match what a user sees in the browser? If headings, product texts, canonical tags, or links only appear after an interaction, an API call, or a cookie check, a gap arises between the user's and the crawler's view. This very gap is the cause of most JavaScript SEO problems.

How Google processes JavaScript pages

According to Search Central, Google processes JavaScript pages in three phases: crawling, rendering, and indexing. Anyone who understands this sequence quickly sees where a page gets stuck.

  1. Crawling: Googlebot first checks the robots.txt, fetches the allowed URL, and extracts further URLs from the href attributes of HTML links. Links that only work via onclick handlers or JavaScript routing without a real <a href> are not reliably discovered in this phase.
  2. Rendering: Pages with HTTP status code 200 are placed in a queue for rendering. The Web Rendering Service (WRS) executes the JavaScript with a current Chromium and produces the rendered HTML. Pages with an error status or a noindex signal in the initial HTML are generally not rendered at all.
  3. Indexing: Google uses the rendered HTML for indexing and also extracts the links that only came into being through JavaScript. These then go back into crawling.

The frequently invoked “second wave” of indexing, in which weeks are supposed to lie between crawling and rendering, is outdated in this form. An analysis by Vercel on how Google handles JavaScript covering more than 100,000 Googlebot fetches found that all indexable HTML pages with status code 200 were fully rendered and that the median rendering delay was around ten seconds. Individual pages, however, waited considerably longer. For websites with hundreds of thousands of URLs, frequently changing content, or a tight crawl budget, this delay remains relevant because new or changed content arrives in the index later.

Handling meta robots instructions is particularly critical. Google makes clear in its documentation that with a noindex in the original HTML it may skip rendering and JavaScript execution. A script that is supposed to remove a noindex afterward then has no effect. Indexing-relevant signals such as robots instructions, canonical, and status code therefore belong in the HTML delivered by the server or in the HTTP header, for example via the X-Robots-Tag.

In the SEO guide for web developers, Google sums up the situation soberly: JavaScript can in principle be executed, but the design has to take into account the particularities and limitations for crawling and rendering. In addition, Google is not the only consumer of your content. Whether other crawlers, such as those of AI answer systems, execute JavaScript is not guaranteed. HTML delivered by the server is therefore the more robust basis for visibility in classic search and in AI answers.

Rendering strategies compared

The choice of rendering strategy decides how much work lies with the crawler and how early the actual content appears in the HTML. According to the explanations by web.dev on JavaScript and Google Search, the rendering strategy influences both performance and robustness; server rendering and pre-rendering make the first HTML content available earlier.

StrategyWhere the content is createdAdvantages for SEORisksSuitable for
Client-side rendering (CSR)In the browser, by JavaScriptLow server load, app-like operationContent missing in the initial HTML, dependent on rendering, resources, and APIsLogged-in areas, dashboards, tools without search relevance
Server-side rendering (SSR)On the server, per requestComplete HTML available immediately, unambiguous signalsHigher server load, more complex infrastructureShops, category pages, editorial content
Static pre-rendering (SSG)At build time, as finished HTML filesVery fast, stable, easy to cacheUpdating requires a new buildGuides, landing pages, documentation
Hybrid with hydrationServer delivers HTML, browser takes over afterwardCombines indexable HTML and interactivityDeviations between server and client outputMost modern framework projects
Dynamic renderingServer detects crawlers and delivers a pre-rendered version to themShort-term relief for legacy systemsMaintaining two versions, error-prone, according to Google only a workaroundTransition phase until migration

Client-side rendering

With client-side rendering, the browser loads a largely empty HTML shell and a JavaScript bundle that creates the content during execution. For users this is often unproblematic; for search engines it means: the content only exists after rendering. Every error in this chain, a blocked script, a slow API, a timeout, or a code error, leads to Google indexing an empty or incomplete page. CSR is not bad for SEO per se, but it shifts the risk entirely onto the rendering step.

Server-side rendering and pre-rendering

With server-side rendering, the server produces the complete HTML before it is delivered. Title, main content, internal links, canonical, and structured data are thus already in the first fetch. Static pre-rendering pursues the same goal but produces the HTML once at build time. Modern frameworks offer both variants and allow combining them per page type: guide pages static, product pages with server rendering, the shopping cart on the client side. For search-relevant pages we recommend this route as the standard.

Comparison of server rendering and pre-rendering

Dynamic rendering: a workaround

With dynamic rendering, the server detects crawlers by user agent and delivers them a server-rendered version while users receive the client-side version. Google explicitly describes dynamic rendering as a workaround and not as a long-term solution, because it causes additional complexity and resource requirements. In practice we regularly see with such setups that the crawler version is outdated, incomplete, or faulty after a deployment without anyone noticing, because users see the correct version. Anyone who still uses dynamic rendering should plan the switch to SSR or pre-rendering.

Typical JavaScript SEO problems

In its guide to fixing search-related JavaScript problems, Google lists a number of recurring error patterns. The following overview arranges them by symptom and solution.

ProblemTypical symptomSolution
Soft 404 in single-page appsError pages return HTTP 200 and end up in the indexSend a real 404 status on the server or redirect via JavaScript to a 404 URL or set noindex
URL fragments (#/product)Subpages are not recognized as separate URLsUse the History API with clean paths
Dependence on stored stateContent only appears with a cookie, LocalStorage, or loginDeliver content statelessly, since the WRS doesn't keep state between fetches
Unsupported APIs or permissionsContent stays empty because, for example, location permission is expectedUse feature detection with a fallback
Outdated JS and CSS resources in the cacheRendered page breaks after a deploymentContent fingerprinting in file names, such as main.2bb85551.js
Web components without visible contentShadow DOM content is missing in the rendered HTMLBring content into the light DOM via slots and check the rendered HTML
Links without hrefSubpages are not discoveredUse real <a href> links
Loading only on scroll or clickProducts or paragraphs are missing in the indexLoad content without interaction, offer pagination with its own URLs

Two points deserve special attention. First, soft 404s: because the client-side error handling of a single-page app often returns status code 200, Google can index hundreds of empty error pages and thereby burden crawl budget and the quality assessment of the domain. Second, lazily loaded content: Googlebot doesn't scroll like a human and doesn't click “Load more” buttons. For category pages and lists it also applies that every page needs its own, linked URL, as explained in the guide to pagination in SEO.

Another frequently overlooked problem is the blocking of resources. If JavaScript files, CSS, or API endpoints are blocked via robots.txt, the WRS can't build the page completely. The result is a rendered page that looks different to Google than to users, without an error being recognizable in the source code.

How to check what Google actually sees

The most important principle is: check instead of assume. The source code in the browser shows the initial HTML, the developer tool shows the DOM in your browser, but neither necessarily shows what Google rendered. Proceed in this order:

  1. URL Inspection tool in Search Console: For a representative URL per page type, run the live test and open the rendered HTML. Check whether main content, headings, internal links, canonical, and structured data are present.
  2. Loaded resources and JavaScript console: In the same test, Google shows which resources could not be loaded and which JavaScript exceptions occurred. Blocked or faulty scripts are immediately visible here.
  3. Rich Results Test: The tool also renders with the WRS and is suitable if you have no Search Console access to the domain.
  4. Comparing initial HTML and rendered HTML: A crawler with and without JavaScript rendering shows which content and links arise exclusively through JavaScript. The larger this difference, the higher the risk.
  5. Crawl stats report: It shows the activity of Googlebot and the WRS. Google points out that client-side analytics tools may not capture this activity completely or accurately; server log files give the more accurate picture.
  6. Page indexing report: Accumulations of “Soft 404”, “Crawled – currently not indexed”, or “Duplicate, Google chose different canonical than user” often point to rendering or signal problems.

Diagnosis after a relaunch or ranking loss

Many JavaScript SEO problems don't become visible when a website is built but at the relaunch: a new front-end framework, a headless CMS, or a theme switch suddenly moves content that used to be in the HTML into client-side components. Rankings then don't fall immediately but gradually, as soon as Google has rendered and re-evaluated the new versions. The following approach has proven useful for the diagnosis:

  1. Narrow down the time: Match the start of the decline in Search Console against deployments, relaunch dates, and Google updates. A drop that begins exactly with a release points to a technical cause.
  2. Identify the affected page types: Are only category pages, only product pages, or only certain directories losing? A pattern by page type almost always points to a template or a component.
  3. Compare old and new: Set the initial HTML and the rendered HTML of the old version (from archives or crawls before the relaunch) against the new version: amount of text, headings, internal links, canonical, meta robots, structured data.
  4. Check signals in the initial HTML: Is a noindex from the staging environment still in the template? Does the canonical point to a wrong domain? Is the status code for non-existent URLs set correctly?
  5. Recount internal linking: If navigation, filters, or breadcrumbs work without a real href after the relaunch, deeper pages lose their internal linking. This often explains why subpages gradually drop out of the index.
  6. Evaluate log files: Server logs show which URLs and resources Googlebot actually fetches, whether API endpoints are reachable, and whether crawl frequency has collapsed after the relaunch.
  7. Correct, prioritize, validate: Fix errors with a large reach first, meaning templates and global components, test the correction in the URL Inspection tool, and request indexing for central URLs. Depending on the scope, recovery stretches over weeks because Google has to crawl and render the affected pages again.

Anyone who runs through these steps on a staging environment before go-live prevents most losses from the start. A structured overview of the basic checks is provided by our SEO basics checklist.

Best practices for development and SEO

Google's recommendations and our project experience yield rules that development and SEO teams should record together, ideally as acceptance criteria in every release:

  • Deliver search-relevant content on the server side: Main content, title, meta description, canonical, and structured data are in the first HTML fetch.
  • Send meaningful HTTP status codes: 404 for non-existent pages, 301 for permanent redirects, never an error page with 200.
  • History API instead of fragments: Every indexable view has its own, descriptive URL.
  • Use real links: Navigation, pagination, and filters that are meant to be indexed work with <a href>.
  • No dependence on state or permissions: Content loads without cookie consent, login, LocalStorage, or location permission.
  • Feature detection with a fallback: If a browser API is missing, the content is output anyway.
  • Content fingerprinting for resources: Versioned file names prevent the WRS from using outdated scripts after a deployment.
  • Don't block resources: JavaScript, CSS, and required API endpoints remain reachable for Googlebot.
  • Test rendered HTML regularly: After every larger release, check at least one URL per page type in the URL Inspection tool.

Our perspective on JavaScript SEO

In more than 25 years of visibility management, we have learned that JavaScript is rarely the actual problem. The problem is the assumption that Google will already see what the user sees. In ranking losses after a relaunch, we keep finding the same patterns in forensic analyses: content that now only arises on the client side, internal links without href, staging signals in the template, or error pages with status code 200. None of these patterns is visible in the browser, and that is why they often go undiscovered for months.

Our approach is data-driven: we compare initial HTML, rendered HTML, and log files instead of relying on individual tool warnings. And we recommend that companies treat rendering not as a decision of development alone but as a visibility decision. Anyone who chooses an architecture today decides not only on indexing at Google but also on whether answer systems of AI search can read the content at all. HTML delivered on the server side and cleanly structured is therefore for us not a technical detail but the basis of every sustainable visibility.

Support with JavaScript SEO

If you have lost visibility after a relaunch or a framework switch, or want to secure a rebuild, we offer suitable services. A technical audit costs €1,500 to €3,500, a forensic audit for root cause analysis of sudden ranking losses €1,500 to €5,500, and relaunch safeguarding starts from €1,500. Anyone who wants to bring the knowledge into their own team finds an entry in our Technical SEO workshop from €500. You will find all packages and prices in our overview How much does SEO cost? As a first step, you can request a free initial analysis.

Frequently asked questions about JavaScript SEO

1

Can Google read JavaScript at all?

Yes. Google renders pages with a current Chromium and indexes the rendered HTML. This only applies, however, if rendering succeeds without errors, all required resources are reachable, and there is no noindex in the initial HTML. Whether other search engines and AI crawlers execute JavaScript just as well is not assured.

2

Is server-side rendering always better for SEO?

For search-relevant pages, server-side rendering or static pre-rendering is the most robust choice, because content and signals are in the HTML immediately. For logged-in areas, configurators, or dashboards without search relevance, client-side rendering is unproblematic. Most projects do best with a hybrid solution per page type.

3

Should I still use dynamic rendering?

Google describes dynamic rendering as a workaround and not as a long-term solution. For legacy systems it can bridge a transition phase, but it requires maintaining two versions and is error-prone. Plan the switch to SSR or pre-rendering.

4

How do I recognize that JavaScript is costing me rankings?

Typical hints are a decline that coincides with a release, rising numbers for “Soft 404” or “Crawled – currently not indexed”, and missing content or links in the rendered HTML of the URL Inspection tool. The proof comes from comparing initial HTML, rendered HTML, and server log files.

Sources