What is dynamic rendering, and should you still use it?
Dynamic rendering sits in an awkward place: officially discouraged, widely misunderstood as against the rules, and yet still the pragmatic answer for a specific real situation. Getting the nuance right matters, because both the "it's fine, use it everywhere" and the "it's forbidden, never touch it" positions are wrong.
What it actually is
Dynamic rendering means returning two different responses from the same URL, chosen by looking at who is asking. A normal browser gets the full client-side JavaScript application. A recognised crawler gets a pre-rendered, static HTML snapshot of the same page, generated by a headless browser on the server side.
The routing decision is made on the request's user-agent header: if it matches a known crawler, serve the snapshot; otherwise serve the app. The snapshot is usually produced by a service or a self-hosted renderer that runs headless Chromium, caches the output, and hands it back to bots. The appeal is that it requires little or no change to the application itself — you bolt it on in front.
Why it isn't cloaking
A common and understandable worry: serving different content to crawlers than to users is the textbook definition of cloaking, which is a genuine violation. So why is this allowed?
The distinction is content equivalence. Cloaking means showing crawlers materially different content to manipulate rankings — keyword-stuffed text a user never sees, a different topic entirely. Dynamic rendering serves the same content in a different form: the crawler gets a pre-rendered version of exactly what the user gets, just as static HTML instead of a JavaScript app. Google explicitly permits this, provided the two representations match. The moment the snapshot diverges from the live app, it stops being dynamic rendering and starts being a problem.
Why Google stepped back from recommending it
Google's own documentation reclassified dynamic rendering as a workaround rather than a long-term recommendation, pointing people instead toward server-side rendering, static rendering, or hydration. The reasoning is practical, not punitive.
When it's still reasonable
"Deprecated as a default" is not the same as "never appropriate". There is a narrow, legitimate case where dynamic rendering is the right call — usually a bridge while something better is built.
The honest framing is Google's own: a bridge, not a destination. If you adopt it, adopt it with an end date and a migration plan, and verify the snapshot against the live site regularly so drift doesn't creep in.
The AI-crawler trap that makes it leakier now
This is the part that has changed the calculation, and most explanations of dynamic rendering haven't caught up to it.
Dynamic rendering only serves the snapshot to user agents it recognises as crawlers. That allowlist was built around search engine bots — Googlebot, Bingbot and the like. The crawlers behind AI assistants and answer engines — GPTBot, ClaudeBot, PerplexityBot, and a steadily growing list of others — are frequently not on the default list. When one of them arrives unrecognised, it gets served the client-side app, which it cannot render, which means it sees an empty shell.
So a dynamic-rendering setup that keeps you indexed in Google can still leave you invisible to AI crawlers, unless you actively maintain the allowlist — adding each new AI user agent as it appears and keeping up as they change. That is ongoing, error-prone maintenance, and it is a real point in favour of server-side rendering, which serves complete HTML to everyone regardless of who is asking and needs no allowlist at all.
Test whether yours is even working
Dynamic rendering fails silently. The snapshot can go stale, the allowlist can miss a crawler, or the renderer can error and start serving the raw app to bots — and nothing obvious breaks, so you find out through lost rankings weeks later. The way to check is to fetch your page as a crawler would and confirm the pre-rendered HTML actually comes back complete.
The checker below fetches the raw response and compares it to the fully rendered page. If your dynamic rendering is working, the raw response should already contain your content. If it comes back as an empty shell, your crawler snapshot is not being served the way you think it is.
Dynamic rendering FAQ
Google reclassified dynamic rendering as a workaround rather than a recommended long-term solution, and now points to server-side rendering, static rendering, or hydration instead. It is not banned or penalised, and it still works. It is simply no longer the recommended approach, particularly for new projects where server rendering is now easy to build in from the start.