Dynamic Rendering
Dynamic rendering is a setup where your server detects whether a visitor is a search crawler or a human and serves a pre-rendered static version to the crawler while sending the normal JavaScript app to the human. It was a workaround for crawlers that struggled with JavaScript-heavy pages.
JavaScript-heavy sites created a hard problem for search. A modern app might ship a nearly empty HTML shell and then build the whole page in the browser with JavaScript. A human waits a beat and sees a full page. A crawler that does not run that JavaScript, or runs it slowly and unreliably, sees the empty shell and indexes nothing. Dynamic rendering was the bridge built to solve exactly that gap.
The idea is straightforward. Your server looks at who is asking. If it recognizes a search crawler by its user agent, it hands over a fully rendered static HTML version of the page, already built on the server so nothing depends on JavaScript. If it is a regular browser, it sends the normal client-side app the way it always did. Two audiences, two delivery methods, same content.
How the flow works
- A request comes in and the server inspects the user agent.
- If it matches a known crawler, the request is routed to a renderer that produces static HTML.
- That pre-rendered HTML is served to the crawler so it can read the full content immediately.
- If the request is a normal user, the server sends the standard JavaScript application.
- Both end up with the same content, just delivered differently.
Dynamic rendering is a workaround, not a destination. Google has been clear that it sees it as a temporary fix and recommends server-side rendering or static generation instead.
Why it has fallen out of favor
Two things changed. First, Google got much better at rendering JavaScript itself, so the original reason for the workaround weakened. Second, maintaining a separate rendering path purely for bots is genuinely painful. You are running and monitoring extra infrastructure, your crawler and your users can drift out of sync, and you have to keep your list of crawler user agents current. It also sits uncomfortably close to cloaking, the banned practice of showing crawlers different content than users. Dynamic rendering is allowed because the content is meant to be identical, but the moment it diverges, you have a problem.
warningWATCH OUT
If the version you serve crawlers differs in content from what users see, that is cloaking, and it can earn a penalty. The two versions must carry the same content for dynamic rendering to stay on the right side of the line.
What to do instead
For new builds, skip dynamic rendering and reach for a rendering strategy that serves everyone the same complete page. Server-side rendering builds the page on the server for every request, so crawlers and users both receive full HTML with no special casing. Static site generation pre-builds pages at deploy time, which is even faster and simpler where the content allows it. Both remove the need to detect bots at all, which removes the whole class of problems dynamic rendering introduced.
targetIf you already run dynamic rendering
You do not need to rip it out overnight, but treat it as technical debt. Keep the crawler and user content perfectly aligned, monitor that the renderer stays healthy, and plan a migration toward server-side rendering or static generation. The goal is to stop maintaining two paths for one page.
Serve everyone the real page
Dynamic rendering splits delivery between crawlers and users as a workaround for JavaScript indexing problems. It is now considered legacy. Prefer server-side rendering or static generation so every visitor gets the same complete page.
For the full picture on making JavaScript sites crawlable and indexable, read my guide on JavaScript SEO.
Want this handled by someone who has measured search for 20 years?
Work with me