GrowthHasten

JavaScript SEO: How to Make JS Sites Crawlable and Indexable

JavaScript builds most of the modern web, and search engines read that content in a later step than the first crawl. This guide explains how Googlebot renders JavaScript, why the delay causes indexing gaps, and how to confirm what Google actually sees.

Anshuman Sinha

Written by Anshuman Sinha

Published July 30, 2026
Updated August 22, 2026
11 min read
Close-up of colorful JavaScript source code displayed on a screen

JavaScript SEO is the practice of making sure search engines can crawl, render, and index the content your site builds with JavaScript, not just the bare HTML your server sends first. It matters because modern frameworks assemble much of the page in the browser, and Google reads that assembled content in a separate, later step than the initial crawl. This guide is for founders, marketers, and developers running sites built on React, Vue, Angular, or any stack where JavaScript shapes what visitors see. It covers how Googlebot handles JavaScript, why the render delay causes indexing problems, the three rendering strategies, how to check what Google actually sees, the failure modes we run into most, and a diagnostic checklist you can run today. The principle underneath all of it: if content exists only after JavaScript runs, treat its visibility to search engines as something to verify, not assume.

The short version

  • Google does render JavaScript. The real risk is not invisibility but timing: rendering happens in a second wave that can lag behind the crawl, so JS-dependent content and links get indexed late or inconsistently.
  • view-source shows the raw HTML your server sent. The rendered DOM shows the page after JavaScript runs. Most JavaScript SEO problems live in the gap between the two.
  • Anything that has to rank, primary content, internal links, titles, and canonicals, should be present in the server HTML, not appear only after client-side scripts execute.
  • Googlebot does not scroll, click, or dismiss cookie prompts. Content that needs those actions to load may never be seen.
  • Hash-based routes (URLs with a # fragment) are not treated as separate pages. Serve real URLs through the History API instead.

What is JavaScript SEO, and why does it matter?

It is the work of closing the gap between what your JavaScript builds and what search engines actually index. On a single-page app, the server often sends a near-empty HTML shell, and the browser fills in the content, links, and metadata after the scripts run. A human sees a finished page. A crawler, at first, sees the shell.

That gap is where rankings quietly disappear. If your headings, body copy, internal links, or canonical tags depend entirely on client-side rendering, Google has to do extra work to see them, and sometimes it indexes a thinner version of the page than your visitors get. JavaScript SEO is not a separate discipline bolted onto the rest. It sits inside the crawl, render, index sequence covered in our technical SEO guide, and it becomes urgent the moment JavaScript owns the content rather than merely enhancing it.

How does Googlebot process JavaScript?

In three stages, and keeping them separate is the whole game: crawl, render, index. Googlebot first fetches the raw HTML response from your server. If the page needs JavaScript to build its content, the URL is placed in a render queue, where a headless, evergreen version of Chromium executes the scripts and produces the rendered HTML. Only then does indexing work from that rendered output.

This is the second wave, and it is deferred rather than instant. The render can follow the crawl within minutes or take considerably longer, depending on the size of the queue and the resources a page demands. Google's own explanation of how Search works describes this crawl, render, index pipeline, and our breakdown of how Google Search works walks through each stage. The rendering service behaves like a real browser, but a patient one that does not interact with the page.

Why does the render delay cause indexing problems?

Because Google can index the first-wave HTML before the rendered version is ready, and sometimes acts on the thinner copy. When the raw HTML is close to empty, the initial crawl finds little content and few links to follow, so discovery of the rest of your site slows down.

The specific ways this bites are consistent. Internal links injected by JavaScript are discovered late, which delays how quickly new pages get found and how fast authority flows to them. Titles, meta descriptions, and canonical tags set by client-side scripts can be missed or can conflict with whatever was in the raw HTML, and when signals conflict, Google may not pick the version you intended. On a large site, that lag compounds: every render competes for the same queue, so the pages that most depend on JavaScript are often the slowest to fully index.

Client-side, server-side, or dynamic rendering: which should you use?

Serve the content that has to rank in the initial HTML, which means server-side rendering or static generation for anything important, and reserve client-side rendering for enhancement. The table below compares the practical options.

ApproachHow it worksBest for
Client-side rendering (CSR)Server sends a shell; the browser builds content with JavaScriptLogged-in app views and dashboards that do not need to rank
Server-side rendering (SSR)Server runs the JavaScript and returns fully built HTML per requestPages with frequently changing, rankable content
Static generation (SSG)Pages are built into HTML ahead of time and served as filesBlogs, docs, and marketing pages that change infrequently
Dynamic renderingBots get a prerendered copy; users get the client-side appA last-resort workaround, not a long-term strategy

Google now treats dynamic rendering as a stopgap rather than a recommended pattern, because maintaining two versions of a page invites drift and cloaking risk. If you are on a React framework, the practical routes are SSR and static generation, and our Next.js SEO guide covers how those map to real rendering modes. When the choice is genuinely architectural, our web development team can help you weigh the trade-offs before you commit.

How do you check what Google actually sees?

Compare three views of the same page: the raw HTML, the rendered DOM, and the version Google reports. Each one exposes a different class of problem, and the gaps between them are the whole diagnosis.

Raw HTML. Use view-source in your browser, or fetch the URL with a plain request. This is exactly what arrives before any JavaScript runs. Search the source for a sentence of your main content and for your key internal links. If they are missing here, they depend on rendering.

Rendered DOM. Open developer tools and inspect the live element tree, which shows the page after scripts execute. If your content appears in the rendered DOM but not in view-source, that is the client-side gap in plain sight.

What Google reports. Run the URL Inspection tool in Search Console and view the rendered HTML, the screenshot, the loaded page resources, and any JavaScript console messages. This is the closest look at what Googlebot built. If content is present in your browser's rendered DOM but absent from Google's rendered HTML, a resource is blocked, a script is failing, or the render is timing out.

What are the most common JavaScript SEO failures?

Most of them trace back to content or signals that appear only after an action Googlebot never takes. These are the patterns we find most often, and the table pairs each with its usual symptom and fix.

Failure modeSymptomFix
Content and links injected only by JavaScriptThin raw HTML; late or missing indexingRender primary content and links server-side
Scripts or CSS blocked in robots.txtGoogle renders a broken or empty pageAllow crawling of the resources the page needs to render
Scripts that error or time outRendered HTML in Search Console is incompleteFix console errors; reduce heavy render-blocking work
Hash-based routing (/#/page)Only one URL indexed for the whole appUse the History API so each view has a real URL
Lazy-loaded content needing scroll or clickBelow-the-fold content never indexedUse native lazy loading or an IntersectionObserver

The lazy-loading case deserves a note, because it surprises people. Googlebot does not scroll a page the way a human does, so content that only fetches on a scroll event, a click, or after a cookie banner is dismissed may never load during rendering. Native lazy loading with loading="lazy" and IntersectionObserver-based loading both work because Googlebot supports them; custom scroll-triggered loaders often do not. Infinite scroll fails for the same reason a hash-based route does: there is no crawlable URL for the second batch, and our guide to infinite scroll and pagination covers the History API fix that gives every batch a real address.

The signals Google uses to discover, understand, and rank the page: internal links, the title, the meta description, the canonical tag, the robots meta tag, and ideally your structured data. If any of these is written only by client-side JavaScript, you are betting on the render completing correctly and on time.

Links deserve particular care. A crawlable link is a real anchor with an href attribute, for example <a href="/pricing">. A <div> or button that navigates through an onclick handler is not a link Google will reliably follow, because there is no URL in the markup to queue. Put your navigation and your important cross-links in real anchors, present in the initial HTML, and the rest of your internal linking work in our SEO services has something solid to build on.

How does JavaScript affect Core Web Vitals?

Heavily, and usually not in your favor, because shipping and executing JavaScript costs time on exactly the metrics Google measures. Large bundles delay the largest contentful paint, and hydration, the step where a framework attaches interactivity to server-rendered HTML, can block the main thread and hurt interaction responsiveness.

The three metrics to watch are LCP for loading, INP for responsiveness, and CLS for visual stability, all defined on web.dev's Core Web Vitals reference. JavaScript most directly threatens LCP and INP: a page that renders instantly on your laptop can feel sluggish on a mid-range phone once a megabyte of script has to download, parse, and execute. Measure with field data from real users, ship less JavaScript, and defer what is not needed for the first view. Our Core Web Vitals guide covers the optimization side in depth.

How do you run the JavaScript SEO diagnostic checklist?

Work through six questions in order, all anchored to one test: is the thing in the rendered HTML that Google reports, not just in your browser? Run this against a template page of each type on your site, not every URL.

Content. Is your main copy present in view-source? If not, is it present in Search Console's rendered HTML? Does the rendered version match what users see?

Links. Are your primary internal links real anchors with href attributes in the initial HTML? Can you find them in view-source?

Metadata. Are the title, meta description, canonical, and robots tags in the raw HTML? Do any client-side scripts overwrite them with something different?

Resources. Are your JavaScript and CSS files crawlable, or blocked in robots.txt? Do the page resources in URL Inspection all load?

Routing. Does every meaningful view have its own clean URL served through the History API, with no reliance on # fragments?

Performance. Do LCP and INP stay in the good range on mobile field data, or is bundle size dragging them down?

When should you not add server-side rendering?

Often. If your site is static or mostly HTML already, a marketing site, a blog, a documentation set, adding SSR buys you complexity you do not need and a server-side runtime you now have to maintain. The content already arrives in the initial HTML, so there is no render gap to close.

SSR earns its cost when JavaScript genuinely owns rankable content and that content changes often enough that pre-building it is impractical. For pages that change rarely, static generation gives you the same crawlable HTML without a live rendering server. And for app views behind a login, where nothing needs to rank, plain client-side rendering is perfectly fine. Reach for the heavier architecture only when the content that has to rank truly depends on JavaScript to exist, and not before.

Where should you start this week?

The habit worth building is a simple reflex before you trust any JavaScript-built page: check the rendered HTML, never just the browser view. Rendering behavior drifts every time you ship a new bundle, change a framework setting, or add a third-party script, and the damage stays invisible until you look at what Google actually stored.

This week, pick your three most important JavaScript-dependent pages and run URL Inspection on each. Confirm your main content, your internal links, and your canonical tag all survive into Google's rendered HTML. If any of the three comes back thin, you have found the highest-priority fix on your site, and you found it before it cost you a quarter of lost visibility.

Is JavaScript Hurting Your Rankings?

If your JavaScript site is not getting crawled or indexed properly, GrowthHasten can diagnose and fix the rendering path.

Talk to an SEO Expert
FAQ

Frequently Asked Questions

Can Google crawl and index JavaScript websites?

Yes. Google renders JavaScript using an evergreen version of Chromium, so content built by frameworks like React, Vue, or Angular can be indexed. The catch is timing: rendering happens in a second wave that runs after the initial crawl and can be delayed. If critical content, links, or metadata appear only after scripts run, Google may index a thinner version first. Serving that content in the server HTML avoids the risk.

What is the difference between view-source and the rendered DOM?

view-source shows the raw HTML your server returns before any JavaScript executes, which is what Googlebot sees on the first crawl. The rendered DOM, visible in browser developer tools, shows the page after scripts have run. If your content appears in the rendered DOM but not in view-source, it depends on client-side rendering. Most JavaScript SEO problems live in that gap, so always compare both against Search Console's rendered HTML.

Does JavaScript hurt SEO?

Not by itself. JavaScript hurts SEO when the content that needs to rank exists only after client-side scripts run, when required resources are blocked in robots.txt, or when heavy bundles slow Core Web Vitals. Google renders JavaScript, but rendering is deferred and can lag. Keep primary content, internal links, titles, and canonical tags in the server HTML, and use JavaScript for enhancement rather than for the content that has to be indexed.

How do I check what Googlebot sees on my JavaScript page?

Use the URL Inspection tool in Google Search Console. It shows the rendered HTML Googlebot builds, a screenshot, the page resources that loaded, and any JavaScript console errors. Compare that rendered HTML against your browser's view-source and rendered DOM. If content is present in your browser but missing from Google's rendered HTML, a resource is likely blocked, a script is failing, or the render is timing out.

Do I need server-side rendering for SEO?

Not always. If your site is already static or mostly HTML, such as a blog or marketing site, the content arrives in the initial HTML and there is nothing to fix. Server-side rendering matters when JavaScript owns rankable content that changes often. For content that changes rarely, static generation gives the same crawlable HTML without a live rendering server. App views behind a login that do not need to rank are fine as client-side rendering.

Share This Article

Anshuman Sinha
Written by

Anshuman Sinha

AI SEO Specialist, GrowthHasten

Anshuman Sinha is an AI SEO Specialist and Computer Science Engineer with over three years of experience in SEO and five years in web development. He specializes in Technical SEO, AI Search Optimization (AEO and GEO), SaaS SEO, and building high-performance websites with modern technologies.

View profile

Stay Ahead Of The Curve

Get the latest SEO insights and growth strategies delivered to your inbox. No spam, just actionable advice.