Skip to content

JavaScript SEO: How to Make JS Sites Crawlable

By TheLinksMaster · SEO Editorial Team
Published: August 11, 2026 Last Updated: October 15, 2026

Google's Two-Wave Rendering Process

Googlebot uses a two-wave indexing process for JavaScript-rendered content. In the first wave, Googlebot fetches and indexes the raw HTML of your page without executing any JavaScript. Content that exists only in JavaScript (like text rendered by React components or data loaded via API calls) is invisible during this first wave. In the second wave, Googlebot queues the page for rendering, executes the JavaScript, and updates the index with the fully rendered content.

The gap between the first wave (HTML discovery) and second wave (JavaScript rendering) can range from seconds to days. During this delay, your JavaScript-rendered content is not in Google's index. Pages that rely entirely on JavaScript for their content, links, and metadata may appear incomplete or missing from search results until the rendering wave completes.

Googlebot runs Chromium at version 120 or later (updated regularly) and supports modern JavaScript features including ES2020 syntax, CSS Grid, Flexbox, Web Components, and Shadow DOM. However, some features like requestIdleCallback and certain Web APIs may not function identically in Googlebot's headless Chromium as they do in a standard browser.

Common JavaScript SEO Problems

SPA routing is the most prevalent issue. Single-page applications use client-side routing to change the displayed content without reloading the page. When Googlebot first requests your page, it receives the same HTML shell for every route. The specific content for /blog/post-title only appears after JavaScript executes and updates the DOM.

If your SPA uses pushState for routing without server-side fallback, Googlebot may not discover pages that are only accessible through client-side navigation. Every route must be accessible by directly requesting its URL. If visiting https://example.com/blog/post-title in a browser with JavaScript disabled shows a blank page or loading spinner, Googlebot may not index that content.

Lazy loading with JavaScript defeats search engine crawlers. Content that loads on scroll events, intersection observer triggers, or button clicks is invisible to Googlebot because the crawler does not trigger user interactions. Product descriptions, article text, and navigation links hidden behind JavaScript-triggered events may never be indexed.

Hash-based routing (example.com/#/page) is invisible to search engines. Everything after the hash is treated as a fragment identifier and is never sent to the server. Googlebot sees only the base URL (example.com/) regardless of which hash route is active. Replace hash routing with history-based pushState routing.

SSR vs CSR: Choosing the Right Approach

Client-Side Rendering (CSR) generates all content in the browser using JavaScript. The server sends a minimal HTML shell with script tags, and JavaScript builds the entire page after loading. CSR is simpler to implement and deploy but creates the two-wave indexing delay. Use CSR for authenticated dashboards, internal tools, or pages that do not need search engine indexing.

Server-Side Rendering (SSR) generates complete HTML on the server for every request. The browser receives fully rendered content immediately, eliminating the rendering delay. Googlebot sees the complete page content in the first wave. SSR is essential for pages that need search engine visibility: product pages, blog posts, category pages, and landing pages.

Static Site Generation (SSG) pre-renders pages at build time. The server sends static HTML files with no rendering required. SSG combines the SEO benefits of SSR with the performance benefits of static hosting. Use SSG for content that changes infrequently: documentation, blog posts, marketing pages, and knowledge bases.

Incremental Static Regeneration (ISR) updates static pages on a schedule without rebuilding the entire site. Next.js and similar frameworks support ISR, which serves pre-rendered HTML while periodically regenerating pages in the background. This approach is ideal for e-commerce product pages that change prices and availability frequently.

// Next.js ISR example
export async function getStaticProps() {
  const product = await fetchProduct(productId);
  return {
    props: { product },
    revalidate: 3600, // Regenerate every hour
  };
}

Testing JavaScript Rendering

Google's Mobile-Friendly Test (search.google.com/test/mobile-friendly) shows exactly what Googlebot sees. It executes JavaScript and displays the rendered DOM, revealing any content that is missing or broken after rendering. Compare the "Rendered HTML" tab with the "Raw HTML" tab to identify content that depends on JavaScript execution.

Search Console's URL Inspection tool provides the same rendering view for URLs already in your index. It shows the rendered HTML as Googlebot sees it, any JavaScript errors during rendering, and whether the content is indexable. Use this to verify that new pages are being rendered correctly after deployment.

The Fetch as Google tool (within URL Inspection) shows the rendered page and any issues encountered during the two-phase rendering process. If content appears in the rendered view but not in the indexed version, it suggests a rendering timing issue where Googlebot's renderer did not wait long enough for the JavaScript to complete execution.

Practical JavaScript SEO Fixes

Ensure all critical content exists in the initial HTML response. If your page title, meta description, canonical URL, Open Graph tags, and primary heading exist only in JavaScript-generated DOM, Googlebot may miss them during the first crawl wave. Move these elements to server-rendered HTML:

<!-- Server-rendered: always visible to crawlers -->
<head>
  <title>Product Name - Store Name</title>
  <meta name="description" content="Product description here">
  <link rel="canonical" href="https://example.com/product">
</head>
<body>
  <h1>Product Name</h1>
  <div id="app"><!-- React app hydrates here --></div>
</body>

For SPAs that must handle routing client-side, implement a pre-rendering service that generates static HTML for each route. Services like Prerender.io, React Snap, or Puppeteer-based prerendering intercept crawler requests and serve pre-rendered HTML instead of the JavaScript shell. Configure your server to detect search engine User-Agents and serve pre-rendered content to them while serving the JavaScript app to regular browsers.

Validate your JavaScript SEO implementation with our page speed checker to ensure that server-side rendering does not negatively impact performance, and test every critical page with Google's Mobile-Friendly Test to verify that content renders correctly for search engine crawlers.

Frequently asked questions

What is the main takeaway from this guide on javascript seo: how to make js sites crawlable?

The guide covers javascript seo: how to make js sites crawlable end to end: what it is, why it matters, and the exact steps to apply it. Skim the key takeaways first, then follow the step-by-step parts in order — most readers can apply the first improvements the same day.

How long does it take to see results from javascript seo: how to make js sites crawlable?

For most sites, changes made from this javascript seo: how to make js sites crawlable guide start showing measurable movement within two to six weeks. Track the affected pages in Google Search Console to see when search engines pick up your updates.

Do I need paid tools to follow this javascript seo: how to make js sites crawlable guide?

No. Every step in this javascript seo: how to make js sites crawlable guide can be completed with free tools, including the free utilities on this site. Paid platforms add convenience and historical data, but they are not required to get results.

TheLinksMaster editorial team

Reviewed by TheLinksMaster

SEO Editorial Team

Our editorial team tests every tool and guide on this site against real websites. We update content when search algorithms change so you always get current, practical SEO advice.

Want a quick SEO check on a page? Run the free SEO checker and get a scored report with prioritised fixes in seconds.
Free SEO checker