Google can render JavaScript. That's been true for years, and it means a JavaScript-built site can rank as well as any other. But rendering adds a step to how Google processes your pages, and that step is where content, links, and directives can quietly go missing. A page that looks perfect in your browser may look half-empty to Google if a script fails, a resource is blocked, or content only appears after a click. This guide explains how Google processes JavaScript, the mistakes that most often hurt rankings, and how to test what Google actually sees.
How Google Processes JavaScript Pages
Google's documentation describes three phases for JavaScript pages:
- Crawling: Googlebot fetches the URL and receives the initial HTML.
- Rendering: pages that return a 200 status are queued for rendering. When resources allow, a headless Chromium browser runs the page's JavaScript and produces the rendered HTML. Google notes that rendering can happen anywhere from seconds to longer after crawling.
- Indexing: Google uses the rendered HTML to index the page.
The crawling vs. indexing guide covers the crawl and index stages in general. JavaScript adds the rendering step in between, and anything that only exists after rendering depends on that step working.
Rendering Approaches and Their SEO Trade-Offs
- Server-side rendering (SSR): the server sends fully formed HTML, and JavaScript adds interactivity afterward. Content is present in the initial HTML, so it doesn't depend on rendering. This is the most reliable approach for SEO.
- Static site generation: pages are pre-built as HTML files. Very reliable and fast.
- Hydration: server-rendered HTML is sent first, then JavaScript takes over in the browser. This combines SSR's reliability with an app-like experience.
- Client-side rendering (CSR): the server sends a mostly empty HTML shell, and JavaScript builds the page in the browser. It works with Google, but everything depends on rendering succeeding.
Dynamic rendering, which serves pre-rendered HTML to bots and the JavaScript version to users, is something Google now describes as a workaround and not a long-term solution, recommending server-side rendering, static rendering, or hydration instead.
Common JavaScript SEO Mistakes
1. Links that aren't real links
Google discovers links from <a> elements with an href attribute. Navigation built with click handlers on buttons or divs, such as <div onclick="goTo('/products')">, may work for users but gives Google no link to follow. Use standard links with real URLs, even if JavaScript handles the navigation afterward. The internal linking guide explains why crawlable links matter.
2. Fragment-based URLs
Older single-page apps load different content at URLs like /#/products. Google's documentation says it can't reliably resolve these, and advises against using fragments to load different page content. Use the History API to give each view a real URL, such as /products.
3. Content that needs interaction to appear
Google renders the page but doesn't click buttons, open menus, or type. Content that only loads after a user action, such as a "load more" button or a tab that fetches its content on click, may never be seen. Primary content should be in the page once it renders, without interaction. This also matters for mobile-first indexing, since Google renders the mobile version.
4. A noindex in the initial HTML
Some sites ship noindex in the initial HTML and plan to remove it with JavaScript once the page loads. Google's documentation warns that when it sees a noindex, it may skip rendering and JavaScript execution entirely, so the JavaScript that removes it may never run. If a page should be indexed, don't include noindex in the original HTML. Check with the Indexability Checker.
5. Conflicting canonicals
Google prefers the canonical tag in the initial HTML. If JavaScript sets or changes it, the JavaScript value should match the original, and a page should have only one rel="canonical" tag. Verify with the Canonical Tag Checker and the canonical tags guide.
6. Missing titles and meta descriptions
JavaScript can set the title and meta description, and Google supports that. Problems arise when every view of a single-page app shares one default title, or when the title is set late or not at all. Each distinct page should have its own descriptive title. Check what's set with the Meta Tag Analyzer.
7. Soft 404s in single-page apps
Client-side routing often can't return a real 404 status for a page that doesn't exist, so the app shows a "not found" message with a 200 status: a soft 404. Google's documentation suggests either redirecting to a URL where the server returns a real 404, or adding a noindex robots meta tag to error views. The soft 404 guide covers the issue in depth.
8. Blocked resources
If robots.txt blocks the JavaScript files, CSS, or API endpoints a page needs, Google can't render it as users see it. Test your rules with the Robots.txt Tester.
9. Heavy scripts and slow rendering
Large JavaScript bundles slow down both users and rendering. They also affect Core Web Vitals, particularly Interaction to Next Paint. The page speed guide covers how to reduce main-thread work, and the Page Speed Optimizer shows where time goes.
How to Test What Google Sees
URL Inspection in Search Console. Run "Test Live URL" and view the tested page. It shows the rendered HTML, a screenshot, and any resources that couldn't be loaded. Search the rendered HTML for your main content, key links, title, and canonical. If something is missing, that's your problem.
Compare source and rendered HTML. In your browser, compare "view source," which shows the initial HTML, with the developer tools Elements panel, which shows the rendered page. Content that only appears in the rendered version depends on JavaScript. That's acceptable, but it's where to look first when something isn't indexed.
Search for a unique phrase. Once a page has been indexed, search Google for an exact sentence that appears only in JavaScript-loaded content, combined with site:yourdomain.com. If it doesn't appear, Google may not be indexing that content.
Watch the Page Indexing report. JavaScript problems often surface as rising "Crawled – currently not indexed" counts, because pages render thin. The guide to crawled and discovered but not indexed pages covers how to diagnose them.
A JavaScript SEO Checklist
- Use real
<a href>links for navigation. - Use real URLs with the History API, not fragments.
- Make primary content available without user interaction.
- Never ship noindex in the initial HTML of pages you want indexed.
- Keep one canonical tag, consistent between initial and rendered HTML.
- Give every page a unique title and description.
- Handle not-found views with a real 404 or a noindex.
- Don't block JavaScript, CSS, or required APIs in robots.txt.
- Prefer server-side rendering, static generation, or hydration for important content.
- Test key templates with URL Inspection after every major front-end change.
JavaScript isn't an SEO problem in itself. Unverified assumptions are. Test what Google sees, and keep the important things, such as content, links, titles, and directives, in the initial HTML wherever you can.