Static vs dynamic pages
Last reviewed
A static page is a finished HTML file built in advance, and a dynamic page is built when someone asks for it, either on the server or in the browser with JavaScript. For SEO the question is not static or dynamic but where the HTML is built: static and server-rendered pages send finished HTML that every crawler can read, while client-side rendered pages send an empty shell that only crawlers running JavaScript can fill.
Three ways to build a page
| Static | Server-rendered (dynamic on the server) | Client-side rendered (dynamic in the browser) | |
|---|---|---|---|
| When the HTML is built | At build time | On each request | In the browser, after JavaScript runs |
| What the server sends | Finished page | Finished page | Shell and scripts |
| Indexed from the first fetch | Indexed from the first fetch | Indexed after rendering, which is queued | |
| AI crawlers | Full page | Full page | Empty page |
| Fresh content | Only after a rebuild | Every request | Every request |
| Hosting | Any file host or CDN | A server that runs your code | Any file host or CDN |
| Examples | Hugo, Astro, Next.js static export | PHP, WordPress, Rails, Next.js server rendering | Create React App style SPAs, Vite apps, many no-code app builders |
Google's web.dev team defines the terms like this:
- Server-side rendering: "Rendering an app on the server to send HTML, rather than JavaScript, to the client."
- Static rendering: "Static rendering happens at build time."
- Client-side rendering: "Rendering an app in a browser, using JavaScript to modify the DOM."
- Prerendering: "Running a client-side application at build time to capture its initial state as static HTML."
Why it matters for indexing
Static and server-rendered pages. The first response has the content, links, title and meta tags. Google can read it on the first fetch. So can crawlers that never run JavaScript.
Client-side rendered pages. Google processes them in three phases: crawling, rendering and indexing. "Googlebot queues all pages with a 200 HTTP status code for rendering", and "the page may stay on this queue for a few seconds, but it can take longer than that." Vercel and MERJ measured the delay on nextjs.org in April 2024: 10 seconds at the median and about 18 hours at the 99th percentile.
Google can index a client-side rendered site. It still says "server-side or pre-rendering is still a great idea" because "not all bots can run JavaScript". web.dev puts it the same way: "Crawlers can understand JavaScript, but there are often limitations to how they render."
AI crawlers. Vercel and MERJ found in December 2024 that "none of the major AI crawlers currently render JavaScript". For a client-side rendered page, GPTBot, ClaudeBot and PerplexityBot see the shell. More on how AI crawlers see your site.
Which one is your site?
curl -s https://www.<your-domain>/ | grep -c "<p"
curl -s https://www.<your-domain>/ | grep -oE '<div id="(root|app)"[^>]*>[^<]{0,40}'
If the first line prints 0 or close to it on a page full of text, and the second shows an empty root or app element, the page is client-side rendered. Static and server-rendered pages show their paragraphs in the raw HTML. The free checker compares the raw and rendered page for you.
See what ChatGPT sees on your site
Static vs dynamic: which is better for SEO?
Neither, as long as the HTML is finished when a crawler gets it.
- Choose static for content that changes on deploy: marketing pages, docs, blogs. Fast, cheap to host, nothing to render on request.
- Choose server rendering for content that changes often or per request: stores, listings, dashboards with public pages.
- Client-side rendering works for logged-in apps where SEO does not matter. For public pages, pair it with one of the options below.
Google's long-term recommendation for JavaScript sites is "server-side rendering, static rendering, or hydration".
If your site is client-side rendered today
- Migrate to a framework with server or static rendering. The most complete fix. It costs a rebuild. See React SEO and single page application SEO.
- Prerender at build time. Save an HTML file per route. Good for small sites whose routes change only on deploy.
- Prerender on request. A service renders the page in a real browser when a crawler asks and serves it from a cache. Google calls this dynamic rendering, "a workaround and not a long-term solution", and says that "as long as your dynamic rendering produces similar content, Googlebot won't view dynamic rendering as cloaking." More in what is prerendering.
When Prebaked is the right choice
Prebaked prerenders on request. It fits client-side rendered sites that work for people and need finished HTML for crawlers, without a migration.
- One snippet in front of the site: Cloudflare Worker, Express, nginx, Netlify or Vercel.
- Crawlers get the page rendered in Chromium, the same content your visitors see.
- Cache hits are free, and you can warm the cache from your sitemap.
- If Prebaked is slow or down, crawlers get your original page.
If your site is already static or server-rendered, you do not need Prebaked.
FAQ
What is the difference between a static and a dynamic page?
A static page is a finished HTML file built in advance and served as is. A dynamic page is built per request, on the server or in the browser with JavaScript.
Are static pages better for SEO?
Not by being static. They are easy for crawlers because the HTML is finished. A server-rendered dynamic page is just as readable.
Is a dynamic website bad for SEO?
No. Server-rendered dynamic sites send finished HTML. The risk is client-side rendering, where crawlers that do not run JavaScript see an empty page and Google has to render before indexing.
Can Google index client-side rendered pages?
Yes. Google renders JavaScript in a headless Chromium after a queue. Rendering can fail or miss content, so check the rendered HTML in URL Inspection. See how to debug rendering problems.
Is prerendering the same as static generation?
Close. Both produce finished HTML. Static generation is built into the framework at build time. Prerendering captures the HTML of a client-side app, at build time or when a crawler asks.