JavaScript SEO is the practice of making JavaScript-rendered websites crawlable, indexable, and rankable by search engines. Because Googlebot must download and execute your JavaScript before it can see your content, sites built with client-side rendering often get crawled and indexed poorly unless you choose the right rendering strategy and verify it with Search Console.
This guide covers why JavaScript sites struggle with SEO, how Googlebot renders JavaScript, the rendering strategies available today, the Core Web Vitals that punish heavy JavaScript, and how to debug problems with the URL Inspection tool.
Why Do Javascript Sites Struggle with SEO?
Search engines evolved around HTML. When a page is nothing more than HTML, the crawler reads the content immediately and decides what to index. A JavaScript site inverts that: the HTML is a mostly empty shell, and the real content exists only after the browser downloads scripts, executes them, and renders the result.
That adds failure points that plain HTML never has:
- Slow or broken JavaScript delays content from ever appearing
- Rendered content is invisible to the crawler until the second crawl pass
- Images and text injected by scripts can be missed if rendering times out
- Duplicate or blocked URLs confuse indexation if routes are not handled properly
- Heavy bundles slow down the Core Web Vitals that Google uses in ranking
None of this means JavaScript cannot rank. It means the rendering pipeline is part of your technical SEO, and you have to manage it deliberately.
How Does Googlebot Render Javascript?
Googlebot crawls JavaScript sites in two passes. In the first pass it fetches the raw HTML and queues the URLs it finds. The queue is prioritized based on signals like site authority, content importance, and how long a page has been waiting. In the second pass Googlebot renders the page with a headless Chromium browser, executes the JavaScript the way a user's browser would, and indexes the rendered DOM.
Two consequences follow. First, a queue is a bottleneck: pages that are not important enough, or that wait too long, may never get rendered and indexed. Second, rendering can fail silently, so content that only exists in JavaScript may never be indexed even though the page has been crawled.
Google also considers the rendered HTML to be canonical for indexing. If your rendered output differs from what you intended, the search result reflects what Googlebot rendered, not what you wrote. For a deep look at one specific technique that grew out of these constraints, see our dynamic rendering guide and when it still makes sense.
TL;DR
- JavaScript sites rank fine if you handle rendering: Googlebot runs a second, headless-browser pass that executes JavaScript, but rendering is queued and can fail silently, so content must be discoverable in the raw HTML too.
- Choose a rendering strategy on purpose: server-side rendering (SSR) and static generation (SSG) deliver HTML immediately, client-side rendering (CSR) offloads everything to the browser, and incremental static regeneration (ISR) mixes both.
- Core Web Vitals are the ranking constraint: large JavaScript bundles inflate LCP, block the main thread and push up INP, and shift layouts to worsen CLS.
- Debug with the URL Inspection tool: fetch and render the page, compare the returned HTML to your source, and check the reasons behind indexation issues.
- Next.js and SSR frameworks remove most of the guesswork: for content-heavy React and Vue apps, prefer a framework with SSR or SSG over a hand-rolled client-only SPA.
What Are the Rendering Strategy Options?
The four strategies differ in where content is generated and how fresh it is. Most production sites combine several.
Client-Side Rendering (CSR)
CSR ships an empty HTML shell and builds the whole page in the browser. It is simple to build but the hardest to index well: crawlers must wait for the second pass, the queue decides who gets rendered, and every user pays a JavaScript tax before seeing content. A hand-rolled CSR SPA is where most JavaScript SEO problems come from.
Server-Side Rendering (SSR)
SSR generates the full HTML on the server for every request and sends it to both browsers and crawlers. Content is immediately visible, which is ideal for SEO and social sharing. The trade-off is that every request pays a server render cost, so SSR can struggle under load unless it is combined with caching.
Static Site Generation (SSG)
SSG renders pages to static HTML at build time and serves them from a CDN. It is the fastest option for content that does not change per user, like docs, blog posts, and marketing pages, and it is nearly perfect for SEO because the HTML arrives fully formed. The cost is that content changes require a rebuild.
Incremental Static Regeneration (ISR)
ISR, popularized by Next.js, serves statically generated pages but rebuilds them in the background when the underlying data changes. It gives you the SEO benefits of SSG with the freshness of SSR for pages that change occasionally.
Hydration
Hydration is the process of attaching event handlers to server-rendered HTML so the page becomes interactive. Hydration itself is not a rendering strategy, but it is where Core Web Vitals go wrong: if hydration scripts are heavy, the page looks ready but takes time to become responsive. Modern frameworks offer partial and selective hydration to limit this cost.
How Do Core Web Vitals Affect Javascript Apps?
Google evaluates user experience with three Core Web Vitals, and all three are routinely harmed by JavaScript.
Largest Contentful Paint (LCP)
LCP measures how long the main content takes to appear. Client-rendered apps push this out because the largest element only renders after scripts execute and data fetches resolve. Static HTML, pre-rendered markup, and a fast hero image help LCP more than any client-side trick.
Interaction to Next Paint (INP)
INP replaced First Input Delay and measures how quickly the page responds to clicks, taps, and key presses. Long main-thread tasks from JavaScript parsing, hydration, and third-party scripts inflate INP. Code-splitting, deferring non-critical scripts, and reducing work on interaction are the levers that matter.
Cumulative Layout Shift (CLS)
CLS measures unexpected layout movement. Client-rendered content causes it constantly: images appear late and push text down, fonts swap, and injected widgets resize containers. Reserving space for images and content, and avoiding layout-triggering DOM injection, keep CLS in the good range. For the full set of fixes, see our Core Web Vitals optimization guide for SPAs.
What Are the Common Javascript SEO Mistakes?
- Shipping a client-only SPA for content pages that need ranking
- Letting the page depend on localStorage or cookies for content, so crawlers see an empty page
- No pre-rendered or fallback content for the first crawl pass
- Blocking JavaScript, CSS, or image files in robots.txt, which prevents rendering
- Client-side routing without proper title, meta, and canonical handling
- Lazy-loading content that crawlers never trigger
- Single-page app history that generates near-duplicate URLs and dilutes signals
Most of these are covered in depth in our React app SEO mistakes guide, and the same patterns apply to any JavaScript framework.
How Do You Debug Javascript SEO with the URL Inspection Tool?
The URL Inspection tool in Google Search Console is the definitive way to see what Googlebot actually receives. The workflow:
- Paste the URL into the inspection bar and wait for the status report
- Request "Test live URL" to force a fresh crawl instead of using cached data
- Open "View Crawled Page" and compare the rendered HTML to what you expect
- Switch between the fetched HTML and rendered HTML views to see if content appears only after rendering
- Check the indexation reason, especially "Discovered - currently not indexed" and "Crawled - currently not indexed"
If content is missing from the rendered HTML, the problem is in your rendering pipeline. If content appears in the rendered HTML but the page is not indexed, the problem is likely queue depth, crawl budget, or a signal issue. If the fetched raw HTML already lacks your content, crawlers that never render will never see it either, so add server-side or pre-rendered content as the priority fix.
How Do Javascript Frameworks Compare for SEO?
Framework | Default Rendering | SEO Strength | Best For |
Next.js | SSR, SSG, or ISR per page | Highest: full control of rendering per route | Content-heavy React sites that must rank |
React (Create React App or Vite) | CSR by default | Low without extra tooling | Apps behind a login where SEO is not needed |
Angular | CSR, SSR via Angular Universal | Medium: needs Universal or prerendering | Large enterprise apps with Angular teams |
Vue (Nuxt) | SSG or SSR via Nuxt | High when using Nuxt with pre-rendering | Vue sites and marketing pages |
Astro / SvelteKit | SSG-first by default | Very high: ships minimal JavaScript | Content sites that want speed and simplicity |
Choose the framework by what you actually need to rank. For content pages, default to SSG or SSR. For application features behind authentication, client-side rendering is fine and not an SEO problem at all.
Building in React specifically? Our React SEO guide covers SSR, SSG, ISR, metadata, and Core Web Vitals fixes for React apps.
Frequently Asked Questions About Javascript SEO
Is Javascript SEO Really Necessary?
Yes if your site uses JavaScript to render content that you want indexed. Googlebot does execute JavaScript in a second rendering pass, but rendering is queued, can fail silently, and adds delay. Content that exists only in JavaScript may never be indexed, so you should either make it available in the raw HTML or verify rendering with the URL Inspection tool.
Does Google Execute Javascript When Crawling?
Yes. Googlebot runs a headless Chromium browser in a second pass and indexes the rendered DOM, not just the raw HTML. That rendering pass is queued based on signals like authority and content importance, so it is not guaranteed and it is not instant.
Is Client-Side Rendering Bad for SEO?
Not always, but it is the hardest option to index well. A client-only SPA depends on the second crawl pass, and crawlers that do not render will see an empty page. Use CSR for app features behind a login, and prefer SSR or SSG for pages you need to rank.
What Is the Difference Between SSR and SSG for SEO?
Both deliver HTML that crawlers can read immediately. SSR renders on the server for each request, so content is always fresh but costs server time per request. SSG builds static HTML once at deploy time, so it is faster and cheaper to serve, but content changes require a rebuild. SEO results are similar; the choice is about freshness versus performance.