Dynamic Rendering
A technique where different content is served to search engines and users by rendering JavaScript applications server-side for crawlers while delivering client-side rendered content to browsers.
What is Dynamic Rendering?
Dynamic rendering is an advanced SEO technique that serves two different versions of a page based on whether the requester is a search engine bot or a regular user. The strategy involves delivering fully rendered HTML to search engine crawlers (containing all meta tags, content, and structured data) while serving JavaScript to users for interactivity and dynamic features. Unlike cloaking, which violates guidelines by intentionally deceiving search engines, dynamic rendering is an acknowledged technique that Google explicitly approves for JavaScript applications where crawlers have difficulty indexing client-side rendered content. Dynamic rendering solves the problem of Single Page Applications (SPAs) and heavily JavaScript-dependent sites that don't include meaningful content in the initial HTML. Traditional crawlers struggle with JavaScript-heavy sites because content is rendered in the browser by JavaScript, not included in the raw HTML. Dynamic rendering bypasses this by pre-rendering pages server-side when detected as a crawler, ensuring search engines get indexable content. Implementation typically uses headless browser services like Headless Chrome, Puppeteer, or services like Rendertron and Prerender.io. Google stated that dynamic rendering is acceptable as a workaround for JavaScript rendering issues, particularly for complex applications. However, Google has also recommended that client-side rendering, server-side rendering, or static generation are preferable long-term solutions. Dynamic rendering should be temporary solution while improving overall site architecture.
Why It Matters for SEO
Dynamic rendering enables search engines to properly index JavaScript applications that would otherwise be invisible in search results. For complex web applications that rely heavily on JavaScript, dynamic rendering makes SEO possible without requiring major architectural changes. However, dynamic rendering introduces technical complexity and potential inconsistencies between what crawlers see and what users see. It also requires maintenance—keeping the rendered version in sync with the live version requires diligent updates. While Google approves dynamic rendering, it's considered a workaround rather than a best practice. Sites using dynamic rendering should be working toward better long-term solutions like proper server-side rendering or static site generation. The technique shows intent to be SEO-friendly, but raises red flags if the rendered and user versions diverge significantly.
Examples & Code Snippets
Dynamic Rendering Architecture
// DYNAMIC RENDERING FLOW
USER REQUEST:
1. Browser requests https://example.com/product/123
2. Server checks User-Agent header
3. Regular browser → Serve JavaScript application
4. Search crawler (Googlebot, Bingbot) → Render with Puppeteer, serve HTML
---
// SERVER-SIDE IMPLEMENTATION (Node.js example)
const express = require('express');
const puppeteer = require('puppeteer');
const isCrawler = (userAgent) => {
const crawlers = /bot|crawler|spider|googlebot|bingbot/i;
return crawlers.test(userAgent);
};
app.get('*', async (req, res) => {
const userAgent = req.get('User-Agent');
if (isCrawler(userAgent)) {
// Serve pre-rendered content to crawlers
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(req.url, { waitUntil: 'networkidle2' });
const html = await page.content();
res.send(html);
} else {
// Serve JavaScript application to users
res.sendFile('index.html');
}
});
---
// USING RENDERTRON (Easier approach)
// Install Rendertron service
// Docker: docker run -d -p 3000:3000 rendertron/rendertron
const express = require('express');
const rl = require('request-promise');
app.get('*', async (req, res) => {
const userAgent = req.get('User-Agent');
if (isCrawler(userAgent)) {
// Send to Rendertron for rendering
const renderedHtml = await rl.get(
`http://localhost:3000/render/${req.url}`
);
res.send(renderedHtml);
} else {
// Normal request
res.sendFile('index.html');
}
});
---
// WHEN TO USE DYNAMIC RENDERING:
✓ Complex single-page applications (React, Vue, Angular)
✓ Heavily JavaScript-dependent content
✓ When you can't refactor to SSR/SSG yet
✓ Temporary workaround while improving architecture
// WHEN NOT TO USE:
✗ Simple websites (use static HTML)
✗ When you can implement SSR/SSG
✗ If it creates content divergence between crawlers and users
✗ As a permanent solutionHow dynamic rendering works for JavaScript applications
If you're heavily JavaScript-dependent, dynamic rendering can help in the short term. However, invest in transitioning to server-side rendering (Next.js, Nuxt) or static generation (Gatsby, Hugo) for better performance and easier SEO. Always ensure the rendered version for crawlers remains in sync with the user-facing version.
Frequently Asked Questions
Ready to Grow Your Organic Traffic?
Get a free SEO audit and a custom strategy roadmap for your business. No commitment required — just results-focused recommendations from our team.