ssrchecker
HomeLearnDynamic rendering

What is dynamic rendering, and should you still use it?

Short answer
Dynamic rendering serves pre-rendered HTML to crawlers and the normal JavaScript app to users, based on the request's user agent. Google now calls it a workaround rather than a best practice and recommends server-side rendering instead. It is not cloaking, and it remains a legitimate bridge for legacy apps — but it is a leakier bridge in the AI era than it used to be.

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.

01
It's a second system to maintain
You now run and monitor a separate rendering layer alongside your app. That's operational surface area that can fail independently of the site.
02
The snapshot drifts
The pre-rendered cache can silently fall out of sync with the live site, so crawlers index a stale version. Drift is the single most common failure mode, and it fails quietly.
03
Frameworks made the better option easy
The original justification was that server rendering was hard. It no longer is — every major framework offers SSR or static generation out of the box, which removes most of the reason to reach for a workaround on a new build.

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.

SituationVerdict
BridgeA large legacy SPA that can't be migrated for months
Reasonable bridge. Buys indexing now while an SSR migration is planned properly.
BridgeConstrained engineering bandwidth, content changes rarely
Defensible. Low drift risk when content is stable, and cheap to stand up.
AvoidA brand-new project
Avoid. Build SSR or static from the start — there's no legacy to bridge.
AvoidFrequently-changing content (prices, inventory)
Risky. High drift risk; the snapshot goes stale fast and misindexes.

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.

Check whether your pre-rendered HTML is served
https://

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.