Eleventy SEO
Eleventy (11ty) ships zero client-side JavaScript by default, so your content is in the raw HTML on the first fetch. The catch — it generates no title tags, meta descriptions, canonicals, or sitemaps. Here's how to configure SEO on an Eleventy site, built around the data cascade.
1 evidence signal on this page
- Related live toolRedirect Checker
Eleventy outputs plain HTML with zero client-side JavaScript by default, which is the safest possible starting point for indexability — content is in the first byte, nothing to render. The trade-off: Eleventy generates no SEO markup at all. Every title, meta description, canonical, sitemap, and bit of structured data is something you implement yourself. The data cascade (_data/site.js → directory data → front matter → eleventyComputed) is the architecture that makes that scalable: declare defaults once, derive canonicals automatically. Plugins like eleventy-plugin-seo and @11ty/eleventy-img add convenience, not capability. Pick any template language — it doesn't affect SEO.
TL;DR — Eleventy builds your site into plain HTML files ahead of time, and — unlike most JavaScript tools — it sends no JavaScript to the browser by default. That’s about as friendly as it gets for Google. The catch: Eleventy won’t write your title tagsThe title tag is the HTML title element in a page's head that specifies the document's title. It's the primary source for the SERP title link and a confirmed light ranking factor — but since August 2021 Google doesn't always show it verbatim., meta descriptionsThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., or sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. for you. You have to add those yourself.
What Eleventy is
Eleventy (you’ll also see it written 11ty) is a static site generatorA 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.. You write your content in Markdown and your page templates in something like Nunjucks or Liquid, and Eleventy turns all of it into finished HTML files before anyone visits. You upload those files to a host, and when Google or a reader requests a page, they get complete HTML straight away. Evidence for this claim Eleventy transforms templates and data into static output files during a build. Scope: Eleventy static site generation. Confidence: high · Verified: Eleventy documentation
The thing that sets Eleventy apart from most JavaScript-based tools is that it ships zero JavaScript to the browser by default. Evidence for this claim Eleventy does not require a client-side JavaScript runtime and ships only the browser JavaScript a developer adds. Scope: Eleventy core output; site code can add JavaScript. Confidence: high · Verified: Eleventy documentation The page a visitor gets is plain HTML — nothing has to run in the browser to build it. For SEO that’s ideal: there’s no renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. step for Google to wait on, and pages load fast.
Why that helps SEO
- Your content is in the raw HTML. Google sees your text and links on the first fetch — no JavaScript has to run successfully first.
- It’s fast. Plain HTML with no script payload is great for Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data..
- Less can break. Fewer moving parts means fewer ways for content to go missing from search.
The big catch: Eleventy does not do SEO for you
This is the part people get wrong. Eleventy gives you clean HTML, but it adds none of the SEO markup automatically:
- No
<title>tag - No meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through.
- No canonical link
- No sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing.
- No structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding.
All of that is yours to add — usually in a shared layout file that wraps every
page, so you write it once and every page inherits it. There are plugins that help
(the popular one is eleventy-plugin-seo), but they’re conveniences, not magic.
The work still has to happen.
The mental model: the data cascade
Eleventy’s clever trick for doing this without hand-editing every page is the data cascade. You set sitewide defaults once in a global data file (your site name, base URL, default social image), and Eleventy applies them everywhere. Override them per section or per page only where you need to. It even lets you compute values — like building each page’s canonical URLHow search engines pick one canonical URL among duplicates and consolidate signals onto it. automatically from your domain plus the page’s path.
Want the technical version — the full data cascade, code for meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. and canonicals, the plugin comparison, sitemaps, image optimization, and paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does. SEO? Switch to the Advanced tab.
TL;DR — Eleventy emits plain HTML at build time with zero client-side JS by default, so content is in the response before the first crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. request — the lowest-risk indexability setup there is. But Eleventy ships no SEO markup: title, description, canonical, robots, OG, sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., and JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. are all yours to build. The data cascade (
_data/site.js→ directory data files → front matter →eleventyComputed) is the architecture that makes this scale — declare defaults once, derive canonicals ineleventyComputed. Plugins (eleventy-plugin-seo,@11ty/eleventy-img,@quasibit/eleventy-plugin-sitemap) add convenience, not capability.robots.txtis a passthrough file. Template language is an SEO non-issue — pick by team familiarity. v3 is ESM-first and makes the Image Transform plugin the default path to CWVGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data.-clean images. Watch three edge cases:eleventyComputeddependency ordering can fail silently, collection membership doesn’t guarantee a URL was emitted, and a local build is not proof of what production actually serves — verify the deployed artifact directly.
Why Eleventy is a strong SEO baseline
Eleventy builds every route to static HTML at build time and, unlike Next.js, Nuxt, Gatsby, or Astro, ships no JavaScript to the browser unless you add it. Evidence for this claim Eleventy compiles templates to static output and adds no client-side framework runtime by default. Scope: Eleventy core behavior. Confidence: high · Verified: Eleventy documentation There’s no client-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. for a crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. to wait on, no renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. budget impact, and no hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. bundle taxing Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data.. Real production Eleventy sites routinely report Lighthouse scoresLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. of 99–100 across the board and homepages that ship 0 KB of JavaScript.
It’s also fast to build, which matters more for SEO than it looks: faster builds
mean tighter deploy cycles, so content fixes reach search engines sooner. On a
4,000-Markdown-file benchmark Eleventy builds in ~1.93s versus ~22.9s for Astro,
~29s for Gatsby, and ~70.6s for Next.js, with a fraction of the node_modules
footprint (34 MB vs Gatsby’s 583 MB).
But — and this is the whole point of the page — none of that buys you SEO
markup. Eleventy generates clean HTML and stops there. Every <title>, meta
description, canonical, sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. entry, and JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. block is something you
implement. The good news is that Eleventy’s data model makes implementing them
once-and-everywhere genuinely pleasant.
The data cascade: your SEO architecture foundation
The single most important concept for scalable Eleventy SEOEleventy (11ty) is a JavaScript-based static site generator that outputs plain HTML with zero client-side JavaScript by default. Eleventy SEO is the practice of explicitly configuring that output — meta tags, canonicals, sitemaps, images, and structured data — because Eleventy generates none of it for you. is the data cascade — the order in which Eleventy resolves a value, lowest priority to highest: Evidence for this claim Eleventy's data cascade resolves data from multiple sources according to a documented priority order. Scope: Eleventy data cascade. Confidence: high · Verified: Eleventy: Data cascade
- Eleventy-supplied global data
- Global data files in
_data/(e.g._data/site.jswithtitle,description,url,author) - Directory data files (e.g.
blog/blog.11tydata.js— give every blog postog:type: article) - Template front matter (per-page overrides)
eleventyComputed(highest — derive values from other data)
In practice:
- Declare your SEO defaults once in
_data/site.js. - Override at the directory level for a content type (all posts get the article
OG type, a
noindexsection getsnoindex, etc.). - Override per page in front matter where a page is special.
- Use
eleventyComputedfor derived values — the canonical being the canonical example:
// _data/eleventyComputed.js (or eleventyComputed in a layout data file)
module.exports = {
canonical: (data) => `${data.site.url}${data.page.url}`,
};Now every page has a correct self-referencing canonical with zero per-page work. That’s the leverage the cascade gives you.
One edge case worth testing rather than assuming: eleventyComputed values can
depend on other computed values (a title that feeds into a computed description,
say), and Eleventy has to resolve that dependency graph before it can render
anything. Straightforward chains work fine, but a computed value that
accidentally depends on itself — directly or through another computed field —
is a circular reference, and ordering issues here fail silently as a missing or
wrong value rather than a loud build error. If you lean on multiple layered
eleventyComputed fields, check the rendered output for the exact values you
expect, not just that the build succeeded. Evidence for this claim Computed Data values can derive from other computed values, so dependency ordering and circular references need testing against the rendered output. Scope: Eleventy eleventyComputed resolution. Confidence: high · Verified: Eleventy: Computed Data
Meta tags in the base layout
Standard architecture is a base layout that owns the <head>, with content
layouts extending it:
_includes/
layouts/
base.njk ← <head> with all SEO meta tags
post.njk ← extends base, adds BlogPosting schema
_data/
site.js ← sitewide SEO defaultsThe meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. you need to implement yourself, at minimum:
<title>— unique per page<meta name="description">— unique per page<link rel="canonical">— Eleventy has no built-in canonical; add it explicitly<meta name="robots">—noindexfor draft/preview pages (and thin paginated pages, if any)- Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears. —
og:title,og:description,og:image,og:url,og:type - Twitter/X Cards —
twitter:card,twitter:title,twitter:description,twitter:image
A minimal Nunjucks <head> pulling from the cascade:
<title>{{ title }} | {{ site.title }}</title>
<meta name="description" content="{{ description or site.description }}">
<link rel="canonical" href="{{ canonical }}">
<meta property="og:title" content="{{ title }}">
<meta property="og:image" content="{{ ogImage or site.defaultImage }}">
<meta name="twitter:card" content="summary_large_image">SEO plugins, compared
You don’t need a plugin — a manual base layout plus the data cascade gives you full control with no dependencies, and many practitioners prefer exactly that. But two plugins are worth knowing:
eleventy-plugin-seo(artstorm) — the most mature and widely used. A single{% seo %}shortcode (Liquid) /{% seo "" %}(Nunjucks) emits title, description, canonical, robots, Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears., Twitter Card, and author from a config block (site title, description, URL, author, Twitter handle, default image). It also handles robot directives on paginated pages, a title divider, and a minimalistic mode. Install:npm install eleventy-plugin-seo.eleventy-plugin-metagen(tannerdolby) — more granular, with named shortcode parameters; generates charset, viewport, title, author, description, generator, OG, Twitter Card, canonical, and CSS/JS tags.
The rule of thumb: plugins add convenience, not capability. Anything they do, you can do in the base layout. Reach for one if you’d rather not maintain the boilerplate.
robots.txt
Eleventy does not auto-generate robots.txt. Two approaches:
1 — Static passthrough (simplest). Drop a robots.txt in your source and copy
it verbatim:
eleventyConfig.addPassthroughCopy("src/robots.txt");2 — Template-generated (for environment-specific output — block everything on staging, allow on production):
---
permalink: /robots.txt
eleventyExcludeFromCollections: true
---
User-agent: *
{% if environment == "production" %}
Allow: /
Sitemap: {{ site.url }}/sitemap.xml
{% else %}
Disallow: /
{% endif %}Remember the universal rule: Disallow blocks crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor., not indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. — and a
noindex tag on a crawl-blocked URL is never seen.
Sitemap generation
Also not built in. The most-control option is a manual template — create
sitemap.xml.njk with permalink: /sitemap.xml and
eleventyExcludeFromCollections: true, loop over collections.all, skip excluded
pages, and emit <loc> / <lastmod> entries:
---
permalink: /sitemap.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for page in collections.all %}
{% if not page.data.excludeFromSitemap %}
<url>
<loc>{{ site.url }}{{ page.url }}</loc>
<lastmod>{{ page.date | dateToISO }}</lastmod>
</url>
{% endif %}
{% endfor %}
</urlset>Or use @quasibit/eleventy-plugin-sitemap (configure with hostname; it also
supports multilingual alternate links). Either way, mark utility pages with
eleventyExcludeFromCollections: true so they don’t leak in.
One thing worth being precise about: looping over collections.all walks
collection membership, not guaranteed output. A template can belong to a
collection and still not emit a URL — most commonly because its permalink
is set to false, or because a data-only file was never meant to render a
page in the first place. Membership in collections.all is not proof an item
belongs in the sitemap; check the rendered <loc> entries against the pages
you actually expect to be crawlable. Evidence for this claim Collection membership does not by itself guarantee that an item emits a URL or belongs in the sitemap. Scope: Eleventy collections and permalink interaction. Confidence: high · Verified: Eleventy: Collections
A correct Nunjucks loop can still inherit a bad hostname or emit a relative location. Validate the built XML itself—the file crawlers receive—not only the Eleventy configuration.
Check the output with my free XML Sitemap Validator Free
- Run the production build and validate its actual sitemap URL or XML.
- Fix malformed XML, relative locations, duplicate entries, and invalid lastmod values at the data or template source.
- Rebuild and confirm excluded utility and noindex pages remain absent.
The validator reports that the loc element is not an absolute URL and says sitemap URLs must be fully qualified rather than relative paths.
Image optimization for Core Web Vitals
A static site’s HTML is fast, but unoptimized images will still tank LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. and CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good..
The fix is @11ty/eleventy-img, and in v3 the recommended path is the
Image Transform plugin, which post-processes every <img> tag in your built
HTML automatically — no per-image shortcode needed:
const { eleventyImageTransformPlugin } = require("@11ty/eleventy-img");
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
formats: ["avif", "webp", "jpeg"],
defaultAttributes: {
loading: "lazy",
decoding: "async",
},
});What that buys you for SEO:
- Auto-stamped
widthandheight→ prevents layout shift (CLS) srcsetwith multiple widths → responsive images<picture>with AVIF + WebP + JPEG fallback- No upscaling
For above-the-fold hero images, override the lazy default so they load eagerly:
<img src="hero.jpg" loading="eager" fetchpriority="high" eleventy:widths="800,1200">Permalinks and clean URLs
Eleventy’s default is clean URLs with a trailing slashA trailing slash is the forward slash (/) at the end of a URL — example.com/page/ versus example.com/page. Except at the bare root domain, the two versions are different URLs to search engines, so you pick one format and enforce it.: about.njk →
_site/about/index.html → /about/. Override in front matter:
permalink: "/blog/{{ title | slugify }}/"Useful flags: permalink: false processes a template for collections but skips
writing it to disk (handy for data-only templates), and dynamicPermalink: false
treats the permalink string literally. The one SEO thing to stay disciplined about:
trailing-slash consistency — mixing /page and /page/ is a duplicate-content
own-goal.
Worth stating plainly because it trips people up: permalink: false suppresses
output entirely — the source file compiles and can still feed collections and
data, but no HTML page is written and no URL exists to crawl. A source file
sitting in your content directory is not proof that a corresponding page shipped;
if a page is missing from search, check the built _site output for the file
before assuming it’s an indexing problem rather than a permalink
one. Evidence for this claim A permalink value of false suppresses page output entirely, so a source file's existence is not proof of a crawlable page. Scope: Eleventy permalink output control. Confidence: high · Verified: Eleventy: Permalinks
Pagination SEO
Eleventy’s paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does. splits a collection across output files. The first page is
/blog/, then /blog/1/, /blog/2/, and so on (customizable via permalink). Each
page in the set needs a unique URL and pagination.alias to expose per-page
data. The SEO decisions:
- Canonicals. Two schools: point every page at page 1 (consolidates signals but buries legitimate deep-page content), or self-referencing canonicals where each page’s canonical is its own URL — Google’s preferred approach in current documentation. I default to self-referencing unless the deeper pages truly have nothing worth indexing.
rel="prev"/rel="next". Google confirmed back in 2019 it no longer uses these as ranking signals. Some still add them to help crawlers understand series structure; if you do, wire them frompagination.href.previous/pagination.href.next.noindexon thin pages. If later pages have insufficient content, addnoindex(via thenoindexfield if you’re usingeleventy-plugin-seo, or manually in the head).
Structured data / JSON-LD
Manual is the most flexible: define a schema object in eleventyComputed or a
directory data file and serialize it in the layout. The cleanest types for a
content site are Organization / WebSite sitewide in the base layout,
BlogPosting / Article per post, BreadcrumbList if you have breadcrumbsBreadcrumbs are a secondary navigation trail (Home > Category > Page) that shows where a page sits in a site's hierarchy. They create internal links that pass PageRank, and when marked up with BreadcrumbList structured data they can drive the path Google shows in desktop search results., and
FAQPage on FAQ sections. @quasibit/eleventy-plugin-schema offers a shortcode
for BlogPosting and WebPage if you’d rather not hand-roll it (it expects ISO
8601 dates, so register a date filter).
Eleventy v2 vs v3 — what changed for SEO
v3 (current stable) is ESM-first: a config file that uses require() now needs
the .cjs extension, or you set "type": "module" in package.json and use
import. CommonJS is still fully supported — just be deliberate about it. The two
SEO-relevant wins:
- ~38% faster cold builds on sites over 500 pages → faster deploys, fresher index.
- The Image Transform plugin is the default path — declarative post-processing
of every
<img>, which makes shipping responsive, CLS-safe images the path of least resistance instead of a per-image chore.
Verify the production artifact, not just the local build
Everything above is about getting the source right — the data cascade, the
layout, the plugins. None of it proves what actually ships. A local _site
build (or eleventy --serve) doesn’t tell you what production serves: the
host and path your deploy platform actually uses, redirectsA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't. it injects, headers
it sets, or whether a CDN/proxy rewrites anything on the way out. Confirm the
installed Eleventy version matches what you’re testing against, then check the
deployed site directly, not just the build output:
- Raw HTML — view-source the live URL, not just
_site/index.html; confirm the title, meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., and canonical are there and correct. - Absolute canonical host — a canonical built from a staging or
localhostsite.urlwill silently ship wrong in production if that value wasn’t overridden per environment. - Sitemap XML — fetch the live
/sitemap.xmland confirm it resolves, uses the production host, and lists the URLs you expect (see the sitemap section above on collection membership not guaranteeing an entry). - Suppressed/utility pages — spot-check that
permalink: falseandeleventyExcludeFromCollections: truepages are actually absent from the live site, not just from your local build. - Assets — CSS, JS, and images referenced in the built HTML resolve on the production host (a relative-vs-absolute path mismatch is easy to miss locally).
- Status codes and redirects — request the live URLs directly and confirm 200s where you expect 200s; a deploy platform’s redirect rules can silently turn a canonical page into a 301 chain that never shows up in a local build.
Third-party plugin installation is not proof of correct output either — it changes what gets generated, not what a specific deploy environment does with it. Treat this as a release-checklist item, not a one-time setup. Evidence for this claim Local build output does not by itself prove production hostnames, redirects, headers, or canonical behavior; the deployed artifact needs its own verification pass. Scope: Eleventy production deployment verification. Confidence: medium · Verified: Patrick Stox: Eleventy SEO
Common Eleventy SEO mistakes
- Assuming Eleventy “handles SEO” — it handles HTML; the SEO markup is all yours.
- Forgetting the canonical entirely (there’s no built-in one).
- Shipping no sitemap because you assumed it was automatic.
- Letting unoptimized images undo the speed advantage.
- Inconsistent trailing slashes creating duplicate URLs.
- Using
Disallowinrobots.txtto try to deindex a page (usenoindexinstead). - Leaving draft/preview pages indexable because no
noindexwas set on the section.
For where Eleventy sits among the other generators, see the Static Site GeneratorsA 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. hub; for the rendering theory behind why static output is low-risk, the parent JavaScript SEOMaking sure search engines can crawl, render, and index content that depends on JavaScript. hub.
AI summary
A condensed take on the Advanced version:
- Eleventy outputs plain HTML at build time with zero client-side JavaScript by default — content is in the first byte, nothing to render. The lowest-risk architecture for indexability, with LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. 99–100 and 0 KB JS homepages common.
- Eleventy generates NO SEO markup. No title, description, canonical, robots, Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears., sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., or JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.. Every one of those is something you implement.
- The data cascade is the scaling architecture: global
_data/site.js→ directory data files → front matter →eleventyComputed. Declare defaults once; derive the canonical witheleventyComputed(${site.url}${page.url}). - Meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. live in a shared base layout — either hand-written, or via
eleventy-plugin-seo(artstorm, the leading plugin: one{% seo %}shortcode for title/description/canonical/robots/OG/Twitter). robots.txtis a passthrough file (addPassthroughCopy) or a template for env-specific output — not auto-generated.- SitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. = a Nunjucks template over
collections.all, or@quasibit/eleventy-plugin-sitemap. Exclude utility pages witheleventyExcludeFromCollections: true. - Images:
@11ty/eleventy-img; v3’s Image Transform plugin post-processes every<img>(autowidth/height→ no CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.,srcset, AVIF/WebP). Override heroes toloading="eager"fetchpriority="high". - PaginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does.: each page a unique URL +
pagination.alias; default to self-referencing canonicals;rel=prev/nextno longer a ranking signal. - Template language doesn’t affect SEO — pick by familiarity. v3 is ESM-first
(
require()needs.cjsor"type":"module") and makes Image Transform the default. - Plugins add convenience, not capability — the manual base-layout approach does everything they do.
- Three edge cases to test, not assume: layered
eleventyComputedvalues can depend on each other and fail silently if ordering breaks;collections.allmembership doesn’t guarantee a URL was actually emitted (check forpermalink: false); and a local_sitebuild proves nothing about production — verify the live canonical host, sitemap, suppressed pages, assets, and status codes directly on the deployed site.
Official documentation
Primary-source documentation — from Eleventy, the SEO plugins, and the search engines.
Eleventy
- Eleventy docs home — the starting point.
- Image plugin (
@11ty/eleventy-img) — Image Transform, responsive images,width/height. - Permalinks — clean URLs,
slugify,permalink: false, trailing slashesA trailing slash is the forward slash (/) at the end of a URL — example.com/page/ versus example.com/page. Except at the bare root domain, the two versions are different URLs to search engines, so you pick one format and enforce it.. - Pagination — splitting collections,
pagination.alias, per-page URLs. - Performance — Eleventy’s build-speed and zero-JS benchmarks.
- Passthrough copy — how to ship a static
robots.txt. - Community plugins — the SEO/sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing./schema plugin indexStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed..
- Eleventy v3 announcement — ESM-first, faster builds, Image Transform.
SEO / sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. / schema plugins
- eleventy-plugin-seo (artstorm) — title, description, canonical, robots, OG, Twitter Card.
- eleventy-plugin-metagen (tannerdolby) — granular meta-tag generation.
- @quasibit/eleventy-plugin-sitemap — sitemap with multilingual alternates.
- @quasibit/eleventy-plugin-schema — JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. (BlogPosting, WebPage).
- Consolidate duplicate URLs (canonicals + pagination) — the canonical and paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does. guidance that informs the SEO decisions above.
Quotes from the source
There are no on-the-record statements from Google or Bing reps specifically about Eleventy — the search engines don’t comment on individual static site generatorsA 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.. The applicable guidance is the general principle that pre-rendered HTML is the lowest-risk thing you can serve, which is exactly what Eleventy outputs.
Google — pre-rendered HTML is simplest
- John Mueller has repeatedly made the general point that while Google can render JavaScript, serving the HTML directly is simpler and faster. The exact wording varies across Search Central office-hours and threads, and no statement specifically referencing Eleventy was foundA 302 (\"Found\") is a temporary redirect: it forwards users to a new URL while telling search engines the original URL should stay in the index. It's a weak canonicalization signal, not the zero-equity dead end of SEO folklore. — so I’m not quoting a verbatim line here. The takeaway holds regardless: Eleventy’s default output is the “just serve the HTML” case.
Eleventy SEO checklist
A pass to confirm your Eleventy site is actually configured for search — because Eleventy did none of it for you:
- SEO defaults declared once in
_data/site.js(title, description,url, author, default OG image). - A base layout owns the
<head>with<title>, meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., OG, and Twitter Card tagsTwitter Card tags (now often called \"X Cards\") are <meta name=\"twitter:...\"> tags in a page's <head> that tell X's link-unfurling system what rich preview to build for a shared URL — image, headline, description, and (for player cards) an embeddable frame. The four card types are summary, summary_large_image, app, and player. Every twitter:* property falls back to its og:* equivalent if missing — except twitter:card itself, which has no fallback and must be set explicitly. They are not a Google or Bing ranking factor. pulling from the cascade. - A canonical is set on every page (Eleventy has none built in) — ideally
derived in
eleventyComputedfromsite.url+page.url. - Draft/preview/section pages that shouldn’t rank carry
noindex(set at the directory data file where possible). - A sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. is generated — template over
collections.allor@quasibit/eleventy-plugin-sitemap— and utility pages are excluded witheleventyExcludeFromCollections: true. -
robots.txtexists (passthrough copy or template), references the sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., and does not block JS/CSS or pages you want indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed.. - Images run through
@11ty/eleventy-img(Image Transform in v3) sowidth,height,srcset, and modern formats are emitted — heroes overridden toloading="eager"fetchpriority="high". - Permalinks are clean and trailing-slash consistent sitewide.
- Paginated sets give each page a unique URL and a self-referencing canonical
(unless deep pages are genuinely thin →
noindex). - Structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. (
Organization/WebSitesitewide,BlogPosting/Articleper post) is emitted in the layout or via a schema plugin. - Content edits trigger a rebuild + redeploy — a static site only reflects its last build.
- The live, deployed site is checked directly — raw HTML, canonical host,
/sitemap.xml, suppressed/utility pages, asset paths, and status codes — not just the local_sitebuild. A local build doesn’t prove what production serves.
The data → template → artifact framework
Eleventy SEOEleventy (11ty) is a JavaScript-based static site generator that outputs plain HTML with zero client-side JavaScript by default. Eleventy SEO is the practice of explicitly configuring that output — meta tags, canonicals, sitemaps, images, and structured data — because Eleventy generates none of it for you. problems usually enter at one of three stages:
- Data: frontmatter and the data cascade define titles, descriptions, canonicals, language, publication state, and structured-data values.
- Template: layouts transform that data into consistent head markup and links.
- Artifact: the generated
_siteHTML, sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., and robots file are what crawlersA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. receive.
Validate in that order when diagnosing the source of a bad value, but validate the built artifact before release. A correct frontmatter field is irrelevant if a layout does not render it or a collection still publishes a draft route.
Eleventy SEO — cheat sheet
Who generates what
| SEO element | Eleventy built-in? | How you get it |
|---|---|---|
| Clean HTML, zero JS | Yes (default) | Nothing to do |
<title> / meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through. | No | Base layout + cascade |
| Canonical | No | eleventyComputed: ${site.url}${page.url} |
robots meta / noindex | No | Front matter / directory data |
| Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears. / Twitter Card | No | Base layout (or eleventy-plugin-seo) |
robots.txt | No | addPassthroughCopy or template |
| SitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. | No | Template over collections.all or @quasibit/...sitemap |
| Responsive images | Plugin | @11ty/eleventy-img (v3 Image Transform) |
| JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. | No | Layout / @quasibit/...schema |
The data cascade (low → high priority)
- Eleventy global data
_data/global files (site.js)- Directory data files (
blog.11tydata.js) - Template front matter
eleventyComputed(derive canonical here)
Plugin shortlist
eleventy-plugin-seo(artstorm) — the leading meta-tag plugin;{% seo %}shortcode.eleventy-plugin-metagen— granular meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored..@quasibit/eleventy-plugin-sitemap— sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. + multilingual alternates.@quasibit/eleventy-plugin-schema— JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal..@11ty/eleventy-img— images.
Fast facts
- Template language (Nunjucks / Liquid / Markdown / WebC / HTML / JS) → no SEO difference; pick by familiarity.
- v3 is ESM-first:
require()config → rename to.cjsor set"type": "module". - Exclude utility pages:
eleventyExcludeFromCollections: true. - PaginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does.: self-referencing canonicals by default;
rel=prev/nextno longer a ranking signal. - Plugins = convenience, not capability.
Scaffold an SEO-ready Eleventy site
A starting point: create the global data file and a base-layout <head> so every
page inherits correct meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. from the cascade.
macOS / Linux
# In your Eleventy project root
mkdir -p src/_data src/_includes/layouts
cat > src/_data/site.js <<'EOF'
module.exports = {
title: "Your Site",
description: "Your default site description.",
url: "https://example.com",
author: "Your Name",
};
EOF
# Derive a self-referencing canonical for every page via the data cascade
cat > src/_data/eleventyComputed.js <<'EOF'
module.exports = {
canonical: (data) => `${data.site.url}${data.page.url}`,
};
EOFWindows (PowerShell)
# In your Eleventy project root
New-Item -ItemType Directory -Force -Path src\_data, src\_includes\layouts | Out-Null
@'
module.exports = {
title: "Your Site",
description: "Your default site description.",
url: "https://example.com",
author: "Your Name",
};
'@ | Set-Content src\_data\site.js
@'
module.exports = {
canonical: (data) => `${data.site.url}${data.page.url}`,
};
'@ | Set-Content src\_data\eleventyComputed.js Confirm your built HTML has the SEO markup
After a build, the content (and your meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored.) should be in the raw HTML — no JS required. Check the output directory directly.
macOS / Linux
# Build, then grep the output for the tags Eleventy does NOT add for you
npx @11ty/eleventy
grep -o '<link rel="canonical"[^>]*>' _site/index.html
grep -o '<title>[^<]*</title>' _site/index.html
# Confirm robots.txt and sitemap.xml actually shipped
ls -l _site/robots.txt _site/sitemap.xmlWindows (PowerShell)
npx @11ty/eleventy
Select-String -Path _site\index.html -Pattern '<link rel="canonical"'
Select-String -Path _site\index.html -Pattern '<title>'
Get-Item _site\robots.txt, _site\sitemap.xmlIf grep/Select-String finds nothing, the markup isn’t there — remember Eleventy
won’t add it on its own.
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.
- Raw vs. Rendered HTML Checker — See what's in your page's initial HTML versus after JavaScript runs — headless-Chrome rendering only when the page actually needs it, a rendering-strategy verdict (SSR / prerendered / CSR / hybrid), ~15 calibrated JavaScript-SEO checks (noindex, canonicals, robots.txt blocking, links, soft 404s), a side-by-side raw-vs-rendered diff, and shareable reports.
Tools for Eleventy SEO
eleventy-plugin-seo(artstorm) — the leading meta-tag plugin: title, description, canonical, robots, OG, and Twitter Card from one{% seo %}shortcode.eleventy-plugin-metagen(tannerdolby) — granular, parameterized meta-tag generation when you want fine control.@11ty/eleventy-img— image optimization; the v3 Image Transform plugin auto-stampswidth/height, buildssrcset, and emits AVIF/WebP.@quasibit/eleventy-plugin-sitemap— sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. generation with multilingual alternate links.@quasibit/eleventy-plugin-schema— JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. (BlogPosting,WebPage).@11ty/eleventy-plugin-rss— RSSAn RSS or Atom feed is an XML file listing a site's most recently published or updated URLs. Search engines accept it as a sitemap-style discovery signal for fresh content — not a replacement for a full XML sitemap./Atom feeds (updated for v3).- LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. / PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. — verify the Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. your static output should be acing.
- Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. URL InspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version. — confirm the rendered HTML matches your built HTML (it should, since there’s nothing to render) and that canonicals resolve.
- Screaming Frog / Ahrefs Site Audit — crawl the built site to catch missing titles, missing canonicals, trailing-slash duplicates, and orphaned output files.
Eleventy SEO anti-patterns
Concrete mistakes I see on real Eleventy sites — every one of them comes from treating Eleventy’s clean HTML output as if it were finished SEO work, when it’s just the starting point.
Assuming Eleventy “handles SEO”
The mistake: Shipping a site on the strength of Eleventy’s zero-JS output and LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. 99–100 scores, without ever adding a title, meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., or canonical.
Why it’s wrong: Eleventy only handles renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. — it builds clean HTML and
stops there. Fast, crawlable HTML with no <title> tag still isn’t going to rank
for anything specific; Google needs the actual on-page signals, and none of them
are generated for you.
What to do instead: Build the SEO meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. into your base layout on day one, before you write a single content page — see the Advanced tab’s “Meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. in the base layout” section. Every page should inherit title, description, and canonical from the data cascade automatically.
Forgetting the canonical entirely
The mistake: Leaving <link rel="canonical"> out of the layout because it
“felt automatic” — it isn’t.
Why it’s wrong: Eleventy has no built-in canonical. Without one, you’re
relying on Google to guess the preferred URL, which matters more than it seems
once trailing-slash variants, ?utm_ params, or paginated pagesPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does. enter the
picture.
What to do instead: Derive it once in eleventyComputed —
canonical: (data) => `${data.site.url}${data.page.url}` — so every page gets
a correct self-referencing canonical with zero per-page effort.
Shipping without a sitemap
The mistake: Assuming a sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. gets generated as part of the build, the same way Eleventy generates the HTML files.
Why it’s wrong: It doesn’t. A missing sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. doesn’t break crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. on a small site, but on anything with more than a handful of pages it slows discovery of new and updated content.
What to do instead: Add a sitemap.xml.njk template that loops over
collections.all, or install @quasibit/eleventy-plugin-sitemap. Either way,
tag utility pages eleventyExcludeFromCollections: true so they don’t leak into
it.
Letting unoptimized images undo the speed advantage
The mistake: Dropping raw JPEGs/PNGs straight into templates because “the site is already fast” thanks to zero JS.
Why it’s wrong: A zero-JS homepage with a 4 MB hero image still fails LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. and
CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. — the JS advantage doesn’t touch image weight or missing width/height
attributes.
What to do instead: Run images through @11ty/eleventy-img (the Image
Transform plugin in v3), which auto-stamps width/height, builds srcset, and
emits AVIF/WebP — then override above-the-fold heroes to
loading="eager" fetchpriority="high" so they don’t get lazy-loaded out of your
LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. window.
Inconsistent trailing slashes
The mistake: Linking to /about in some templates and /about/ in others,
or letting a redirectA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't. layer paper over both existing.
Why it’s wrong: Eleventy’s default output is /about/ (a directory with an
index.html). Mixed internal linksAn internal link is a hyperlink from one page on a website to another page on the same website. Internal links help search engines discover your pages and pass ranking signals (PageRank and anchor-text context) between them. split link equity and crawl budgetThe number of URLs an engine will crawl in a timeframe. across two
URLs that render the same content — a duplicate-content own-goal you created
yourself, not one Eleventy created for you.
What to do instead: Pick one form (Eleventy’s default trailing slashA trailing slash is the forward slash (/) at the end of a URL — example.com/page/ versus example.com/page. Except at the bare root domain, the two versions are different URLs to search engines, so you pick one format and enforce it. is the
path of least resistance) and enforce it in every internal link and in
permalink overrides. Spot-check with a crawl — my
Redirect Checker will surface redirect chainsA → B → C instead of A → C. Each hop loses link equity and adds latency. if a
slash mismatch is being papered over with 301s instead of fixed at the source.
Using Disallow to try to deindex a page
The mistake: Adding a Disallow rule in robots.txt to remove a page that’s
already indexed.
Why it’s wrong: Disallow blocks crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor., not indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed.. If the page is
already indexed, blocking the crawl just means Google can no longer see a
noindex tag you add later — the URL can persist in the index with no snippet.
What to do instead: Add <meta name="robots" content="noindex"> to the page
(via front matter or a directory data file) and let Google crawl it long enough
to see and honor that tag. Only add Disallow for content you never want crawled
in the first place.
Test yourself: Eleventy SEO
Five quick questions on optimizing an Eleventy (11ty) site for search. Pick an answer for each, then check.
Resources worth your time
My related writing
- JavaScript SEO: A Definitive Guide — renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., DOM parityWhether the rendered DOM matches what you expect the raw HTML to become., and why static/prerendered output (Eleventy’s default) is the low-risk end of the spectrum.
- The Beginner’s Guide to Technical SEO — where renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. architecture and on-page configuration fit in the bigger picture.
My speaking
- How Search Works (SlideShare) — my walkthrough of crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor., rendering, indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed., and ranking. (My standing disclaimer applies: “This is my understanding of systems… not going to be 100% complete or accurate.”)
From around the industry
- Eleventy docs — the primary source for everything in this guide.
- Eleventy Image plugin — the v3 Image Transform path to responsive, CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.-safe images.
- eleventy-plugin-seo (artstorm) — the leading meta-tag plugin’s README and config reference.
- @quasibit/eleventy-plugin-sitemap — sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. generation with multilingual alternates.
- Create a sitemap for your Eleventy website (DEV.to) — a clear walkthrough of the manual
collections.alltemplate approach. - Adding robots.txt to an Eleventy site (Mike Fallows) — passthrough vs. environment-specific template generation.
- Add structured data to an Eleventy blog (Maxi Vanov) — manual JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. patterns beyond BlogPosting.
Eleventy SEO
Eleventy (11ty) is a JavaScript-based static site generator that outputs plain HTML with zero client-side JavaScript by default. Eleventy SEO is the practice of explicitly configuring that output — meta tags, canonicals, sitemaps, images, and structured data — because Eleventy generates none of it for you.
Related: Static Site Generator, JavaScript SEO
Eleventy SEO
Eleventy (11ty) is a Node.js static site generatorA 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. that turns templates and Markdown into finished HTML at build time, shipping zero client-side JavaScript by default. That makes it one of the safest possible architectures for indexability: your content is in the raw HTML on the first fetch, so there’s no renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. step for a crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. to wait on. “Eleventy SEO” is the work of configuring that clean output for search — and the key word is configuring, because Eleventy generates no <title>, meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., canonical, sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., or structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. on its own.
The architectural lever is Eleventy’s data cascade: values resolve from global _data/ files (like site.js) up through directory data files, page front matter, and finally eleventyComputed for derived values such as a self-referencing canonical. Declare your SEO defaults once, override them per section, and compute the rest — that’s how you scale correct <head> markup across thousands of pages without hand-editing each one.
Three things make up most of the day-to-day work: meta tagsMeta tags are HTML elements in a page's head that pass metadata about the page to search engines and browsers. For SEO only a few matter — the title element, the meta description, and the robots meta tag — while meta keywords and most others are ignored. in a shared base layout (manually, or via eleventy-plugin-seo), a sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. (a Nunjucks template over collections.all, or @quasibit/eleventy-plugin-sitemap), and a passthrough-copied robots.txt. Add @11ty/eleventy-img — and in v3 its Image Transform plugin — to get responsive, width/height-stamped images that keep Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. clean. The template language you pick (Nunjucks, Liquid, Markdown, WebC, HTML, JavaScript) doesn’t affect SEO; choose by team familiarity.
Related: Static Site Generator, JavaScript 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
Updated Jul 17, 2026.
Editorial summary and recorded change details.Summary
Added three implementation edge cases: eleventyComputed dependency ordering, collections-vs-emitted-URLs, and verifying the production artifact (not just the local build) before treating a page as indexed.
Change details
- Before
No prior coverage of eleventyComputed dependency ordering or circular-reference risk.AftereleventyComputed values can depend on other computed values; ordering issues fail silently, so check rendered output against multiple layered computed fields rather than assuming the build succeeding means the values are correct. - Before
No prior coverage of the gap between collection membership and emitted URLs.AfterCollection membership (looping over collections.all) does not guarantee a URL was emitted — most commonly because permalink: false suppresses output — so sitemap entries should be checked against rendered <loc> values, not source-tree membership. - Before
Verification steps (Scripts lens) only checked the local _site build output, not the deployed production site.AfterAdded a 'Verify the production artifact, not just the local build' section and a matching checklist item covering raw HTML, absolute canonical host, live sitemap.xml, suppressed/utility pages, asset paths, and status codes/redirects on the deployed site.
Full comparison unavailable — no prior snapshot was archived for this revision.