CARVIEW |
Select Language
HTTP/2 200
access-control-allow-origin: *
age: 0
cache-control: public, max-age=0, must-revalidate
content-disposition: inline; filename="id-attribute"
content-encoding: gzip
content-type: text/html; charset=utf-8
date: Sat, 11 Oct 2025 06:51:49 GMT
etag: W/"94954cb62a1d2ba5dfa9b9daf07079fb"
last-modified: Sat, 11 Oct 2025 06:51:49 GMT
server: Vercel
strict-transport-security: max-age=63072000
x-vercel-cache: HIT
x-vercel-id: bom1::bh9td-1760165508932-ade1c104aa9c
Id Attribute — Eleventy
- Stable
3.1.2
- Canary
4.0.0-alpha.4
- Guide
Guide
- Plugins
- Services
Id Attribute Added in v3.0.0
On this page
The Id Attribute plugin adds id
attributes to headings on your page (<h1>
through <h6>
). This was added to allow deep linking to different sections of blog posts and is compatible with all template languages in Eleventy that output HTML. Related GitHub #3363.
- Existing
id
attributes on your page will not be modified. - If two headings on the page have the same text, we’ll de-duplicate the
id
attributes we assign automatically. - If a heading’s text would result in a conflict with any existing
id
attribute on the page, we’ll de-duplicate the newid
automatically.
This is best paired with a user interface piece to add anchor links to heading elements in an accessible way. A few options:
<heading-anchors>
from David Darnes<heading-anchors>
from Zach Leatherman (only for anchor links as siblings)
Examples
<h1>Welcome to Eleventy</h1>
is transformed into:
<h1 id="welcome-to-eleventy">Welcome to Eleventy</h1>
Ignore a node Added in v3.0.0
Use the eleventy:id-ignore
attribute on a child node to ignore it (only for the purposes of id
attribute generation).
<h1>Welcome to Eleventy<span eleventy:id-ignore> ignore this</span></h1>
is transformed into:
<h1 id="welcome-to-eleventy">Welcome to Eleventy</h1>
Usage
This plugin is bundled with Eleventy and requires no additional package installation (though you do need to opt-in via addPlugin
).
eleventy.config.js
import { IdAttributePlugin } from "@11ty/eleventy";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(IdAttributePlugin);
}
module.exports = async function (eleventyConfig) {
const { IdAttributePlugin } = await import("@11ty/eleventy");
eleventyConfig.addPlugin(IdAttributePlugin);
}
With options
eleventy.config.js
import { IdAttributePlugin } from "@11ty/eleventy";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(IdAttributePlugin, {
selector: "h1,h2,h3,h4,h5,h6", // default
// swaps html entities (like &) to their counterparts before slugify-ing
decodeEntities: true,
// check for duplicate `id` attributes in application code?
checkDuplicates: "error", // `false` to disable
// by default we use Eleventy’s built-in `slugify` filter:
slugify: eleventyConfig.getFilter("slugify"),
filter: function({ page }) {
if(page.inputPath.endsWith("test-skipped.html")) {
return false; // skip
}
return true;
}
});
}
module.exports = async function (eleventyConfig) {
const { IdAttributePlugin } = await import("@11ty/eleventy");
eleventyConfig.addPlugin(IdAttributePlugin, {
selector: "h1,h2,h3,h4,h5,h6", // default
// swaps html entities (like &) to their counterparts before slugify-ing
decodeEntities: true,
// check for duplicate `id` attributes in application code?
checkDuplicates: "error", // `false` to disable
// by default we use Eleventy’s built-in `slugify` filter:
slugify: eleventyConfig.getFilter("slugify"),
filter: function({ page }) {
if(page.inputPath.endsWith("test-skipped.html")) {
return false; // skip
}
return true;
}
});
}