What Is Dynamic Rendering?
Dynamic rendering is a serving setup that inspects the requesting user agent and returns pre-rendered static HTML to crawlers while sending the JavaScript app to everyone else.
Dynamic rendering is a serving setup that inspects the requesting user agent and returns pre-rendered static HTML to crawlers while sending the JavaScript application to everyone else. It is not a fix for your visitors, who still receive the same client-side experience they always did. Only the crawler’s copy changes, and only because the crawler was assumed unable to cope with the original.
Why dynamic rendering still comes up
It comes up because it once solved a real problem, and because a generation of tutorials, agency decks and prerender vendors were built on that solution. Sites still run it. Migration proposals still propose it. Developers inherit it without documentation and cannot tell whether it is load-bearing.
The cost of keeping it is quiet rather than dramatic. You now maintain two versions of every page and only one of them gets tested by humans. When the crawler copy drifts, nothing on your monitoring dashboard reports it, because the visitor path is fine. Rankings soften on the templates that drifted first. Before you touch the rendering setup, look at which templates actually bring in visits, because that tells you which snapshots are worth checking and which parts of the site nobody would miss.
How the setup works
The whole mechanism is a fork in the request path. Everything downstream of that fork exists to keep two outputs looking like one.
- The request is classified. Middleware, a CDN worker or a reverse proxy reads the user-agent string and decides whether the caller looks like a crawler.
- Traffic splits. Browsers continue to the normal application. Anything classified as a bot is diverted to a rendering service.
- A headless browser runs the page. The service loads the URL, executes the JavaScript, waits for the network to settle, and captures the resulting DOM.
- The snapshot is cached. Rendering on demand is slow and expensive, so output is stored and reused for a set period.
- Static HTML is returned. The crawler receives a complete document it never had to render itself.
- The two paths drift. A deploy changes the application, the cache still holds yesterday’s markup, and the version Google reads stops matching the version people see.
Step six is where the failures live. Google’s guidance has long been that serving crawlers an equivalent pre-rendered copy is not cloaking, but that protection depends on equivalence, and a stale cache quietly removes it. All of this sits on top of the ordinary process, so it helps to understand how Google processes JavaScript pages before deciding whether an extra serving path earns its keep.
| Approach | What the crawler receives | What it costs you |
|---|---|---|
| Client-side rendering alone | An HTML shell, with content added after rendering | Delay, and total loss if the render fails |
| Dynamic rendering | A cached snapshot, while browsers get the app | Two output paths to keep in sync |
| Server-side rendering | The full document, identical to the visitor copy | Server load and framework work |
| Static rendering at build time | The full document, generated ahead of the request | A rebuild whenever content changes |
| Hydration | Server HTML, with interactivity attached in the browser | Framework complexity |
The blunt version
Google’s own documentation now describes dynamic rendering in the past tense: a workaround, not a long-term solution, and not a recommended one, because it adds complexity and resource requirements. The same page directs you to server-side rendering, static rendering or hydration instead. What that documentation does not carry is a deprecation date, so if a proposal cites one, ask to see the source. We checked the live page rather than repeating the version circulating in blog posts.
The decision rule is short. Building something new: do not choose this. Pick server-side rendering when content changes constantly, static rendering when it changes on a schedule, hydration when the page needs both a fast document and rich interactivity. Already running dynamic rendering on a site that indexes cleanly: it is technical debt, not an emergency, and it belongs in the next framework migration rather than in an urgent ticket.
Follow the money on why it lingers. Prerender services bill per URL rendered and per refresh, so a large catalogue is a recurring subscription. Selling a bolt-on service is easier than telling a client their framework choice was wrong and the honest fix is a rebuild the vendor cannot invoice for. That asymmetry, not the evidence, is what keeps the recommendation alive. It is a good example of the difference between fundamentals and noise, since a page Google can read without special treatment was always the actual goal.
Example
Say a furniture retailer runs a single-page application with dynamic rendering in front of it, and the snapshot cache holds each product page for a week. The team runs a sale and drops prices on a Monday. Visitors see the new prices immediately. Googlebot keeps receiving last week’s snapshot, complete with the old prices in the structured data, until the cache expires. Search results advertise a price the site no longer charges, and the markup no longer matches the visible page. Nobody notices, because every browser test passes and the application itself is faultless. The bug is not in the code. It is in maintaining a second version of the truth on a timer.
FAQ
Is dynamic rendering cloaking?
Not by itself. Google’s guidance is that serving crawlers a pre-rendered copy of the same content is acceptable, because the format differs rather than the substance. The risk arrives with drift: once the cached snapshot stops matching the page a visitor sees, you are serving different content to crawlers, and that is the line.
Should I set up dynamic rendering today?
No. Google’s documentation describes it as a workaround rather than a recommended solution, and points to server-side rendering, static rendering or hydration in its place. Adding it to a new build means committing to two serving paths, a cache to police, and a class of bug that only ever appears in search results.
We already run it. Do we have to rip it out?
Not urgently. If your pages index correctly and the snapshots match what visitors see, the setup is working, and an unplanned removal carries its own risk. Treat it as debt to clear during the next framework upgrade, and in the meantime check cached snapshots against live pages after every significant deploy.
Related terms
- Subdomain vs Subdirectory — the other architecture argument that gets settled by engineering convenience rather than evidence.
- Pagination — a second place where crawlers and visitors are often handed different journeys through the same content.
- JavaScript rendering — the underlying process that dynamic rendering was built to sidestep.
Google’s documentation puts dynamic rendering in the past tense and names its replacements; nobody needs a deprecation date to act on that. If your architecture requires a separate copy of the site for robots, the architecture is the thing to fix.