DEV Community

Cover image for Let's Learn 11ty Part 4: Data in Eleventy
James 'Dante' Midzi
James 'Dante' Midzi

Posted on • Updated on

Let's Learn 11ty Part 4: Data in Eleventy

Last time we did quite a bit of work on our site to make it come together. At this point, I think it's time we talk about Data in Eleventy.

But first, let's improve the flow on our blog posts by adding next and previous post links to the bottom of our posts.

Adding Next/Previous Post Links

Let's start by adding a third post in our blog folder.
Now we are going to implement what is called layout chaining in Eleventy.

We will start by creating a partial for our pagination. Yes, this is pagination (I have an article planned for this concept, but later).

In _includes/partials create a paginate.njk and place this in it:

 {% set previousPost = | getPreviousCollectionItem(page) %}
 {% set nextPost = | getNextCollectionItem(page) %}
 {% if previousPost %}Previous: <a href="{{ previousPost.url }}">{{ }}</a>{% endif %}
 {% if nextPost %}Next: <a href="{{ nextPost.url }}">{{ }}</a>{% endif %}
Enter fullscreen mode Exit fullscreen mode

In the snippet above, we introduce a new feature of Eleventy - set . Set is used when we want to create a specialised piece of content that is not present in our site.

  • We create a previousPost and nextPost that relates to our post collection
  • Then we make an if statement to check if these exist in our collection.
    • If they do, output the URL of that post otherwise display nothing.

Then in _layouts make a new file called blogLayout.njk and place this in it:

 layout: base
 {{content| safe}}
 {% include "partials/_paginate.njk" %}
 <a href="/blog">Blog Home</a>
Enter fullscreen mode Exit fullscreen mode

Next, we change the layout key in the frontmatter of our post files to this:

 title: First Post
 layout: blogLayout # modify this line
 tags: post
Enter fullscreen mode Exit fullscreen mode

We are switching the layout we use for posts to the one we just made - this is where we've chained layouts. A post uses the blogLayout which uses the base layout.

Previous and Next Post
I've added more styles to make the page look better


Permalinks are another feature of Eleventy(that I forgot 😁) that allows you to determine what a pages' URL becomes

Say for example you chose to place your page files in a pages directory, but didn't want them to be output as [your_site_url]/pages/about_page but as [your_site_url]/about_page, this is where permalinks come in:

 # src/pages/
 layout: base
 title: About
 tags: page
 permalink: /about/
Enter fullscreen mode Exit fullscreen mode

Eleventy Data Cascade

Eleventy'a data cascade refers to the order in which Eleventy renders site data.

The closer (more specific) data is to content, the higher priority it has

That cascade, in order of priority is:

  1. Computed Data - data derived from other data
  2. Frontmatter Template Data - in a single template
  3. Template Data Files - Applied to one file
  4. Layout Frontmatter Data - Applied to all templates that use that layout.
  5. Directory Data Files
  6. Configuration Global Data
  7. Global Data Files

When we make use of this data, it is usually in reverse order, with global data first, then config data and so on...

When I say template, it just means any file with content

Currently we have used two type two kinds of Eleventy data

  • Layout Template Data - when we rendered the navigation and post list
  • Front Matter Data - the title frontmatter in our pages

Let's make use of some of the other types of data

Global Data Files

If you recall when we set up our project, we did this in our .eleventy.js

  return {
     dir: {
       input: "src",
       data: "_data",  //take note of this
       includes: "_includes",
       layouts: "_layouts",
Enter fullscreen mode Exit fullscreen mode

Global data refers to files we place in the _data folder. In most instances we use global data for things we want site wide, for example the site title and description.

Let's make a global data file to house some of our site data.

Make an _data folder in src and in in a site.json and place this in it

   "title": "James Midzi",
   "description": "A site to showcase Eleventy features by building a site.",
   "keywords": "eleventy, 11ty, css, ssg"
Enter fullscreen mode Exit fullscreen mode

This will give us some global configuration options that will be used on the site.

Now, we will modify the head tag in base.njk to

<title>{{site.title}}{% if title %} - {{title}} {% endif %} </title>
    <meta name="description" content="
      {% if description %}
      {% else %}
      {% endif %}
Enter fullscreen mode Exit fullscreen mode

Above, we are running checks to see if the title and description data exists in our pages (templates), if it does render it. Otherwise, use the data in site.json (global data)

The final head tag should look like this:

    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <!-- stylesheet -->
   <!-- <link rel="stylesheet" href="{{ '/assets/css/style.css' | url }}"> -->
   <link rel="stylesheet" href="{{ '/assets/css/tailwind.css' | url }}">

   <!-- Meta -->
    <title>{{}}{% if title %} - {{title}} {% endif %} </title>
    <meta name="description" content="
      {% if description %}
      {% else %}
      {% endif %}
Enter fullscreen mode Exit fullscreen mode

NOTE: our data files can be json or javascript

The changes we have made will help with our site SEO

Config Global Data

I at present do not know the correct way to apply global config data. I will continue researching and asking questions. I will revisit this part when I have a better understanding of this.

Directory Data Files

These set data on a folder level, and they must be named the same as the folder they are in.

They apply data in it to everything contained in that folder.

Let's take a look at our posts. We are currently setting this in each post's frontmatter

 title: First Post
 layout: blogLayout
 tags: post
Enter fullscreen mode Exit fullscreen mode

While this might be fine now, imagine if we added more posts. We would have to copy this frontmatter pattern into each of them.

A Data Directory File helps us with this repetition problem. Let's do that, shall we?

In the src/blog folder, create a blog.json file and place this in it

   "layout": "blogLayout",
   "tags": "post"
Enter fullscreen mode Exit fullscreen mode

With this done, we can remove the layout and tags from our post files so they now look like this:

title: First Post
description: This is my first post
Enter fullscreen mode Exit fullscreen mode

with data direcory file

Checking our site, we can see that everything is still working. Now, if we add more posts, we only have to be concerned with the title and description.

Template Data Files

This data is applied on a file(template level) where if you had a you can have data that applies only to it in a about.11tydata.js or about.11tydata.json

Computed Data

For the life of me, I can't figure out how one would go about using computed data. But I believe someone in the Discord will be able to help. As with Config Data, I will return.

An Intermission

That was a lot right? Yeah, I know. But at least we have now covered some of the more involved parts of Eleventy and how you can make them work for you.


This has been one of the more longer tutorials of this series. I hope you all stayed till the end because understanding how data works will greatly improve how you build your Elevnety site.

In this article we:

  • Added pagination to our posts
  • Added a data file to manage site metadata (we will build on it later)
  • Added a directory data file to simplify the creation of new posts.
  • Talked about the data cascade in Eleventy.

As always:

Thank you for reading, let's connect!

Thank you for visiting this little corner of mine. Let's connect on Twitter, Polywork and LinkedIn

Top comments (3)

klemcijada profile image
Klemen Červ • Edited

I had a problem with the layout chaining, the front matter was not being evaluated. It seems it doesn't like indentation, there are some spaces in front of some code chunks in the tutorial. So the issue was me copying the code instead of typing it out by myself. Just a heads up :)

Thank you James for these writings on 11ty!

psypher1 profile image
James 'Dante' Midzi

Thank you for going through the series!

Oh, that's interesting... it's probably because I copied directly from my editor and pasted without stripping the formatting - thank you for the catch :-)

rwdev profile image

Just a heads up to anyone following this and is using Liquid instead of Nunjucks (and to save you a bit of Googling):

Liquid does not have a set tag, it's called assign. And it does not allow parenthesis, so for the Next / Previous posts links you'll have to replace the code with the following:

{% assign previousPost = | getPreviousCollectionItem: page %}
{% assign nextPost = | getNextCollectionItem: page %}
Enter fullscreen mode Exit fullscreen mode