---
title: "Dynamic Rendering SEO: How It Works, Benefits and Setup"
url: https://encited.com/blog/dynamic-rendering-seo
description: "Learn what dynamic rendering is, how it fixes JavaScript indexing for search and AI crawlers, how to set it up, and whether it's the right rendering strategy for your site."
lang: en
---

Image: Dynamic Rendering for SEO: How It Works, Benefits and Setup (https://encited.com/blog/thumbnails/dynamic-rendering-seo.webp)

# Dynamic Rendering for SEO: How It Works, Benefits and Setup

Oct 8, 2026 October 8, 2026 · Updated Oct 9, 2026 October 9, 2026 · by Aki from Encited

Learn what dynamic rendering is, how it fixes JavaScript indexing for search and AI crawlers, how to set it up, and whether it's the right rendering strategy for your site.

Dynamic rendering still works for SEO in 2026. Google documents dynamic rendering, doesn't treat it as cloaking as long as crawlers get the same content as people, and has said switching to server-side rendering brings no ranking bonus. It also works alongside server-side rendering. SSR builds the first HTML response, and dynamic rendering captures the page after everything has loaded.

Plenty of server-rendered pages still load prices, reviews, stock, recommendations and whole sections in the browser after the first response. Crawlers that only read that first response never see them. The crawlers behind ChatGPT, Claude and Perplexity don't run JavaScript at all, and complex layouts are hard for them to parse even when the HTML is complete.

Encited (https://encited.com/dynamic-rendering) serves every crawler the fully loaded page, on client-side apps and server-rendered sites, with no changes to your code.

**TL;DR**

- Google still supports dynamic rendering and doesn't consider it cloaking when the content matches.
- It works alongside server-side rendering. SSR delivers the first HTML, and dynamic rendering captures content loaded after it: deferred sections, client-fetched data and widgets.
- Dynamic rendering speeds up indexing, puts your metadata in the first response, and fixes soft 404s on single-page apps.
- AI crawlers can't render JavaScript, so for them it decides whether your page has any content at all.
- It covers client-side apps entirely, and fills the gaps on server-rendered pages with heavy client-side data or complex layouts.

## What is dynamic rendering

Dynamic rendering serves two versions of each page from the same URL. People get your JavaScript app as usual. Crawlers get a static HTML snapshot of the same page, rendered ahead of time in a real browser after all scripts and data have loaded. It's also called dynamic bot rendering or bot routing. The snapshot carries the same text, links, titles and structured data people see. The full explanation is on what is dynamic rendering (https://encited.com/dynamic-rendering).

## How dynamic rendering works

It takes three steps:

1. **Detect the crawler.** A rule at your server or CDN reads the user agent of each request.
2. **Route it.** Requests from Googlebot, Bingbot, AI crawlers and link preview bots go to a renderer or a cache of rendered pages.
3. **Serve HTML.** The crawler gets the finished page: text, links, titles, canonical tags and structured data, all in the first response.

Nothing changes for your visitors. The setup sits in front of your site, so your app code stays as it is.

The user agent is how the rule tells people from crawlers. Every request names its client, such as Chrome, Googlebot or GPTBot. Anyone can fake a user agent, but a fake crawler only gets the public page, so most sites don't need more. If you want to verify, Google and Bing crawlers can be confirmed with a reverse DNS lookup on the request's IP.

## How Google indexes JavaScript without it

Googlebot fetches the raw HTML first. For a typical React, Vue or Angular single-page app, that HTML is a near-empty shell with script tags. Google then puts the page in a render queue. Later, sometimes much later on large sites, it runs the JavaScript in a headless browser and indexes what comes out.

This works for most pages. It also fails in a few common ways:

- **Delay.** New and updated pages wait in the render queue before their content is indexed. On sites with thousands of URLs, that wait adds up.
- **Timeouts.** Pages that load data slowly or depend on many API calls can be rendered before the content arrives.
- **Content behind interaction.** Anything that appears only after a click or scroll isn't rendered at all.
- **Errors.** A script error during rendering can leave Google with a blank or partial page.

With dynamic rendering, Googlebot gets the finished HTML on its first request and doesn't wait in the render queue.

## Dynamic rendering vs CSR vs SSR

| | Client-side rendering | Server-side rendering | Dynamic rendering |
| --- | --- | --- | --- |
| Who builds the HTML | The visitor's browser | Your server, on every request | A headless browser, ahead of time, for crawlers |
| What crawlers get first | An empty shell | The first response | The fully loaded page |
| Content loaded after the first response | Only after Google's render pass | Only after Google's render pass | Included |
| AI crawlers | Get nothing | Get the first response | Get the full page, as HTML or Markdown |
| Changes to your app | None | Move to a server framework | None |

Server-side rendering is Google's recommendation for building pages, and it helps real visitors' load speed. Dynamic rendering covers client-side apps that can't be rebuilt and content that loads after the first response. Many sites use both. Refer to dynamic rendering vs server-side rendering (https://encited.com/blog/dynamic-rendering-vs-server-side-rendering) for the full detailed comparison.

In Next.js, "dynamic rendering" also names something else: a route rendered on the server for each request instead of at build time. That's still server rendering, and content a Next.js page loads in the browser after hydration still needs dynamic rendering for SEO to reach crawlers.

## Dynamic rendering SEO benefits

**Faster indexing.** Content is in the HTML Googlebot fetches, so pages don't wait for a second rendering pass. This matters most for large sites and pages that change often, like product listings and news.

**Complete metadata on the first request.** Titles, meta descriptions, canonical tags, hreflang and structured data set by JavaScript are missing from a client-side app's raw HTML. In a rendered snapshot they're all present. Link previews on LinkedIn, Slack and X read the same raw HTML, so shares start showing the right title and image too.

**Real status codes.** A single-page app answers every URL with a 200, including URLs that show a "not found" screen. Google reads those as soft 404s. A renderer can return a real 404 for those routes, and redirect rules in front of the app can return a real 301 for URLs the app redirects in the browser.

**Links crawlers can follow.** Internal links added by JavaScript aren't in the raw HTML. In the snapshot they are, so crawlers find deeper pages without waiting for rendering.

**Less work per page for crawlers.** Rendering is expensive for search engines. Serving finished HTML means each crawl visit can cover more of your site.

Dynamic rendering doesn't raise rankings by itself. It makes sure your content reaches the crawler, and the content decides the ranking.

## Google's dynamic rendering guidance

Google introduced dynamic rendering in 2018 as a workaround for sites with JavaScript content its crawlers struggled with. Its documentation describes the use case as indexable, public JavaScript content that changes rapidly, or content that uses JavaScript features crawlers don't support.

**The current documentation.** Google's dynamic rendering page (https://developers.google.com/search/docs/crawling-indexing/javascript/dynamic-rendering) now opens by saying dynamic rendering "was a workaround and not a long-term solution." The past tense is about what Google recommends for new builds. The same page still explains how to set it up and when it isn't cloaking. It recommends server-side rendering, static rendering or hydration, and notes that dynamic rendering adds complexity and resource requirements. Search Engine Land covered the change (https://searchengineland.com/google-no-longer-recommends-using-dynamic-rendering-for-google-search-387054) when Google added a warning banner to the top of that page.

**No rush to switch.** After the change, Google's John Mueller answered a question on Reddit about moving from dynamic rendering to server-side rendering. As Search Engine Journal reported (https://www.searchenginejournal.com/google-no-rush-to-switch-away-from-dynamic-rendering/461763/), he said the differences come down to infrastructure setup and maintenance, that there's no SEO ranking bonus for switching, and that dynamic rendering isn't going to become unsupported. His advice was to consider other options at your next rebuild.

**Not cloaking.** Google states that it generally doesn't consider dynamic rendering cloaking, as long as the version crawlers get has similar content to what people see. Serving crawlers completely different content can be treated as cloaking.

Google's guidance is about how the first HTML response gets built, and for that it prefers server-side rendering. It doesn't cover content that loads after that response, or crawlers other than Googlebot. Dynamic rendering covers both, on client-side and server-rendered sites alike.

## Dynamic rendering on server-rendered pages

Server-side rendering gets the page shell, headings and initial content into the first response. On many sites, a lot of the page arrives later:

- **Data fetched in the browser.** Prices, stock levels, reviews, ratings and related products often load from an API after the page is up.
- **Deferred and lazy sections.** Content below the fold, tabs, accordions and "load more" lists render only when needed.
- **Third-party widgets.** Review platforms, store apps and embedded content inject their HTML with scripts.
- **Complex layouts.** Even complete HTML can bury the content in nested components, inline SVGs and repeated markup that AI crawlers struggle to parse.

A crawler that reads only the first response misses all of the first three. Googlebot catches some of it in its render pass, with a delay. AI crawlers catch none of it.

Dynamic rendering snapshots the page after all of that has loaded, so crawlers get the full page. For AI crawlers, Encited also strips the snapshot down to the content, as cleaned HTML or Markdown, so complex layouts don't get in the way. This is why an ecommerce site on a server-rendered platform still benefits: the product page is server-rendered, and the reviews and recommendations aren't.

## Dynamic rendering for AI crawlers

Being readable by crawlers is even more important now that search is shifting more and more to AI agents with no javascript execution capability whatsoever in their data fetchers.

In December 2024, Vercel and MERJ published crawl data (https://vercel.com/blog/the-rise-of-the-ai-crawler) from live traffic across Vercel's network. None of the major AI crawlers they measured ran JavaScript. GPTBot downloaded JavaScript files in about 11.5% of its requests and ClaudeBot in about 24%, and neither executed them. The exceptions were Gemini, which uses Googlebot's rendering, and Applebot.

So a client-side app can be fully indexed in Google and still be empty to ChatGPT, Claude and Perplexity.

Dynamic rendering closes that gap with the same routing rule. Add the AI user agents (GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, PerplexityBot, Perplexity-User) and they get the rendered page. On a typical modern page, more than 70% of the HTML is scripts, styles, inline SVGs and decorative markup rather than content. Encited also serves AI crawlers a lighter version of the snapshot, as cleaned HTML or Markdown, so they get the content without the scripts and markup.

## Mistakes that hurt SEO

- **Stale snapshots.** If prices, stock or copy change and the snapshot doesn't, crawlers see an older page than visitors do. Small gaps are harmless. Large ones drift toward the "different content" Google warns about. Snapshots need refresh rules that match how often each section of your site changes.
- **Cached error pages.** A renderer that runs during a deploy or an outage can save the error page and serve it to every crawler. Check each page before saving it.
- **An outdated crawler list.** The rule only covers user agents on its list. A list written for Googlebot and Bingbot misses every AI crawler.
- **CDN mixups.** If your cache doesn't keep the two versions apart, visitors can get the static snapshot or crawlers can get the empty app.
- **Soft 404s left in place.** Without a not-found signal from the app, the renderer still returns 200 for missing pages.

## When to use dynamic rendering

Use dynamic rendering when:

- **Your site is a client-side app.** React, Vue or Angular single-page apps, and sites built with AI website builders, send crawlers an empty shell without it.
- **Your server-rendered pages load key content in the browser.** Prices, reviews, stock, recommendations or deferred sections that crawlers should see.
- **Your layouts are complex.** Pages heavy with components, widgets and markup, where AI crawlers need a cleaner version to read the content.
- **Content changes often.** Large catalogs and listings where Google's render queue slows indexing.
- **You need AI crawlers and link previews covered.** They read only the first response.

You don't need it when the first HTML response already contains everything on the page and nothing loads afterwards. Compare view-source with what you see in the browser after the page settles. If they match, crawlers already get the full page.

## Set up the routing rule

A working setup comes down to five checks:

1. **List every crawler.** Search engines (Googlebot, Bingbot, Applebot), AI crawlers (GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, PerplexityBot, Perplexity-User) and link previews (facebookexternalhit, LinkedInBot, Twitterbot, Slackbot).
2. **Route only page requests.** `GET` requests for pages go to snapshots. Scripts, styles, images, API routes, `robots.txt` and sitemaps pass through.
3. **Keep the two versions apart in your cache.** Send `Vary: User-Agent`, or put a crawler flag in the CDN cache key, so people never get a snapshot.
4. **Return real status codes.** A not-found route should return 404 to crawlers, and moved pages should return 301.
5. **Refresh snapshots** on a schedule that matches how often each section of the site changes, and right after you publish.

At the edge, the rule is a few lines. As a Cloudflare Worker that calls the Encited render API:

js

Copy Download

const CRAWLERS =

/ googlebot | bingbot | applebot | gptbot | oai-searchbot | chatgpt-user | claudebot | claude-user | perplexitybot | perplexity-user | facebookexternalhit | linkedinbot | twitterbot | slackbot / i;

export default {

async fetch (request, env) {

const url = new URL (request. url);

const ua = request. headers. get ("user-agent") ?? "";

const isPage = request. method === "GET" &&! / \. \w + $ /. test (url. pathname);

if (isPage && CRAWLERS. test (ua)) {

try {

const rendered = await fetch (

"https://encited.com/api/prerender/render?url=" + encodeURIComponent (request. url),

{

headers: {

"x-lovablehtml-api-key": env. LOVABLEHTML_API_KEY,

"user-agent": ua,

accept: "text/html",

},

redirect: "manual",

},

);

if (rendered. status === 301) {

return Response. redirect (rendered. headers. get ("location"), 301);

}

if (rendered. status === 200) return new Response (rendered. body, rendered);

} catch {

// Render API unreachable: serve the site as usual

}

}

return fetch (request);

},

};

`LOVABLEHTML_API_KEY` is your Encited API key, stored as a Worker secret. The render API answers with the snapshot (200), a redirect from your redirect rules (301), or a 304 when the request should go to your site as usual. The same check works in Fastly VCL, nginx, Vercel or Netlify middleware. The bot routing guide (https://encited.com/docs/domain-setup/dynamic-bot-rendering-bot-routing) covers each part in detail.

The renderer behind the rule can be one you run yourself on Puppeteer, which we cover in Puppeteer dynamic rendering (https://encited.com/blog/puppeteer-vs-managed-dynamic-rendering), or a managed service. Google's open-source Rendertron, which teams used to deploy on Google Cloud, is no longer maintained.

With Encited, the setup guides include a working rule for Cloudflare Workers (https://encited.com/docs/domain-setup/setup-with-cloudflare-workers), Fastly VCL (https://encited.com/docs/domain-setup/fastly-vcl), Express (https://encited.com/docs/domain-setup/express-js), Next.js (https://encited.com/docs/domain-setup/nextjs) and other hosts, or a DNS change (https://encited.com/docs/pre-rendering/setup-no-code-via-dns) with no code at all. Snapshots refresh on the schedule you set for each URL group (daily, weekly, monthly or quarterly), and you can re-render any page on demand or through the cache invalidation API (https://encited.com/docs/api-reference/cache-invalidation). Plans start at $19 a month with about 10,000 renders included.

### Web components and shadow DOM

Sites built with web components put part of their content inside shadow DOM. A plain HTML serialization of the page leaves shadow DOM content out, so a snapshot can look complete in a browser and still miss text. If your site uses web components, check the snapshot's HTML for the text inside them, and make sure your renderer flattens shadow DOM or that the components use declarative shadow DOM.

## How to test dynamic rendering for SEO

1. **Compare the raw responses.** Run `curl -A "Googlebot" https://yoursite.com/page` and `curl -A "Mozilla/5.0" https://yoursite.com/page`. The crawler response should contain your page text.
2. **Check AI crawlers.** Repeat with `-A "GPTBot"`. If it gets the empty shell, the AI user agents are missing from your rule.
3. **Use URL Inspection.** In Search Console, inspect a page and view the crawled HTML. Your content, title and canonical tag should be there.
4. **Check a missing URL.** Request a page that doesn't exist with a crawler user agent. It should return 404.
5. **Compare in one place.** Our crawler simulator (https://encited.com/free-tools/crawler-simulator) shows what Googlebot, Bingbot and AI crawlers each receive from a URL.
6. **Watch real crawler visits.** Crawl logs show which crawlers fetched which pages and the status each one got. Track indexing in Search Console and your citations in AI answers after the switch.

## FAQ

**What is rendering SEO?** The part of technical SEO that makes sure search engines and AI crawlers get the content a page builds with JavaScript. It covers how pages are rendered (client-side, server-side, static or dynamic) and checking what each crawler actually receives.

**How does dynamic rendering tell people from crawlers?** By the user agent each request sends. Requests from known crawlers get the snapshot, and everything else goes to your app. Google and Bing crawlers can also be verified with a reverse DNS lookup.

**What is dynamic rendering and how does it affect SEO?** Dynamic rendering serves search engines and AI crawlers a prerendered snapshot of each page while people get your JavaScript app. For SEO, it removes the wait for Google's render queue and puts your content, metadata and links in the first response. Encited serves HTML to search engines and Markdown to AI agents.

**What is the difference between CSR, SSR and dynamic rendering?** Client-side rendering builds the page in the visitor's browser, which leaves crawlers that don't run JavaScript with an empty page. Server-side rendering builds the HTML on your server for every request. Dynamic rendering keeps client-side rendering for people and serves crawlers a prerendered snapshot, without moving the app to SSR.

**Is dynamic rendering bad for SEO?** No. Google supports it, and there's no ranking penalty. It doesn't raise rankings by itself either: it makes sure crawlers receive your content, metadata and links. Problems come from stale snapshots, cached errors or serving crawlers different content.

**Does Google still support dynamic rendering?** Yes. Google's documentation now says it was a workaround and recommends server-side rendering for building the initial HTML. It still documents the setup, and dynamic rendering isn't being removed. John Mueller has said there's no rush to switch away from it.

**Do I need dynamic rendering if my site uses server-side rendering?** If everything on the page is in the first HTML response, no. If prices, reviews, stock, recommendations or other sections load in the browser afterwards, crawlers that read only the first response miss them, and dynamic rendering captures them.

**Is dynamic rendering cloaking?** Not when crawlers get similar content to what people see. Google says serving completely different content can be treated as cloaking. Snapshots cover public pages only: logged-in areas aren't routed, and visitors' cookies are never part of a render.

**Is dynamic rendering the same as prerendering?** Prerendering is the step of rendering pages to HTML ahead of time. Dynamic rendering is serving those prerendered pages to crawlers while people get the live app. Most services, including ours, do both.

**Is dynamic rendering still relevant in 2026?** Yes. Client-side apps still send crawlers an empty shell, server-rendered sites still load content after the first response, and the AI crawlers behind ChatGPT, Claude and Perplexity don't run JavaScript. Google recommends server-side rendering for new builds, which doesn't help sites that can't be rebuilt.

**Is SSR better than a single-page app for SEO?** A single-page app on its own sends crawlers an empty page, so SSR is better for SEO than a bare SPA. A single-page app with dynamic rendering gives crawlers the full page too, without the rewrite.

**Is SSG better than SSR?** For pages that change only on deploy, like docs and blog posts, static generation is faster and cheaper. For pages with frequently changing data or too many URLs to build ahead of time, SSR fits better.

**Do AI crawlers need dynamic rendering?** The ones behind ChatGPT, Claude and Perplexity can't run JavaScript. If your content is built in the browser, they need rendered HTML to read it.

### Serve every crawler a complete page

Dynamic rendering for Googlebot, Bingbot, link previews and AI crawlers. Set up through DNS or your host's middleware, with no changes to your app.

See how Encited works: https://encited.com/dynamic-rendering

## Get discovered anywhere search happens

Readable, citable, outranking pages.

Book a demo: https://encited.com/book-a-demo
Get started: https://encited.com/?authModal=true

Image: Avatar (https://replymaven.com/api/uploads/Su6Q0nK63iZW0ZFJBRNWpmRuppVDLuab/98df5262-f992-45fa-a750-00a6c919baf9.png)

How can we help?

Get instant answers to your questions or leave a message for an engineer will reach out

Ask AI about Encited

See our docs (https://lovablehtml.com/docs)

Contact support

Leave a message

We'll get back to you soon

Ask AI about Encited

Product questions, troubleshooting and

Thinking

Image: Preview

Drop an image to attach

Powered by ReplyMaven (https://replymaven.com/)

## Structured data

```json
[
  {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [
      {
        "@type": "ListItem",
        "position": 1,
        "name": "Home",
        "item": " https://encited.com/"
      },
      {
        "@type": "ListItem",
        "position": 2,
        "name": "Blog",
        "item": " https://encited.com/blog"
      },
      {
        "@type": "ListItem",
        "position": 3,
        "name": "Dynamic Rendering for SEO: How It Works, Benefits and Setup",
        "item": " https://encited.com/blog/dynamic-rendering-seo"
      }
    ]
  },
  {
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "Dynamic Rendering for SEO: How It Works, Benefits and Setup",
    "description": "Learn what dynamic rendering is, how it fixes JavaScript indexing for search and AI crawlers, how to set it up, and whether it's the right rendering strategy for your site.",
    "image": " https://encited.com/blog/thumbnails/dynamic-rendering-seo.webp",
    "datePublished": "2026-10-08",
    "dateModified": "2026-10-09",
    "author": {
      "@type": "Person",
      "name": "Aki from Encited"
    },
    "publisher": {
      "@type": "Organization",
      "name": "Encited.com",
      "alternateName": "LovableHTML.com",
      "logo": {
        "@type": "ImageObject",
        "url": "https://encited.com/brand/logo.svg"
      }
    },
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": " https://encited.com/blog/dynamic-rendering-seo"
    }
  }
]
```