How Googlebot Renders

How Googlebot Renders JavaScript

Googlebot queues every URL that returns 200 for rendering unless a robots meta tag or header forbids indexing. When resources allow, the Web Rendering Service (WRS) runs the page in headless Chromium 4,389 and parses the rendered HTML. In March 2026 Google dropped its old warning: it has rendered JavaScript "for multiple years now". What breaks sites are the differences from a user's browser:

Where Googlebot's renderer differs from a user's browser
Browser feature In Google's WRS
Scrolling and clicking Never happens; lazy-load on viewport entry
Cookies and Web Storage Cleared across page loads
Cache-Control headers May be ignored; fingerprint file names
Permission prompts, WebSockets Declined; HTTP requests only
Shadow DOM Flattened with light DOM; use <slot>
href="#/products" routes Not reliably resolved; use History API

In single-page apps the server answers 200 for every route, so a "not found" view becomes an indexable soft 404. Redirect to a URL that really returns 404, or inject noindex. The reverse fails: if the initial HTML contains noindex, rendering may be skipped, so a script that removes it never runs.

Marking a missing product as noindex in a client-side routerJavaScript
const res = await fetch(`/api/products/${id}`);
if (res.status === 404) {
  document.head.insertAdjacentHTML('beforeend', '<meta name="robots" content="noindex">');
  renderNotFound();
} else {
  renderProduct(await res.json());
}