Static Site Generators
How Hugo, Jekyll, Eleventy, Hexo, Gatsby, and Astro pre-build every page into static HTML — bypassing Google's JS rendering queue so content is indexable on the first fetch.
1 evidence signal on this page
- Related live toolRaw vs. Rendered HTML Checker
A static site generator (SSG) builds every page into finished HTML at build time, so your content is already in the raw HTML before a crawler ever asks for it — no JavaScript rendering queue, no Wave 2 delay, immediately indexable. That's the core SEO advantage over client-side frameworks. Hugo, Jekyll, Eleventy, Hexo, Gatsby, and Astro all share it; they differ in language, how much JS they ship to the browser, and built-in image/sitemap tooling. The one real gotcha is build freshness: a static site is only as current as its last build, so content changes need a rebuild and redeploy to reach search engines. I built this site (and patrickstox.com) with Astro for exactly these reasons.
TL;DR — A static site generator builds your whole site into plain HTML files ahead of time. So when Google shows up, the content is already there in the page — no waiting for JavaScript to run. That’s the easiest possible setup for SEO. The catch: the site only updates when you rebuild it.
What a static site generator is
Most of the SEO trouble with JavaScript comes down to one question: is your content actually in the page when a crawler fetches it, or does it only appear after scripts run? A static site generator (SSG) sidesteps that question entirely.
An SSG takes your content (usually written in Markdown) and your templates, and — on your computer or a build server — turns every page into a finished HTML file before anyone visits. You then upload those plain HTML files to a host. When Google, Bing, or a reader requests a page, they get complete HTML on the first try. Evidence for this claim A static site generator builds source content and templates into static files before requests are served. Scope: Hugo as a representative static site generator. Confidence: high · Verified: Hugo documentation
Compare that to a typical JavaScript app, where the server sends a near-empty shell and the browser builds the page afterward. With an SSG, there’s nothing to build in the browser — it’s already done.
Why that’s great for SEO
- The content is in the raw HTML. No rendering step has to succeed for Google to see your text and links.
- It’s fast. Plain HTML files load quickly, which helps Core Web Vitals.
- There’s less to break. Fewer moving parts means fewer ways for content to go missing from search.
The popular ones
There are six you’ll hear about most: Hugo, Jekyll, Eleventy, Hexo, Gatsby, and Astro. They all produce static HTML; they differ in what language they’re built in and how much extra JavaScript (if any) they send to the browser. Each has its own deep dive linked at the bottom of this page.
The one thing to watch
A static site is a snapshot. It shows whatever was true the last time you built it. If you change a price, fix a typo, or publish a post and forget to rebuild and redeploy, search engines keep seeing the old version. So the main discipline with an SSG is making sure changes trigger a fresh build. Evidence for this claim Changes to a statically generated site require a new build and deployment before the generated output changes. Scope: Astro static builds as a representative SSG workflow. Confidence: high · Verified: Astro: Deploy your site
Want the technical version — how SSGs differ from client-side frameworks and meta-frameworks, a side-by-side comparison of all six, and the build-freshness trap in detail? Switch to the Advanced tab.
TL;DR — An SSG pre-renders every route to static HTML at build time, so the content exists in the response before the first crawler request — no Web Rendering Service, no rendering queue, no “Wave 2” delay. That’s the single biggest indexability advantage you can give a site. SSGs differ from CSR frameworks (which build the page in the browser) and from meta-frameworks (which can SSR per request). The six in this cluster — Hugo, Jekyll, Eleventy, Hexo, Gatsby, Astro — all ship static HTML; they vary in language, JS payload, and built-in sitemap/image tooling. The real failure mode isn’t rendering, it’s build freshness: a static site is only as current as its last build, so changed content that doesn’t trigger a rebuild silently serves stale HTML to search engines. I run this site on Astro for exactly this set of trade-offs.
What “static” actually means
A static site generator runs your content and templates through a build step and emits a folder of finished HTML, CSS, and assets. The crucial part for SEO is when the HTML is produced: at build time, once, for everyone — not per request, and not in the browser. Google’s JavaScript guidance describes crawling, rendering, and indexing as distinct processing stages. An SSG removes client-side rendering from the critical path for its generated content because the HTML is already complete. Evidence for this claim Google processes JavaScript through crawling, rendering, and indexing, while pre-rendered HTML is present before client execution. Scope: Google Search JavaScript processing; indexing is not guaranteed. Confidence: high · Verified: Google: JavaScript SEO basics
This is why static sites are the safest possible architecture for getting indexed. The content is in the first byte of the response. There’s no parity gap between raw and rendered HTML, no dependency on the renderer succeeding, no stateless-Chrome quirks to design around.
SSG vs. client-side rendering vs. meta-frameworks
Three architectures, three different moments the HTML comes into existence:
- Static site generation (SSG). HTML is built once, at build time, before any request. Served as flat files (often from a CDN). Content is in the raw HTML. This is Hugo, Jekyll, Eleventy, Hexo — and Gatsby and Astro in their default static mode.
- Client-side rendering (CSR). The server sends a minimal shell; JavaScript builds the page in the browser at request/runtime. Content depends on rendering succeeding. This is a default-CSR React or Vue SPA — the riskiest setup for SEO (see JavaScript SEO).
- Meta-frameworks (SSR / hybrid). Frameworks like Next.js, Nuxt, and SvelteKit can render HTML per request on the server (SSR), pre-render some routes (SSG), or mix both. Content is in the HTML, but produced at request time, which adds server cost and latency you don’t have with a pure SSG.
The line blurs at the edges — Gatsby and Astro are sometimes called meta-frameworks because they’re component-based and can do more than emit flat files. But in their bread-and-butter mode they’re static generators, and that’s how you should treat them for SEO. The mental model that matters: the earlier the HTML exists, the less can go wrong before a crawler sees it. SSG is the earliest.
The six generators, compared
All six produce indexable static HTML. Here’s how they differ on the axes that actually affect an SEO decision:
| Generator | Language / built in | JS shipped to browser | Sitemap | Image optimization | Best for |
|---|---|---|---|---|---|
| Hugo | Go | None by default | Built-in (sitemap.xml auto-generated) | Built-in image processing (resize, WebP) | Large content sites that need fast builds |
| Jekyll | Ruby | None by default | Plugin (jekyll-sitemap) | Plugins (jekyll-picture-tag etc.) | GitHub Pages blogs; the original SSG |
| Eleventy (11ty) | JavaScript (Node) | None by default | Template/plugin (you generate it) | Plugin (@11ty/eleventy-img) | JS devs who want zero-JS output and flexibility |
| Hexo | JavaScript (Node) | None by default (theme-dependent) | Plugin (hexo-generator-sitemap) | Plugins | Blogs, especially in the Node/Asia ecosystem |
| Gatsby | JavaScript / React | React bundle (hydrates) | Plugin (gatsby-plugin-sitemap) | Built-in (gatsby-plugin-image, strong) | React teams wanting a data-driven static site |
| Astro | JS/TS, any UI framework | None by default (islands only) | Official (@astrojs/sitemap) | Built-in (astro:assets) | Content sites wanting components without the JS tax |
A few things worth pulling out of that table:
- JS payload is the SEO-adjacent differentiator. Hugo, Jekyll, Eleventy, and Hexo ship essentially no JavaScript unless you add it. Gatsby rehydrates a full React bundle on the client — still indexable (the HTML is static), but it carries a Core Web Vitals cost the others don’t. Astro splits the difference with islands architecture: static HTML by default, JavaScript only for the specific interactive components (“islands”) that need it.
- Build speed scales differently. Hugo (Go) is famously fast and handles tens of thousands of pages comfortably. The Node-based generators are slower at large scale, and Gatsby’s build times have historically been its biggest complaint.
- Sitemaps and image optimization are mostly solved everywhere — but Hugo and Astro give you the most out of the box, while Jekyll/Eleventy/Hexo lean on (well-maintained) plugins.
- Gatsby’s release cadence has slowed noticeably. The project isn’t archived and still ships patches, but as of July 2026 its GitHub repo shows only a handful of commits over the trailing 90 days and one minor release since February. That’s worth weighing against a more actively-developed option if you’re picking a generator today, on top of the hydration/CWV cost above.
Why I built this on Astro
I built this site — and patrickstox.com — with Astro, and the reasoning is straight out of this page. I wanted to author in Markdown/MDX with real components, but I did not want to pay the JavaScript tax on every page just to get them. Astro’s default is zero client-side JS: the pages you’re reading ship as static HTML, and the only JavaScript that loads is for the handful of interactive pieces (like the lens tabs and the quiz). That gets me the indexability of a classic SSG and good Core Web Vitals, without giving up a component-based authoring experience. If I needed blistering build speed across a huge content set with zero interactivity, Hugo would be the obvious call; for a React data layer, Gatsby. For this — a content-heavy site with a few interactive flourishes — Astro is the right trade.
The one real gotcha: build freshness
Everything above is the upside. Here’s the catch that bites people.
A static site is only as current as its last build. The HTML is a snapshot frozen at build time. Change a price, correct a fact, publish a post, update a title tag — none of it reaches search engines until you rebuild and redeploy. There’s no live server assembling the page from a database on each request, so there’s nothing to pick up your change automatically. Evidence for this claim Static build output remains a snapshot until the project is rebuilt and redeployed. Scope: Astro static build workflow as a representative example. Confidence: high · Verified: Astro: Build and deploy
In practice this means:
- Content edits must trigger a build. If you author in a headless CMS or Git, wire up a webhook so a publish kicks off a deploy. A manual-only build process is how stale prices and “ghost” 404s sneak into the index.
- Frequently-changing data is awkward. Inventory, prices, live counts — if it changes faster than you rebuild, the static copy lags. That’s where incremental builds, scheduled rebuilds, or a hybrid (a meta-framework with SSR/ISR for the volatile routes) earn their keep.
- Time-sensitive pages need a cadence. If “today’s deals” is baked at build time, the build has to run at least daily, or the page lies.
None of this is a dealbreaker — it’s a discipline. The whole reason SSGs are great for SEO (HTML decided ahead of time) is the same reason you have to be deliberate about re-deciding it when content changes.
Where to go next: the static site generators cluster
This hub is the map. Each generator below is its own deep dive — language, JS payload, sitemap/image tooling, the framework-specific SEO gotchas, and how to keep builds fresh:
- Hugo SEO — Go-powered, zero-JS, blazing builds; the auto-generated sitemap, built-in image processing, and managing huge content sets.
- Jekyll SEO — the original SSG and the GitHub Pages default;
jekyll-seo-tag,jekyll-sitemap, and the plugin-on-GitHub-Pages limitation. - Eleventy (11ty) SEO — JavaScript-based, zero-JS output; generating sitemaps
from templates and
eleventy-imgfor responsive images. - Hexo SEO — the Node blog generator; sitemap/feed plugins, theme JS, and permalink/canonical hygiene.
- Gatsby SEO — React-based static generation; the hydration/CWV trade-off,
gatsby-plugin-image,gatsby-plugin-sitemap, and build-time data sourcing. - Astro SEO — zero-JS by default, islands architecture,
@astrojs/sitemap,astro:assets, View Transitions, and Server Islands fallback behavior.
Every topic above is nested under this hub and lives in the sidebar too.
For the broader context — how Google renders JavaScript, the parity and interaction failure modes, and which rendering mode to pick when you do need JS — see the parent JavaScript SEO hub.
AI summary
A condensed take on the Advanced version:
- An SSG pre-renders every page to static HTML at build time — content exists in the response before the first crawler request. No Web Rendering Service, no rendering queue, no “Wave 2” delay. The safest architecture for indexability.
- Three architectures by when the HTML exists: SSG (build time, safest), CSR (in the browser at runtime, riskiest), meta-frameworks/SSR (per request on the server, content present but with latency/cost).
- All six generators ship indexable static HTML. They differ in language, JS
payload, and built-in sitemap/image tooling:
- Hugo (Go) — zero JS, fastest builds, built-in sitemap + image processing.
- Jekyll (Ruby) — zero JS, GitHub Pages default, plugin-driven.
- Eleventy (Node) — zero JS, flexible, plugin-driven.
- Hexo (Node) — zero JS by default, blog-focused, plugin-driven.
- Gatsby (React) — hydrates a React bundle (CWV cost), strong image tooling, but its release cadence has slowed markedly as of mid-2026.
- Astro (any framework) — zero JS by default via islands, official sitemap
astro:assets.
- JS payload is the SEO-adjacent differentiator — Gatsby carries a React bundle; Astro’s islands ship JS only where needed; the rest are zero-JS.
- Patrick built this site (and patrickstox.com) on Astro — components without the JS tax: static HTML + good Core Web Vitals.
- The one real gotcha is build freshness: a static site is only as current as its last build. Wire content edits to a rebuild webhook; use incremental/scheduled builds or a hybrid SSR/ISR route for fast-changing data.
Official documentation
Primary-source documentation — from the search engines and from each generator.
Search engines — rendering & static HTML
- Understand the JavaScript SEO basics — the crawl → render → index phases that a static build lets you skip for content.
- In-Depth Guide to How Google Search Works — where rendering sits, and why pre-rendered HTML is lowest-risk.
The generators
- Hugo documentation — and the sitemap template and image processing docs.
- Jekyll docs — plus jekyll-seo-tag and jekyll-sitemap.
- Eleventy (11ty) docs — and eleventy-img.
- Hexo docs — and the hexo-generator-sitemap plugin.
- Gatsby docs — and gatsby-plugin-image and gatsby-plugin-sitemap.
- Astro docs — plus @astrojs/sitemap and astro:assets / images.
Quotes from the source
On-the-record statements from Google and from the generators’ own teams, plus a note from my own writing.
Google — rendering is a separate step
- “During the crawl, Google renders the page and runs any JavaScript it finds using a recent version of Chrome.” — the step an SSG removes from the critical path by shipping finished HTML. Jump to quote
- “Rendering is important because websites often rely on JavaScript to bring content to the page, and without rendering Google might not see that content.” — i.e., if the content is already in the static HTML, rendering can’t cost you visibility. Jump to quote
Astro — static by default
- “By default, Astro pages, routes, and API endpoints will be pre-rendered at build time as static pages. However, you can choose to render some or all of your routes on demand by a server when a route is requested.” Jump to quote
Hugo — speed
- Hugo bills itself as “the world’s fastest framework for building websites” — the build-speed advantage that matters at large content scale. Source
Patrick Stox (my own work — JavaScript SEO: A Definitive Guide)
- “Any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines.” — static generation is the low-risk end of that spectrum.
Static-site SEO checklist
A quick pass to confirm your SSG setup is search-friendly — and staying fresh:
- Important content is present in View Source (raw HTML), not just after JS runs — the whole point of an SSG.
- An XML sitemap is generated on every build and submitted in Google Search Console and Bing Webmaster Tools.
- Each page has unique, build-time
<title>and meta description (via the generator’s templating or an SEO plugin/integration). - Canonical tags are set and point to the live, final URLs (not localhost or a preview domain).
- Images are optimized at build time (responsive sizes, modern formats) — use the generator’s built-in tooling or image plugin.
- Any client-side JavaScript (Gatsby’s React bundle, Astro islands, theme JS) isn’t hiding primary content behind interaction.
- JS/CSS assets are not blocked in
robots.txt. - Content edits trigger a rebuild + redeploy — a CMS/Git webhook fires a deploy automatically.
- Time-sensitive or frequently-changing pages have a scheduled rebuild cadence (or are served via SSR/ISR instead of static).
- Old URLs from a previous build aren’t left as orphaned static files — clean the output dir / handle removals so deleted pages 404 or 410.
- The deployed build matches the latest content (spot-check a recently changed page in production, not just locally).
Static site generators — cheat sheet
The six at a glance
| Generator | Language | JS to browser | Sitemap | Best for |
|---|---|---|---|---|
| Hugo | Go | None | Built-in | Huge sites, fastest builds |
| Jekyll | Ruby | None | Plugin | GitHub Pages blogs |
| Eleventy | Node | None | Template/plugin | Flexible zero-JS output |
| Hexo | Node | None* | Plugin | Node-ecosystem blogs |
| Gatsby | React | React bundle | Plugin | React/data-driven sites |
| Astro | Any | None (islands) | Official | Content + light interactivity |
When the HTML exists (and why it matters)
| Architecture | HTML produced | SEO risk |
|---|---|---|
| SSG (static) | At build time, once | Lowest — content in raw HTML |
| SSR / meta-framework | Per request, on server | Low — present, but server cost/latency |
| CSR (SPA) | In the browser, at runtime | Highest — depends on rendering |
Fast facts
- SSG = no Web Rendering Service in the critical path → no “Wave 2” delay for content.
- Gatsby hydrates a React bundle (CWV cost); Astro ships JS only for islands; Hugo/Jekyll/Eleventy/Hexo are zero-JS by default.
- Gatsby’s release cadence has slowed as of mid-2026 — check its GitHub activity before betting a new build on it.
- Hugo (Go) is the speed champion at large scale.
- The one trap: build freshness — a static site shows its last build. Wire a rebuild webhook to content edits.
- Fast-changing data (prices, inventory) → incremental/scheduled builds or hybrid SSR/ISR.
Which rendering path fits?
Choose a static-site approach
The build → deploy → verify framework
- Build: enumerate intended routes and generate complete HTML, metadata, canonicals, and structured data.
- Deploy: publish the new artifact atomically so HTML, assets, sitemaps, and redirects stay in sync.
- Verify: compare source HTML and the production response with the content version that triggered the build.
Static HTML solves rendering dependence; it does not solve stale builds, missing routes, broken deploy hooks, or client-side metadata that never reaches source HTML.
Check whether key content exists in source HTML
curl -sS https://example.com/page/ | grep -F 'Expected visible heading' For a URL list, fail CI when a production route is missing or lacks a title:
while IFS= read -r url; do html=$(curl -fsSL "$url") || { echo "FETCH FAIL $url"; continue; }; printf '%s' "$html" | grep -qi '<title>[^<]' || echo "TITLE FAIL $url"; done < urls.txtRun this in DevTools Console to compare a rendered page’s title, canonical, and heading:
({title: document.title, canonical: document.querySelector('link[rel="canonical"]')?.href, h1: document.querySelector('h1')?.textContent.trim()}); Patrick's relevant free tools
- SEO Incident Simulator — Practice thirty deterministic technical SEO incident investigations — indexability, crawl controls, redirects, sitemaps, markup, caching, DNS, bot verification, rendering, hreflang, and faceted navigation — with clearly labeled fixture evidence and Find → Fix → Verify handoffs.
Tools for static output
- Raw vs. Rendered HTML Checker shows whether important content and head signals are already present in the initial HTML.
- HTTP Status Checker checks generated routes, redirects, and missing pages in batches.
- HTTP Header Checker inspects caching and deployment headers across redirects.
- A framework’s build log and deployment manifest are the source of truth for which routes were generated successfully.
Prove the static deployment works
Source-HTML test
Test to run: fetch representative production URLs with curl or Render Gap. Expected result: primary content, title, canonical, and links appear in raw HTML. Failure interpretation: the route is client-rendered or the build omitted data. Monitoring window: immediate after deploy. Rollback trigger: important templates ship empty or incomplete source HTML.
Publishing-freshness test
Test to run: publish a controlled content change and compare its CMS timestamp, build log, deploy artifact, and live HTML. Expected result: the change triggers one successful build and reaches production. Failure interpretation: the webhook, build, cache, or deployment chain is stale. Monitoring window: the normal publish SLA. Rollback trigger: production mixes old HTML with new metadata or assets.
Route-completeness test
Test to run: compare intended canonical URLs with generated/deployed routes and batch-check statuses. Expected result: every intended route returns its planned status. Failure interpretation: dynamic path discovery or build configuration missed routes. Monitoring window: every build. Rollback trigger: canonical pages become 404s or redirect unexpectedly.
Test yourself: Static Site Generators
Five quick questions on why static site generators are easy mode for SEO — and the one thing that can still trip you up. Pick an answer for each, then check.
Resources worth your time
My related writing
- JavaScript SEO: A Definitive Guide — rendering, DOM parity, and why static/prerendered output is the low-risk end of the spectrum.
- The Beginner’s Guide to Technical SEO — where rendering architecture fits in the bigger picture.
My speaking
- How Search Works (SlideShare) — my walkthrough of crawling, rendering, indexing, and ranking. (My standing disclaimer applies: “This is my understanding of systems… not going to be 100% complete or accurate.”)
From around the industry
- web.dev — Rendering on the Web — the Chrome team’s canonical explainer of SSG vs. SSR vs. CSR and the trade-offs between them.
- Google Search Central — JavaScript SEO basics — the crawl → render → index phases a static build lets you skip for content.
- Jamstack — the architectural movement (pre-rendered markup served from a CDN) that static site generators are the engine of, with a generators directory.
- Astro — Why Astro? — the clearest statement of the “static HTML, zero JS by default, islands for interactivity” model.
- Hugo — the Go-based generator built around build speed at large content scale.
- Smashing Magazine — Static site generator coverage — practitioner articles on choosing and using SSGs.
Static Site Generator
A build tool that pre-renders every page into static HTML files at deploy time, so the server delivers complete HTML without executing code per request — eliminating JavaScript rendering delays for search engine crawlers.
Related: JavaScript SEO, Rendering, Astro SEO
Static Site Generator
A static site generator (SSG) is a build tool that processes templates, content files, and data sources at deploy time to produce a complete set of static HTML files. Unlike server-side rendering (where HTML is generated on each request) or client-side rendering (where the browser builds the page from JavaScript), SSGs generate all pages once and serve them as plain files.
For SEO, static generation is the safest rendering approach: search engine crawlers receive complete HTML with no JavaScript execution required, no render queue delay, and no risk of timing out on slow or complex scripts. Pages indexed from static HTML typically match what users see exactly, eliminating the parity gap that client-side rendering introduces.
Popular static site generators include Hugo (Go-based, very fast builds), Jekyll (Ruby, GitHub Pages native), Eleventy (JavaScript, flexible), Hexo (JavaScript, blog-focused), Gatsby (React-based, GraphQL data layer), and Astro (component islands, ships zero JavaScript by default). Next.js and Nuxt support SSG mode alongside SSR and ISR, making them meta-frameworks rather than pure SSGs.
Related: JavaScript SEO, Rendering, Astro SEO
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Revision history
Compare the published article with an archived editorial snapshot. Added and removed words are shown only after you open a comparison.
Updated Jul 19, 2026.
Editorial summary and recorded change details.Summary
Verified generator versions/roster against npm and GitHub release data, replaced a direct Astro quote that no longer appears on the live docs page with an accurate one, and added a dated note about Gatsby's markedly slower 2026 release cadence next to its comparison-table recommendation.
Change details
- Before
Quoted Astro's why-astro page: "Astro renders your entire website to static HTML during the build, removing all JavaScript from your final page by default." — no longer present on the live page.AfterReplaced with a verbatim, currently-live quote from Astro's on-demand-rendering guide confirming static pre-rendering is still the default, with a working #:~:text= fragment. -
Added a sentence to the advanced-lens generator comparison and a cheat-sheet note flagging that Gatsby's GitHub release cadence has slowed markedly in 2026 (one minor release since February, versus a burst of patches in 2025) — worth weighing when choosing a generator today.