Navigation Plugin #
A plugin for creating hierarchical navigation in Eleventy projects. Supports breadcrumbs too! Used in production on this very website!
- This documentation is for
eleventy-navigation
v0.1.3
. - GitHub.
Contents #
Template Compatibility #
- Any template language can add to navigation.
- Nunjucks is required for rendering the navigation menu.
Installation #
Available on npm.
npm install @11ty/eleventy-navigation --save-dev
Open up your Eleventy config file (probably .eleventy.js
) and use addPlugin
:
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:
- Mammals
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:
- Mammals
- Humans
bats.md #
---
eleventyNavigation:
key: Bats
parent: Mammals
---
Now our navigation structure looks like:
- Mammals
- Humans
- Bats
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
.
Use alternate text for the navigation link #
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
---
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 }}
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"
}
]
Breadcrumbs #
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:
- Copy and Paste templates give you full control of the markup. Use this if your navigation will have one level/tier of items.
- 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!