/ โ† JavaScript Checker Fixes / Crawler Rendering
In this guide
  1. How search engines handle a JavaScript page
  2. Symptoms that point to a rendering problem
  3. Comparing raw and rendered HTML
  4. Using URL Inspection properly
  5. The fix, step by step
  6. Patterns that break rendering, and their replacements
  7. Framework and platform notes
  8. Stopping it from coming back
  9. Questions and answers

How search engines handle a JavaScript page

Google describes its process in three phases: crawling, rendering and indexing. Googlebot first fetches the URL and reads the HTML the server returns. Links and signals found in that raw HTML are available straight away. The page is then queued for rendering, where Google's Web Rendering Service loads it in an up-to-date version of Chromium, runs the scripts and takes the resulting DOM. Indexing works from that rendered result.

Several things can go wrong between those phases:

๐Ÿ’ก This guide is about search engine crawlers indexing your pages. If the concern is AI tools reading specific facts such as prices and dates, the JavaScript-only content guide covers that angle.

Symptoms that point to a rendering problem

What you noticeLikely rendering cause
Search results show a generic title such as the app name on every pageThe <title> is set by script and the raw HTML has one shared placeholder.
Deep pages are "Discovered, currently not indexed" in Search ConsoleLinks to them only exist after rendering, or are buttons with click handlers rather than links.
Missing pages are reported as indexed, or "Soft 404" appearsThe app shows a not-found screen but the server returns 200 for every URL.
URL Inspection screenshot shows a spinner or blank areaA data request failed, timed out or was blocked during rendering.
Wrong canonical or noindex reportedScript changes the canonical or robots meta tag after load, so raw and rendered values disagree.
Only the first page of a listing is indexedFurther items load by infinite scroll or a "load more" button with no paginated URLs.

Comparing raw and rendered HTML

The core diagnostic is simple: fetch the page without running scripts, fetch it again after rendering, and look at the differences. The JavaScript Checker loads the page in headless Chromium and compares the rendered page with what a crawler receives, which gives you that difference for a template in one pass. You can reproduce it by hand as well.

The raw HTML

curl -sL -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
  https://www.example.co.uk/shoes/trail-runner-2 -o raw.html
grep -o "<title>[^<]*" raw.html
grep -c "<a " raw.html

Using a crawler user agent also shows whether your server treats bots differently. View Source in the browser gives the same raw HTML for a quick look.

The rendered HTML

In DevTools, the Elements panel shows the live DOM after scripts have run. To save it, right-click the <html> element and copy the outer HTML. In Search Console, URL Inspection gives Google's own rendered version, described below.

What to compare

Using URL Inspection properly

In Search Console, open URL Inspection, enter the address and choose Test live URL. When the test finishes, View tested page gives three tabs: the rendered HTML, a screenshot, and More info, which lists page resources that could not be loaded and JavaScript console messages.

The Rich Results Test uses the same rendering and does not need Search Console access, which makes it useful for pages on sites you do not have verified.

The fix, step by step

Step 1

Compare raw and rendered HTML for key templates

Run the JavaScript Checker on one URL of each main template and note what exists only after rendering. Confirm by fetching the raw HTML with curl and comparing it with the DOM in the Elements panel. Check the title, meta description, canonical, robots meta, main heading, body text, internal links and structured data. Make a list per template of every item missing from the raw HTML, because each one is a separate fix below.

Step 2

Check the rendered page in URL Inspection

For each template, run Test live URL in Search Console URL Inspection and open the tested page. Search the rendered HTML for a sentence of main content and for your pagination and category links. Open More info and write down any resources that failed to load and any console errors. Repeat the test once, because a single failed request can be temporary, but treat anything that fails every time as a real blocker.

Step 3

Unblock the files rendering depends on

Open robots.txt and remove any rule that blocks script bundles, stylesheets or the API paths your pages call to fetch content, such as a blanket Disallow: /api/. Check that the firewall or bot protection does not challenge Googlebot on those paths, and that the API responds quickly without cookies. Fix any console error seen in the rendered test, since an uncaught error during rendering can leave the page unfinished at that point.

Step 4

Turn script navigation into real links

Replace clickable elements that change the page with script, such as a div or button that calls the router, with <a href> elements pointing to real URLs; your router can still intercept the click for visitors. Stop using hash fragments such as #/products for distinct pages and use the History API with normal paths. Give infinite scroll and load-more lists paginated URLs that each work when loaded directly.

Step 5

Send correct status codes and head tags from the server

Make the server return 404 or 410 for URLs that do not exist, and 301 for moved pages, instead of returning 200 and letting the app draw an error screen. Output the unique title, meta description, canonical and any robots meta tag in the raw HTML for every route. Do not rely on script to change a noindex to index later, because Google may act on the first value it sees.

Step 6

Render essential content on the server

For each template, move the main heading, body text, product details, internal links and structured data into HTML the server sends, using static generation for pages that change rarely and server-side rendering for the rest. Most frameworks can do this per route. Keep client-side JavaScript for filters, baskets and other interaction. If a full change is not possible yet, prerender the most important routes at build time as an interim step.

Step 7

Watch coverage and logs after release

Re-run the checker and a URL Inspection live test on each template to confirm the raw and rendered HTML now match on the essentials. Request indexing for a few important pages. Over the following weeks, watch the Search Console page indexing report for fewer soft 404 and "Discovered, currently not indexed" entries, and check server logs to confirm Googlebot is fetching your deep pages and their resources successfully.

Patterns that break rendering, and their replacements

PatternWhy a crawler misses itReplacement
Content loaded after a scroll eventThe renderer does not scroll like a visitor, so the event may never fire.Use IntersectionObserver for below-the-fold extras, and put the main content in the HTML.
Tabs or accordions that fetch their content on clickNo click happens during rendering.Include the content in the HTML and show or hide it with CSS.
Content that depends on stored data or cookiesStorage and cookies are cleared between page loads during rendering.Render a sensible default for a first-time visitor.
Content behind a geolocation or notification promptPermission requests are declined.Show default content and let the visitor choose a location.
Links built only in click handlersCrawlers follow href values, not script.Real anchors with real URLs.
Hash-based routesEverything after # is ignored when identifying a page.Path-based routes via the History API.
Timers that wait several seconds before showing contentRendering does not wait indefinitely for page activity.Render immediately; animate afterwards if needed.

Framework and platform notes

โš ๏ธ Never show crawlers content that visitors cannot see. Serving materially different pages to bots and people can be treated as cloaking. Server rendering avoids the risk because everyone gets the same HTML.

Stopping it from coming back

Questions and answers

1. Does Google render JavaScript?

Yes. Google renders pages with an up-to-date version of Chromium and indexes the rendered result. However, rendering happens after the initial crawl, it depends on your scripts and data requests working without errors, and it will not click, type or grant permissions. So Google can see most script-built content, but anything that relies on interaction, cookies or blocked files can be missed. Content in the raw HTML avoids all of those risks and is seen straight away.

2. How do I see the HTML Google rendered for my page?

Use URL Inspection in Search Console. Enter the URL, choose Test live URL, then View tested page. The HTML tab shows Google's rendered DOM, the screenshot tab shows the top of the page, and More info lists resources that failed to load and JavaScript console messages. Search the rendered HTML for a sentence of your main content and for important links. The Rich Results Test uses the same rendering if you do not have Search Console access.

3. Why are my single-page app routes reported as soft 404?

Usually because the server returns a 200 status for every URL, and the app then draws a not-found message in the browser. Google sees a 200 page that looks like an error and flags it as a soft 404, or the reverse happens and thin error pages get indexed. Fix it on the server: return a real 404 for unknown routes, or at minimum add a noindex robots meta tag to the error view in the raw HTML.

4. Can Googlebot follow links created with JavaScript?

Googlebot follows links that are anchor elements with an href containing a real URL, whether the anchor is in the raw HTML or added by script before rendering finishes. It does not follow buttons, spans or divs that navigate through click handlers, and it does not treat hash fragments as separate pages. Links in the raw HTML are also found earlier, during the first crawl, so they are the most dependable way to get deep pages discovered.

5. Should I block my API endpoints in robots.txt?

Not if your pages call them to fetch content while rendering. When robots.txt blocks those requests, Google's renderer cannot load the data, and the page is indexed without it. If you want to keep API URLs out of search results, leave them crawlable and send an X-Robots-Tag noindex header on the API responses instead. Only block endpoints that no public page depends on, such as internal admin or account-only paths.

6. Is prerendering the same as server-side rendering?

Not quite. Prerendering usually means generating static HTML for routes ahead of time, either at build time or with a headless browser, and serving those files. Server-side rendering builds the HTML on each request. Both give crawlers complete HTML. Prerendering suits pages that change occasionally; server rendering suits pages with frequently changing data such as stock levels. Either is better than dynamic rendering, which serves bots a different version from people.

7. Do other search engines and AI crawlers render JavaScript?

Bing says it renders JavaScript, although it recommends not depending on it for important content. Many other crawlers, including a number of AI crawlers and the fetchers behind social and chat link previews, are widely reported to read only the raw HTML. Behaviour varies and changes over time, so the safe approach is to make sure titles, main content, links and structured data are in the HTML the server sends, and to use JavaScript for enhancements.

Compare what crawlers receive

The JavaScript Checker loads your page in headless Chromium, compares the rendered page with what a crawler receives, captures console errors that can stop rendering, and lists every script with its size and execution time.

Open JavaScript Checker Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All JavaScript Checker Fixes  ·  JavaScript-Only Content  ·  Fixing Console Errors at Page Load  ·  JS Checker Guide  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.