Technical SEO

JavaScript SEO: How Google Renders JavaScript and How to Avoid Indexing Problems

What happens when Google meets a JavaScript-heavy page, where things go wrong, and how to test what Google actually sees.

Google can render JavaScript, but rendering adds a step that static HTML doesn’t need. Content, links and metadata that only appear after scripts run can be delayed, missed or interpreted differently from what visitors see.

This guide explains Google’s three-phase process, the problems that come up most on React, Vue, Angular and heavily scripted WordPress or Shopify themes, and a testing routine that shows exactly what Googlebot sees.

Short answer: Google processes JavaScript pages in three phases: crawling, rendering and indexing. Pages with a 200 status are queued for rendering, which may take seconds or longer. To avoid problems, put links in real <a href> elements, keep titles and canonicals in the initial HTML, don’t block scripts in robots.txt, avoid soft 404s in single-page apps, and use server-side rendering where you can.

Key Takeaways

  • Google crawls, then renders, then indexes; content that needs rendering may be processed later.
  • Google only reliably follows <a> elements with an href attribute.
  • Don’t change canonicals with JavaScript, and don’t rely on JavaScript to remove a noindex.
  • Single-page apps need a real 404 strategy to avoid soft 404s.
  • Server-side rendering or pre-rendering is still the safest option for search.

How Google processes JavaScript

  1. Crawling: Googlebot fetches the URL and reads the HTML response. It checks robots.txt first; blocked files aren’t fetched.
  2. Rendering: pages that return 200 are queued for rendering. Google’s documentation says a page may stay in the queue for a few seconds, but it can take longer. A headless Chromium runs the JavaScript.
  3. Indexing: Google uses the rendered HTML to index content and discover more links.

If a page returns an error status, or a noindex is present in the initial HTML, Google may skip rendering altogether. That’s why the initial response matters even on JavaScript sites.

Google can only reliably discover links that are <a> elements with an href. Navigation built from buttons, divs with click handlers, or href="javascript:..." may not be followed.

PatternCrawlable?
<a href="/products/shoes">Shoes</a>Yes
<a href="/products/shoes" onclick="…">Yes (href present)
<span onclick="goTo(‘/products’)">Not reliably
<a onclick="goTo(‘/products’)"> (no href)Not reliably
<a href="javascript:goTo(‘products’)">Not recommended

For single-page apps, use the History API for routing so each view has a real URL, not a #fragment. Links inserted by JavaScript are fine as long as they use normal <a href> markup. See Google’s link best practices.

Problem 2: titles, meta and canonicals set by script

JavaScript can set the title and meta description, and Google can use them. Canonicals are riskier: Google advises putting the canonical in the HTML source and not using JavaScript to change it to something else. Make sure only one rel=canonical exists after rendering.

Problem 3: noindex and JavaScript

If the initial HTML contains noindex, Google may skip rendering, so a script that later removes the noindex may never run for Google. If you want a page indexed, don’t include noindex in the original page code. Adding noindex with JavaScript to error views is acceptable, but test it.

Problem 4: soft 404s in single-page apps

Client-side routing often returns 200 for every URL, including views that show “not found”. Google reports these as soft 404s. Google’s documentation suggests two fixes: redirect with JavaScript to a URL where the server returns 404, or add a noindex robots meta tag to error views with JavaScript. See how to find crawl errors.

Problem 5: stale or blocked resources

  • Blocked files: scripts and styles disallowed in robots.txt aren’t used when rendering. Check your robots.txt, especially old rules for /wp-includes/ or asset folders.
  • Aggressive caching: Google may ignore caching headers and use an older copy of a script. Use content fingerprinting (a hash in the file name, like main.2bb85551.js) so a new version means a new URL.
  • Lazy-loaded content: content loaded only on scroll or click may not be seen. Lazy-load images properly and keep main text in the page.

Problem 6: structured data and web components

JSON-LD injected by JavaScript is supported, but test it with the Rich Results Test or URL Inspection. Google flattens shadow DOM and light DOM content when rendering, so content in web components is indexable only if it appears in the rendered HTML.

Rendering strategies compared

ApproachWhat Google receivesSEO notes
Server-side rendering (SSR)Full HTML on first responseMost reliable; content and links visible without rendering
Static generation / pre-renderingPre-built HTML filesVery reliable for content that doesn’t change per request
Client-side rendering (CSR)Mostly empty HTML plus scriptsWorks for Google when done carefully; other crawlers may see little
Hybrid (SSR + hydration)HTML first, then interactiveCommon in modern frameworks; check hydration doesn’t change key content

Google still recommends server-side rendering or pre-rendering because not all bots run JavaScript. That includes many social media crawlers and, in our experience, a number of AI crawlers.

How to test what Google sees

  1. Open the page in Search Console’s URL Inspection and click Test live URL.
  2. Open View tested page: check the rendered HTML for your main text, headings, internal links, canonical and structured data.
  3. Check the screenshot for missing sections and the JavaScript console for errors.
  4. Compare with the raw HTML (view-source) to see what depends on rendering.
  5. Repeat for each template: home, category, product or article, and an error page.

If the screenshot is missing content, check robots.txt for blocked resources first, then console errors, then content that loads only after user interaction.

JavaScript issues often surface as indexing problems; see how to fix indexing problems. For platform-specific work, see our technical SEO service.

Frequently asked questions

Can Google index JavaScript content?

Yes. Google renders pages with a headless Chromium and indexes the rendered HTML. Rendering can be delayed, and content that depends on user interaction may not be seen.

Is client-side rendering bad for SEO?

Not automatically, but it adds risk. Google recommends server-side rendering or pre-rendering because not every crawler runs JavaScript.

Is dynamic rendering still recommended?

Google describes dynamic rendering as a workaround rather than a long-term solution. Server-side rendering, static rendering or hydration are the preferred approaches.

Why does Google show a blank page in the URL Inspection screenshot?

Usually blocked scripts or styles, JavaScript errors, or content that loads only after a click or scroll. Check robots.txt and the console messages in the live test.

Do I need to change anything for a WordPress site?

Most WordPress themes output HTML on the server, so rendering issues are rare. Problems usually come from page builders, sliders or plugins that load content with scripts, and from blocked asset folders.

Want a second pair of eyes on your technical SEO?

We review crawling, indexing, rendering and speed issues by hand and give you a prioritized list of fixes, starting with a free manual audit.

Sources

Last reviewed October 12, 2026.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *