Eleventy The possum is Eleventy’s mascot

Eleventy Documentation

This is an older version of Eleventy. Go to the newest Eleventy docs (current path: /docs/plugins/navigation/) or the full release history.
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);
};

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: