Free SEO audit for new clients — claim yours
Home/Blog/Technical SEO/JavaScript SEO: How to Make JS Sites Search-Frie…
Technical SEO

JavaScript SEO: How to Make JS Sites Search-Friendly

JavaScript SEO: How to Make JS Sites Search-Friendly
Table of contents
  1. Key Takeaways
  2. How Google Processes JavaScript
  3. Rendering Options Compared
  4. JavaScript SEO Best Practices
    1. Use real links
    2. Use the History API, not fragments
    3. Return meaningful status codes
    4. Give every view a unique title, description and canonical
    5. Don't block JavaScript and CSS
    6. Make lazy-loaded content discoverable
    7. Keep performance in check
  5. How to Audit a JavaScript Site: Step by Step
  6. Quick Diagnosis Table
  7. Common JavaScript SEO Mistakes
  8. Related Guides
  9. Frequently Asked Questions
    1. Can Google crawl and index JavaScript?
    2. Is client-side rendering bad for SEO?
    3. Should I still use dynamic rendering?
    4. Do AI crawlers render JavaScript?
    5. How do I check what Google sees on a JavaScript page?
    6. Can I add noindex with JavaScript?
  10. Conclusion
  11. References

Modern websites are increasingly built with JavaScript frameworks such as React, Vue, Angular and Svelte. They make fast, app-like experiences possible, but they also change how search engines see your content. If the important text and links only appear after JavaScript runs, a single blocked file or rendering error can leave Google looking at an empty page.

This guide explains how Google processes JavaScript in 2026, which rendering approach is safest for SEO, and the practical rules for links, routing, metadata and status codes. You will also get a step-by-step audit process, code examples and the mistakes we see most often on JS-heavy sites.

New to the technical side of SEO? Start with our technical SEO beginner's guide, then come back here.

Key Takeaways

  • Google processes JavaScript pages in three phases: crawling, rendering and indexing.
  • Rendering is queued and can be delayed, so critical content and links should be in the initial HTML where possible.
  • Server-side rendering, static generation or hydration are preferred; dynamic rendering is now a workaround.
  • Use real <a href> links, History API routing and meaningful HTTP status codes.
  • Test with the URL Inspection tool and compare raw HTML with the rendered DOM.

How Google Processes JavaScript

According to Google's JavaScript SEO basics, Googlebot handles JavaScript web apps in three main phases:

  1. Crawling: Googlebot fetches the URL, checks robots.txt, and parses the raw HTML for links.
  2. Rendering: pages that return a 200 status are queued for rendering. A headless Chromium then executes the JavaScript.
  3. Indexing: Google uses the rendered HTML to index content and discover more links.

“The page may stay on this queue for a few seconds, but it can take longer than that.”

— Google Search Central, Understand JavaScript SEO basics

Two practical consequences follow. First, anything in the initial HTML is seen immediately, while JavaScript-only content waits for rendering. Second, Google notes that when it encounters a noindex tag, it may skip rendering altogether, so robots directives must be correct in the raw HTML.

Other crawlers are less capable. Many social preview bots, SEO tools and AI crawlers do not execute JavaScript reliably, which matters if you want your content cited in AI Overviews and other AI search experiences.

Rendering Options Compared

Your rendering strategy is the single biggest JavaScript SEO decision. Google states that server-side or pre-rendering is still a great idea because it makes sites faster for users and crawlers.

ApproachHow it worksSEO riskTypical tools
Client-side rendering (CSR)Server sends a near-empty HTML shell; the browser builds the pageHigher: content depends on successful renderingCreate React App-style SPAs, plain Vue/Angular SPAs
Server-side rendering (SSR)Server sends full HTML for each request; JS hydrates itLowNext.js, Nuxt, SvelteKit, Angular SSR
Static site generation (SSG)HTML is pre-built at deploy timeVery lowAstro, Next.js static export, Eleventy, Hugo
Hybrid / incrementalMix of static and server rendering per routeLowNext.js, Nuxt, Remix
Dynamic renderingBots get pre-rendered HTML; users get CSRMedium: extra complexity to maintainPrerender services, Rendertron (archived)

Google's dynamic rendering page now calls it a workaround and not a recommended solution because it creates additional complexity, and recommends server-side rendering, static rendering or hydration instead. For a deeper technical comparison, see web.dev's Rendering on the Web.

JavaScript SEO Best Practices

Google can only discover links that are <a> elements with an href attribute. Click handlers on spans or buttons are invisible to crawlers.

<!-- Good: crawlable -->
<a href="/services/technical-seo/">Technical SEO</a>

<!-- Bad: not crawlable -->
<span onclick="goTo('/services/technical-seo/')">Technical SEO</span>
<a href="javascript:void(0)" onclick="goTo('/pricing')">Pricing</a>

Crawlable links are also the foundation of a good internal linking strategy.

Use the History API, not fragments

Google advises using the History API for routing between views and not using URL fragments (#/products) to load different content, because Googlebot cannot reliably resolve them.

<!-- Avoid -->
<a href="#/products">Our products</a>
<!-- Use -->
<a href="/products">Our products</a>

Return meaningful status codes

Single-page apps often return 200 OK for every route, including ones that show “not found”. That creates soft 404s. Google suggests either redirecting to a URL where the server returns a 404, or adding a noindex robots meta tag to error views:

fetch(`/api/products/${id}`)
  .then(res => res.json())
  .then(product => {
    if (!product.exists) {
      // Option 1: send the user to a URL that returns a real 404
      window.location.href = '/not-found';
    }
  });

Our guide to fixing 404 errors explains soft 404s in more detail.

Give every view a unique title, description and canonical

Set <title>, meta description and canonical per route, ideally on the server. Framework tools such as Next.js metadata APIs or Nuxt's useHead make this straightforward. See our guides to title tags and the canonical tag.

Don't block JavaScript and CSS

If robots.txt blocks the scripts or API endpoints needed to render content, Google cannot render the page as users see it. Our comparison of robots.txt vs meta robots explains what to block and what to leave open.

Make lazy-loaded content discoverable

Googlebot does not scroll or click like a user. Load content when it enters the viewport (for example with IntersectionObserver or native loading="lazy" for images) rather than on user interactions, and use paginated URLs for infinite scroll.

Keep performance in check

Heavy bundles hurt both rendering and user experience, especially Interaction to Next Paint (INP). Code-split, defer non-critical scripts and remove unused libraries. Our Core Web Vitals guide covers the metrics.

How to Audit a JavaScript Site: Step by Step

  1. Compare raw and rendered HTML. View source (raw) and inspect the DOM (rendered). Note which content and links only exist after rendering.
  2. Use URL Inspection in Search Console. Test the live URL and check the rendered HTML, screenshot, loaded resources and console errors.
  3. Run the Rich Results Test to confirm structured data appears in the rendered output.
  4. Crawl with JavaScript rendering on and off in a tool such as Screaming Frog or Sitebulb. Large differences in word count or link counts show where you rely on rendering.
  5. Check status codes for missing products or deleted posts to catch soft 404s.
  6. Search Google for a distinctive sentence that only loads via JavaScript to confirm it was indexed.
  7. Review Crawl Stats in Search Console for spikes in JavaScript or API requests.

Quick Diagnosis Table

SymptomLikely causeFix
Pages indexed with no content or the wrong titleCSR shell indexed before rendering; render errorsSSR/SSG, or set metadata server-side
Deep pages never discoveredLinks built with click handlers or fragmentsUse <a href> and History API
Error pages indexedSPA returns 200 for missing contentRedirect to a 404 URL or add noindex
Content missing in URL Inspection screenshotBlocked JS/CSS or API in robots.txtAllow required resources
Structured data not detectedInjected late or after interactionRender JSON-LD on the server

Common JavaScript SEO Mistakes

  • Relying on dynamic rendering for new builds instead of SSR or SSG.
  • Removing noindex with JavaScript. Google may never render the page to see the change.
  • Content behind interactions such as “load more” buttons or tabs fetched only on click.
  • Features that need permissions, such as geolocation, gating content; Googlebot declines permission requests.
  • Using JavaScript redirects where a server-side redirect is possible; see 301 vs 302 redirects.
  • Not testing after deploys. A framework upgrade can silently change what is server-rendered.

Frequently Asked Questions

Can Google crawl and index JavaScript?

Yes. Googlebot renders pages with an evergreen version of Chromium and indexes the rendered content. However, rendering happens after crawling and can be delayed, and errors or blocked resources can stop content from being seen.

Is client-side rendering bad for SEO?

Not automatically, but it adds risk. Content and links only exist after JavaScript runs. Server-side rendering, static generation or hydration make content available in the initial HTML, which is faster and more reliable for users and crawlers.

Should I still use dynamic rendering?

Google now describes dynamic rendering as a workaround rather than a recommended solution. Prefer server-side rendering, static rendering or hydration for new projects.

Do AI crawlers render JavaScript?

Many AI and third-party crawlers do not execute JavaScript reliably, so content that only appears after rendering may be invisible to them. Serving key content in the initial HTML is the safest approach if you want to be cited in AI search.

How do I check what Google sees on a JavaScript page?

Use the URL Inspection tool in Search Console (view the crawled page and rendered HTML) or the Rich Results Test. Both show the rendered DOM and JavaScript console errors.

Can I add noindex with JavaScript?

It is risky. Google may skip rendering when it sees noindex in the initial HTML, so changing or removing noindex with JavaScript may not work as expected. Set robots directives in the server response.

Conclusion

JavaScript and SEO work well together when the important parts of each page, namely content, links, metadata and status codes, are available without depending on a perfect render. Choose server-side or static rendering where you can, use real links and clean URLs, and test what Google actually sees after every major release.

Building or rebuilding a JavaScript site? Our web development and SEO teams work together to ship framework sites that search engines can crawl from day one. Get a free quote for a JavaScript SEO audit.

References

  1. Google Search Central: Understand JavaScript SEO basics
  2. Google Search Central: Fix Search-related JavaScript problems
  3. Google Search Central: Dynamic rendering as a workaround
  4. Google Search Central: Link best practices for Google
  5. web.dev: Rendering on the Web
  6. Semrush: JavaScript Rendering — What It Is and How to Handle It
My SEO Experts Team

Our team of SEO and digital marketing specialists has been helping businesses grow organically since 2018. More about us.

Keep reading

Related articles

Ready to grow your business online?

Get a free, no-obligation proposal tailored to your goals and budget.

CallFree Quote