# Google's crawler split: why SSR vs. CSR decides Merchant Center compliance

> The Shopping crawler does not render JavaScript; it validates price and availability. SSR vs. CSR is the real determinant of Merchant Center compliance.

Canonical: https://brandonlazovic.dev/articles/google-crawler-rendering-split/  
Author: Brandon Lazovic  
Published: 2026-06-26

## The short version

- Google runs two separate crawl pipelines for e-commerce pages that treat JavaScript differently, and this SSR versus CSR distinction, not Rich Results Test results, determines Merchant Center compliance.
- Google operates two pipelines: high-volume price and availability validation for Shopping and queued JavaScript rendering for Search, and each follows different rules.
- The Shopping crawler, Storebot-Google, reads only server-delivered HTML for structured data; Google's documentation confirms markup generated by JavaScript after page load is not read.
- The Rich Results Test renders JavaScript and validates schema syntax, so it can pass even when the Shopping crawler reads stale or missing values from the raw HTML.

Google runs two distinct crawl pipelines for e-commerce pages, and they do not share the same rules about JavaScript. A Google engineer confirmed at Search Central Live Zurich in December 2025 that the Shopping crawler ignores structured data generated through JavaScript after page load [2]; Merchant Center's official documentation has said the same in writing for over a year. [1] The gap between what the Rich Results Test tells you and what the Shopping crawler actually reads is where compliance failures quietly live.

> Two pipelines: high-volume price and availability validation (Shopping) versus queued JavaScript rendering (Googlebot for Search).

## What are the two pipelines, and why do they behave differently?

Googlebot for Search uses a Web Rendering Service backed by headless Chromium. [4] It crawls raw HTML first for links and then passes pages to a rendering queue that executes JavaScript. That queue is deferred: rendering can happen seconds or days after the initial crawl, depending on resource availability. The pipeline is designed for comprehensiveness over immediacy.

The Shopping crawler, operating under the Storebot-Google user agent, is built for different constraints entirely. It crawls product detail pages, cart pages, and checkout flows to verify data submitted through Merchant Center, collecting price, availability, shipping costs, payment methods, and return policies. [6] The Google engineer at Zurich described the difference plainly: "Shopping crawls a lot, fast. It is different from Google Search." Because Shopping needs the latest information for real-time pricing and inventory, it cannot cache content the way Search can. That caching constraint is the structural reason why JavaScript rendering is not viable in this pipeline.

## Does the Shopping crawler execute JavaScript at all?

Google's official Merchant Center structured data documentation states: "Structured data markup must be present in the HTML returned from the web server. [1] The structured data markup can't be generated with JavaScript after the page has loaded." The mismatched price error documentation is equally explicit: "If data on your website is passed dynamically with JavaScript after the page is loaded, this will trigger an error. [5]"

The event confirmation from Search Central Zurich adds the engineering rationale. The Shopping crawler crawls at high volume and speed, which means it cannot absorb the compute cost of a rendering queue on every request. My read is that Storebot-Google is effectively an HTML-only reader for structured data purposes, though I note this conclusion rests on a Google engineer's spoken statement and the documentation above, not a published technical specification from Google that directly addresses the crawler's rendering capability. The behavior is well-documented; the internal architecture is not.

## What does the Rich Results Test actually measure, and where does it mislead?

The Rich Results Test renders JavaScript and validates structured data syntax and type eligibility. [7] A Product schema with `price: 49.99` passes the test even if the live page displays `$59.99`. The tool confirms that your JSON-LD is structurally valid and that Googlebot can find it after rendering; it does not compare field values against visible page content, and it does not replicate the Shopping crawler's code path.

This creates a specific failure mode. A team ships a client-side React storefront where price and availability are injected by JavaScript after hydration. The Rich Results Test returns a clean pass. Merchant Center flags a price mismatch. The team looks at the test result and concludes the structured data is fine. It is fine, from Googlebot's perspective. The Shopping crawler never saw the JavaScript-rendered values; it read the server-delivered HTML, which either had no schema markup or had stale values from the build.

There is a second trap worth naming. In Next.js with Server Components, JSON-LD script tags appear in both the initial HTML and in the RSC hydration payload. [8] JavaScript-executing tools parse schema from both locations and can report duplicates. A clean Rich Results Test result in this configuration does not mean rich results will appear; the duplicate schema can suppress them in actual SERPs. The tool does not catch this. It also does not catch adaptive-serving mismatches where desktop templates include structured data but mobile templates omit it. Since Google uses mobile-first indexing, desktop-only validation produces false confidence.

## What is the correct SSR/CSR decision rule for Merchant Center compliance?

Server-side rendering is the only reliable path for structured data that feeds Merchant Center. Google's merchant listing documentation puts it as a recommendation rather than an absolute prohibition, noting that "dynamically-generated markup can make Shopping crawls less frequent and less reliable [3]," and recommending that Product structured data appear in the initial HTML "for best results." The practical effect for price and availability fields, which change frequently and trigger mismatch errors when stale, is that CSR is not a viable approach.

The decision tree is short. If a field's value can change between page requests, it must be in the server-rendered HTML. If structured data is assembled client-side after hydration, even partially, the Shopping crawler will read whatever was in the initial HTML response: either missing markup or a static shell. The same logic governs any Merchant Center capability that refreshes price and availability from structured data on the live page rather than from a feed edit: it depends on the Shopping crawler successfully reading that data, and CSR defeats it.

## What should a team audit when they suspect a CSR compliance problem?

The first check is direct: fetch the product page with `curl` or a request library that does not execute JavaScript, and inspect the HTML for the structured data fields that Merchant Center is reporting as mismatched. If the JSON-LD is absent or contains values that differ from the live rendered page, the rendering pipeline is the cause.

The second check is user-agent specific. Storebot-Google's documented user-agent string identifies as Chrome 79 [6], which is significantly older than Googlebot's evergreen Chromium version. Some sites conditionally serve different markup based on user-agent parsing; the relevant question is what Storebot-Google receives, not what a modern browser receives. The Rich Results Test does not impersonate Storebot-Google.

The audit should also cover cart and checkout pages, not just product detail pages. Storebot-Google crawls those flows to verify shipping costs, payment methods, and return policies submitted through Merchant Center. If those pages depend on JavaScript to render policy structured data, the same compliance risk applies, and the Rich Results Test gives no signal about it at all.

## Sources

1. Google Merchant Center: Structured data markup requirements — https://support.google.com/merchants/answer/7331077?hl=en
2. Aleyda Solis: Search Central Live Zurich 2025 recap — https://www.aleydasolis.com/en/search-engine-optimization/what-we-learned-google-search-central-zurich-2025/
3. Google: Merchant Listing structured data documentation — https://developers.google.com/search/docs/appearance/structured-data/merchant-listing
4. Google: JavaScript SEO basics (Web Rendering Service) — https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics
5. Google Merchant Center: Mismatched price error documentation — https://support.google.com/merchants/answer/12159029?hl=en
6. Google: StoreBot-Google crawler documentation — https://support.google.com/merchants/answer/13294660?hl=en
7. Rich Results Test guide (squin.org) — https://squin.org/seo-tools/rich-results-test-guide/
8. Next.js JSON-LD duplicate schema discussion (Vercel GitHub) — https://github.com/vercel/next.js/discussions/66896
