Royking Niba

Server-Side Rendering for SEO: Google Calls Dynamic Rendering a Workaround, and the Parity Arithmetic Says Why

· Royking Niba

A developer typing at a keyboard with lines of code visible on the screen behind their hands.

The rendering argument has been settled in Google’s documentation for a while and most SEO advice has not caught up. Google no longer recommends dynamic rendering, the user-agent-sniffing approach that serves crawlers a pre-rendered copy. Its own page on the subject calls it a workaround and names server-side rendering, static rendering and hydration as what to use instead. Below are those sentences verbatim, a matrix of the five strategies against what Googlebot actually has to do to see your content, and the parity arithmetic that explains why the recommendation changed.

What Google now says about dynamic rendering

Quoted from Google Search Central’s page on dynamic rendering, last updated 10 December 2025, checked today.

Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines.

On what dynamic rendering was for

Instead, we recommend that you use server-side rendering, static rendering, or hydration as a solution.

On what to do instead

Dynamic rendering is a workaround and not a recommended solution, because it creates additional complexities and resource requirements.

On why

Three sentences, and the word “workaround” appears in two of them. Note what the stated reason is not. Google does not say dynamic rendering is penalised, or that it counts as cloaking, or that it stops working. It says the approach creates additional complexities and resource requirements. That is an engineering objection, and it is a correct one, which is why the rest of this page is arithmetic rather than policy.

The five strategies, defined by the people who named them

These definitions are quoted from the rendering-on-the-web article on web.dev by Addy Osmani and Jason Miller, published 6 February 2019 and last updated 5 January 2026.

Rendering an app on the server to send HTML, rather than JavaScript, to the client.

Server-side rendering

Rendering an app in a browser, using JavaScript to modify the DOM.

Client-side rendering

Running client-side scripts to add application state and interactivity to server-rendered HTML.

Hydration

Lets you send HTML in chunks that the browser can progressively render as it’s received.

Streaming server-side rendering

The article is also candid about what each one costs, which is the part that rarely makes it into an SEO recommendation. On server-side rendering: “generating pages on the server takes time, which can increase your page’s TTFB.” On static rendering, it achieves “a fast FCP, and also a lower TBT and INP” plus “a consistently fast TTFB, because the HTML for a page doesn’t have to be dynamically generated.” On client-side rendering: “the amount of JavaScript required tends to grow as an application grows, which can impact a page’s INP.” And the warning that matters most, on rehydration, that it has a “significant negative impact on TBT and INP, even if it improves FCP.”

On indexability the article’s position is one sentence: “Server-side rendering is a popular choice for delivering a ‘complete looking’ experience that crawlers can interpret.” That is the whole SEO case, and it is a modest claim rather than a promise.

The matrix: what Googlebot has to do before it sees your content

The first two columns follow from the definitions above. The rest is the practical consequence for a crawler, and the last column is the one the documentation’s “additional complexities” sentence is pointing at.

StrategyPrimary content in the first responseLinks crawlable without renderingNeeds the render passGoogle’s current position
Static renderingYes, built ahead of timeYesNoRecommended by name
Server-side renderingYes, built per requestYesNoRecommended by name
SSR plus hydrationYes for content, scripts add interactivity afterYesNo, for contentRecommended by name
Dynamic renderingOnly for a user agent the server recognisesOnly for a recognised user agentYes, for anything unrecognisedCalled a workaround
Client-side renderingNoNoYes, for everythingNot recommended for this problem
Five strategiesThree deliver content on the first fetchThree need no rendering to find linksTwo depend on the render queueThree recommended, one deprecated in effect

The dynamic rendering row is the only one in the table whose answer to any question is “it depends what the request looked like”. Every other strategy gives the same answer to every client. That conditional is the complexity Google is describing, and it is measurable.

The parity arithmetic: dynamic rendering doubles the thing you have to get right

This is the original dataset on this page. Take a 10,000 URL site and count the rendered outputs that have to exist and stay consistent with each other under each strategy.

StrategyOutputs per URLOutputs sitewidePairwise parity comparisons needed
Static rendering1 build output10,0000
Server-side rendering1 server output10,0000
SSR plus hydration1 server output plus a client state payload10,0000
Dynamic rendering1 client-rendered output and 1 pre-rendered output20,00010,000
Client-side rendering1 client output10,0000
Dynamic rendering against any other2 against 1Twice the outputs10,000 comparisons that otherwise do not exist

Four of the five strategies produce one version of a page, so the question “does the crawler see what the user sees” cannot be asked, let alone answered wrongly. Dynamic rendering produces two, which creates 10,000 pairwise comparisons that have to stay equal through every release. There is no report that tells you when one of them drifts.

And the detection problem, which has got worse since 2019

Dynamic rendering decides which of the two outputs to serve by matching the request’s user agent. Every request that fails to match falls through to the client-rendered version, and a crawler that lands on the client-rendered version sees whatever the first response contains, which under this architecture is close to nothing until the render pass.

Share of crawler requests the pattern list fails to matchURLs of 10,000 served the client-rendered version to a crawler
0%, a perfectly maintained list0
2%200
5%500
10%1,000

The reason that failure rate is not zero in practice is that the list of crawlers a publisher now wants to serve has grown. Googlebot, Googlebot-News and Googlebot-Image, Bingbot, Applebot, and then the newer group: GPTBot, OAI-SearchBot, ChatGPT-User, PerplexityBot, ClaudeBot. Ten families, each with its own string and each free to revise that string. A list that handled one crawler in 2019 now has roughly ten entries to keep current, and over three years of revisions that is on the order of thirty patterns maintained by hand, each of which is one typo away from sending a search engine the empty version of your site.

What this model assumes

The output counts are exact arithmetic on a stated site size and do not depend on any estimate. The detection-failure table is a sensitivity range, not a measurement: I do not know what share of crawler requests any given pattern list misses, and nor does anyone without the server logs. The ten crawler families and the thirty-patterns-over-three-years figure are a count of what a publisher may reasonably want to serve, not a requirement. The conclusion stands on the exact part: one architecture asks you to keep two outputs identical across 10,000 URLs with no report to tell you when they diverge, and four do not.

How I advise on this

  • If the content is the same for everyone and changes rarely, use static rendering. It is the only strategy that wins on TTFB, FCP and indexability at the same time, and web.dev says so in the quotes above.
  • If the content is personalised or changes per request, use server-side rendering and accept the TTFB cost, which web.dev names explicitly rather than hides.
  • If the page needs real interactivity, server-render the content and hydrate, but treat the hydration payload as a performance liability. The documented warning is a “significant negative impact on TBT and INP, even if it improves FCP”. A page that looks ready and is not is a worse experience than one that looks slow.
  • Do not build new dynamic rendering. Google’s own page calls it a workaround twice and names three alternatives. If you have inherited one, the migration target is whichever of the three fits the content, and the interim job is a parity check between the two outputs.
  • Do not treat rendering strategy as an SEO deliverable on a site that already server-renders. It is not a lever you can pull twice, and on most sites the crawlable-links problem is a bigger win than the rendering one.

The thing to hold onto is that Google’s objection to dynamic rendering is about maintenance, not about rules. It stopped recommending the approach because keeping two versions of a site identical forever is a job nobody resources after the launch, and the arithmetic above is what that job looks like on an ordinary ten thousand page site.

Related reading

Need help with your own site?

Tell me where it stands. I reply within a day, and the first look is free.

Send me a message

Goes straight to my inbox. I reply within a day.

Leave a Reply

Your email address will not be published. Required fields are marked *