Eleventy The possum is Eleventy’s mascot

Eleventy Documentation

Menu

Navigation Plugin #

A plugin for creating hierarchical navigation in Eleventy projects. Supports breadcrumbs too! Used in production on this very website!

Contents #

Template Compatibility #

Installation #

Available on npm.

npm install @11ty/eleventy-navigation --save-dev

Open up your Eleventy config file (probably .eleventy.js) and use addPlugin:

Filename .eleventy.js
const eleventyNavigationPlugin = require("@11ty/eleventy-navigation");

module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(eleventyNavigationPlugin);
};
You’re only allowed one module.exports in your configuration file, so make sure you only copy the require and the addPlugin lines above!

Read more about Eleventy plugins.

Adding Templates to the Navigation #

Add the eleventyNavigation object to your front matter data (or in a data directory file). Assign a unique string to the key property inside of eleventyNavigation.

Example #

mammals.md #

---
eleventyNavigation:
key: Mammals
---

This gives us:

humans.md #

To nest a template inside of the Mammals template, use parent: Mammals:

---
eleventyNavigation:
key: Humans
parent: Mammals
---

Any templates that do not have parent will be assumed to be at the top level.

Now our navigation structure looks like:

bats.md #

---
eleventyNavigation:
key: Bats
parent: Mammals
---

Now our navigation structure looks like:

You can nest these as deep as you want! Want to put something under Humans or Bats? Use parent: Humans or parent: Bats. If you want to add another root template, leave out parent.

If you want your key and your link text to be different, use the title property:

---
eleventyNavigation:
key: Mammals
title: All of the Mammals
---

Re-Ordering Items #

To ensure that Humans comes first before Bats, use the order property. It can have an arbitrary number. If omitted, order: 0 is the default.

---
eleventyNavigation:
key: Humans
parent: Mammals
order: 1
---
---
eleventyNavigation:
key: Bats
parent: Mammals
order: 2
---

Overriding the URL #

New in Navigation v0.1.4 If you’d like to add a link to an external URL that is not on your local page, create a new template for it and add a url key.

---
eleventyNavigation:
key: Zach’s site
url: https://www.zachleat.com/
permalink: false
---

Use permalink: false to ensure that this meta-template doesn’t create a file in your Eleventy site output.

Rendering the Navigation Bar (Nunjucks-only) #

Currently only Nunjucks support is available for this plugin. More to come!

Just Give Me Some Code #

If you’re tired of reading, just use the following:

{{ collections.all | eleventyNavigation | eleventyNavigationToHtml | safe }}

This is using the Nunjucks filters documented below. If you want more control or need additional customization, keep reading!

Fetch the Structure #

The eleventyNavigation filter returns a sorted array of objects with url and title properties (sorted using order, as noted above). If an entry has nested children, it will also include a children property with an array of similar objects (and those may contain children too, and so on).

Example #

For our documented templates above with the following Nunjucks template:

{% set navPages = collections.all | eleventyNavigation %}
{{ navPages | dump | safe }}
Note that you can also pass any collection into eleventyNavigation. It doesn’t have to be collections.all!

Shows that navPages has the following structure:

[
{
"key": "Mammals",
"url": "/mammals/",
"title": "Mammals",
"children": [
{
"key": "Humans",
"parentKey": "Mammals",
"url": "/humans/",
"title": "Humans"
},
{
"key": "Bats",
"parentKey": "Mammals",
"url": "/bats/",
"title": "Bats"
}
]
}
]

Get just one Branch #

Just show the children of a specific key, pass a key to eleventyNavigation:

{% set navPages = collections.all | eleventyNavigation("Mammals") %}
{{ navPages | dump | safe }}
[
{
"key": "Humans",
"parentKey": "Mammals",
"url": "/humans/",
"title": "Humans"
},
{
"key": "Bats",
"parentKey": "Mammals",
"url": "/bats/",
"title": "Bats"
}
]

You can also render only the parents of a specific key too, to make breadcrumb navigation. Pass a key to eleventyNavigationBreadcrumb like this:

{% set navPages = collections.all | eleventyNavigationBreadcrumb("Bats") %}
{{ navPages | dump | safe }}

And an array of all the parents of the Bats entry will be returned (top-most parent is first):

[
{
"key": "Mammals",
"url": "/mammals/",
"title": "Mammals"
}
]

Render the Structure #

There are a couple of methods for rendering:

  1. Copy and Paste templates give you full control of the markup. Use this if your navigation will have one level/tier of items.
  2. A eleventyNavigationToHtml filter that will render the full navigation tree. Use this if you want to easily scale to an unlimited number of tiers/levels in your navigation.

Copy and Paste Templates #

This template will render a single tier of items (no children).

{% set navPages = collections.all | eleventyNavigation %}
<ul>
{%- for entry in navPages %}
<li{% if entry.url == page.url %} class="my-active-class"{% endif %}>
<a href="{{ entry.url | url }}">{{ entry.title }}</a>
</li>
{%- endfor %}
</ul>

You can use a Nunjucks macro to recursively render list items of any depth but the code isn’t quite as clean:

Nunjucks Macro Code for Rendering Unlimited Child Levels:
{% set navPages = collections.all | eleventyNavigation %}
{% macro renderNavListItem(entry) -%}
<li{% if entry.url == page.url %} class="my-active-class"{% endif %}>
<a href="{{ entry.url | url }}">{{ entry.title }}</a>
{%- if entry.children.length -%}
<ul>
{%- for child in entry.children %}{{ renderNavListItem(child) }}{% endfor -%}
</ul>
{%- endif -%}
</li>
{%- endmacro %}

<ul>
{%- for entry in navPages %}{{ renderNavListItem(entry) }}{%- endfor -%}
</ul>

Render with a Filter #

With the Navigation structure returned from eleventyNavigation or eleventyNavigationBreadcrumb, we can render the navigation HTML. Pass the object to the eleventyNavigationToHtml filter to automatically output the full HTML menu:

{{ collections.all | eleventyNavigation | eleventyNavigationToHtml | safe }}
{{ collections.all | eleventyNavigationBreadcrumb("Bats") | eleventyNavigationToHtml | safe }}
Showing excerpts

You can also use this to display a longer list of navigation items with description text. This is useful for category/index pages. Add excerpt to the eleventyNavigation object.

---
eleventyNavigation:
key: Mammals
excerpt: Vertebrate animals of the class Mammalia.
---

When you render a navigation list, pass showExcerpt: true to the eleventyNavigationToHtml filter, like so:

{{ collections.all | eleventyNavigation("Humans") | eleventyNavigationToHtml({ showExcerpt: true }) | safe }}
Advanced: All Rendering Options for eleventyNavigationToHtml

You can change the HTML elements, classes on the list and list items, and add an additional class for the current page’s navigation entry!

{{ collections.all | eleventyNavigation | eleventyNavigationToHtml({
    listElement: "ul",            // Change the top level tag
    listItemElement: "li",        // Change the item tag

    listClass: "",                // Add a class to the top level
    listItemClass: "",            // Add a class to every item
    listItemHasChildrenClass: "", // Add a class if the item has children
    activeListItemClass: "",      // Add a class to the current page’s item

    anchorClass: "",              // Add a class to the anchor
    activeAnchorClass: "",        // Add a class to the current page’s anchor

    // If matched, `activeListItemClass` and `activeAnchorClass` will be added
    activeKey: "",
    // It’s likely you want to pass in `eleventyNavigation.key` here, e.g.:
    // activeKey: eleventyNavigation.key

    // Show excerpts (if they exist in data, read more above)
    showExcerpt: false
}) | safe }}

These work with eleventyNavigationBreadcrumb | eleventyNavigationToHtml too.

If you find yourself using a lot of these class options, maybe you should use the Advanced: Unlimited Child Levels example above and have full control of your HTML!


Other pages in Plugins: