Home Web Development Eleventy By Example

Eleventy By Example

By Bryan Robinson
ai-assist-svg-icon Book + AI Assistant
eBook + AI Assistant $21.99 $14.99
Print $26.99
Subscription $15.99 $10 p/m for three months
ai-assist-svg-icon NEW: AI Assistant (beta) Available with eBook, Print, and Subscription.
ai-assist-svg-icon NEW: AI Assistant (beta) Available with eBook, Print, and Subscription. $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime! ai-assist-svg-icon NEW: AI Assistant (beta) Available with eBook, Print, and Subscription.
What do you get with a Packt Subscription?
Gain access to our AI Assistant (beta) for an exclusive selection of 500 books, available during your subscription period. Enjoy a personalized, interactive, and narrative experience to engage with the book content on a deeper level.
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
Gain access to our AI Assistant (beta) for an exclusive selection of 500 books, available during your subscription period. Enjoy a personalized, interactive, and narrative experience to engage with the book content on a deeper level.
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Along with your eBook purchase, enjoy AI Assistant (beta) access in our online reader for a personalized, interactive reading experience.
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
ai-assist-svg-icon NEW: AI Assistant (beta) Available with eBook, Print, and Subscription. ai-assist-svg-icon NEW: AI Assistant (beta) Available with eBook, Print, and Subscription. BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime! ai-assist-svg-icon NEW: AI Assistant (beta) Available with eBook, Print, and Subscription.
eBook + AI Assistant $21.99 $14.99
Print $26.99
Subscription $15.99 $10 p/m for three months
What do you get with a Packt Subscription?
Gain access to our AI Assistant (beta) for an exclusive selection of 500 books, available during your subscription period. Enjoy a personalized, interactive, and narrative experience to engage with the book content on a deeper level.
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
Gain access to our AI Assistant (beta) for an exclusive selection of 500 books, available during your subscription period. Enjoy a personalized, interactive, and narrative experience to engage with the book content on a deeper level.
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Along with your eBook purchase, enjoy AI Assistant (beta) access in our online reader for a personalized, interactive reading experience.
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Chapter 2: Adding Data to Your 11ty Website
About this book
11ty is the dark horse of the Jamstack world, offering unparalleled flexibility and performance that gives it an edge against other static site generators such as Jekyll and Hugo. With it, developers can leverage the complete Node ecosystem and create blazing-fast, static-first websites that can be deployed from a content delivery network or a simple server. This book will teach you how to set up, customize, and make the most of 11ty in no time. Eleventy by Example helps you uncover everything you need to create your first 11ty website before diving into making more complex sites and extending 11ty’s base functionality with custom short codes, plugins, and content types. Over the course of 5 interactive projects, you’ll learn how to build basic websites, blogs, media sites, and static sites that will respond to user input without the need for a server. With these, you’ll learn basic 11ty skills such as templates, collections, and data use, along with advanced skills such as plugin creation, image manipulation, working with a headless CMS, and the use of the powerful 11ty Serverless plugin. By the end of this book, you’ll be well-equipped to leverage the capabilities of 11ty by implementing best practices and reusable techniques that can be applied across multiple projects, reducing the website launch time.
Publication date:
May 2023
Publisher
Packt
Pages
198
ISBN
9781804610497

 

Adding Data to Your 11ty Website

In the last chapter, we set up the basics of an 11ty website. In this chapter, we’ll give it superpowers by exploring the many ways that 11ty allows us to add static and dynamic data to our templates, layouts, and pages.

At the heart of any website is data. Whether that’s content, structured data, or third-party information, getting data onto a page is the most important thing any site generator can do. By adding a data layer to the simple website we built in Chapter 1, we’ll see how the flexibility of 11ty extends to data via its Data Cascade feature, and how this provides us with great power for customizing our various layouts, includes, and pages.

In this chapter, we’ll be covering the following topics:

  • Understanding the 11ty Data Cascade
  • Adding data for each page
  • Adding data to external files
  • Adding global data
 

Technical requirements

The code in this chapter builds on the site that we built in Chapter 1. If you didn’t follow along with that chapter, you can find the complete code in the companion GitHub repository: https://github.com/PacktPublishing/Eleventy-by-Example/tree/main/project-1/chapter-2/start.

 

Understanding the 11ty Data Cascade

Before we can dive into the code, we need to discuss how 11ty handles data.

Much like 11ty’s template options, the way 11ty handles data is also very flexible. With that flexibility comes some extra complexity. 11ty allows you to add data at every layer of your project, in page files, layout files, directories, and globally. Based on that, there’s a specific order and precedence in which it ingests the data along the way. This is called the 11ty Data Cascade. Let’s take a look at data sources in order of highest priority to lowest priority. At each step along the way, data can either be merged or overridden.

Lowest-priority, most generic data—such as a global data file—is the first to be computed. This gives us access to that data to be used or mutated by higher-priority, more specific data—such as computed data.

Computed data

While we won’t cover computed data in this chapter, it is the data with the highest priority and the last to run. 11ty computed data is run at the page or template level and has access to various data variables that are already available. It can be used for things such as generating page permalinks, working with the navigational structure, or anything else that requires additional data to be already compiled.

Page frontmatter

We covered the frontmatter a little in Chapter 1 as a way of declaring what layout our pages will use. The frontmatter can also be used to add page-specific data to each page template. Examples include titles, publish dates, descriptions, and data required for the page, such as banner content and promotional space content.

Template data files

Template data files are specific files of JSON or JavaScript data that are paired by name with specific pages. This can make for a better developer experience than just using frontmatter data on an individual page. These data files need filenames that match the template name.

Directory data files

Directory data is shared between multiple pages in a specific directory in your project. This can be used to share things such as layouts and parent IDs between various pages within a section of your site. For deeply nested directories, the data from parent directories is also available within the deeply nested template. This data file needs to match the directory it lives within.

Layout frontmatter

Layouts in 11ty are just chained templates. So, any page or layout can have frontmatter. In the context of a layout, the frontmatter is the same as a page, but a page can override its layout. The layout frontmatter can be helpful for creating template inheritance features to show different data on each section of your site based on the layout.

Configuration API global data

You used the 11ty configuration API to set up your 11ty instance in Chapter 1, but it can also be used to store global data. The addGlobalData method on the configuration object can be used to create regular global data but is best used to create data source plugins for various APIs and add data programmatically to the 11ty data stack.

Global data files

The lowest-priority data is global data. These files are typically JavaScript or JSON files and are stored by default in the src directory of your project. This data is accessible to any template, layout, include, or page in your project. These files are great for data that should be fetched or created once and used in multiple places.

With the basics in hand, let’s begin by making our templates and includes more dynamic. To start, we’ll add individual page data that can be used in our base template, as well as in includes.

 

Adding data for each page

The home page of our website has a large banner at the top. It would be great to be able to reuse the HTML from that banner on the About page as well. If we move the HTML from the home page into an include and use it in both places, the headline and banner text will be identical. That’s where page data comes in.

Adding variable data to the home page

In the index.html file, we already have the YAML frontmatter that we used when setting up the layout in Chapter 1. This is where the page data lives.

To add additional variables, we can follow the same format as we use for the layout variable and add a new line to the frontmatter. This time, add a title and bannerContent variable. Each of these will contain a string that will be used by the templates:

---
layout: "layouts/base.html"
title: "This is my homepage"
bannerContent: "This is my banner content"
---

These two new variables are accessible inside of the page, the layout controlling the page, and the includes that are included on the page.

To start, replace the static HTML in index.html with Liquid variable expressions, as we discussed in Chapter 1 for the {{ content }} variable. Any variable entered into the frontmatter of a page is accessible by the key given to it:

<section class="banner">
  <h1>{{ title }}</h1>
  <p>{{ bannerContent }}</p>
</section>

Now that we have the content as data in our page, we can move the HTML from the page into an include placed in the base layout.

Copy the markup from the home page and move it into a new file named banner.html in the src/_templates/includes directory. Your directory structure should now be updated.

Figure 2.1 – banner.html should now be in the includes directory

Figure 2.1 – banner.html should now be in the includes directory

No noticeable changes should happen on the home page. Once the file is added, we can include banner.html in the base.html layout file with the following code:

{% include "includes/banner.html" %}

At this point, we can modify the About page to handle the same data.

This HTML is now on every page using the base.html layout. That means we have access to it on the About page as well as the home page. Right now, there’s no data, so the h1 and p elements will appear on the page but will be empty. We’ll update the About page with the proper data in a moment, but let’s first add protections against pages that don’t have this content.

Writing conditionals to display no markup if data doesn’t exist

To protect our HTML, we need to add conditionals to our include. We need to think about three different cases:

  • When there is no title or bannerContent, don’t display the entire section
  • When there is no title, don’t display h1, but display the bannerContent paragraph
  • When there is no bannerContent, display h1, but not the bannerContent paragraph

Most conditional operators you may be used to from other languages are also available in Liquid (and Nunjucks). For the first case, we need to check whether either title or bannerContent exists; for the second case, we need to check whether title exists; and for the third case, we need to check whether bannerContent exists:

{% if title or bannerContent %}
  <section class="banner">
    {% if title %}<h1>{{ title }}</h1>{% endif %}
    {% if bannerContent %}<p>{{ bannerContent }}</p>
      {% endif %}
  </section>
{% endif %}

This adds all the protections we need. Now, the About page no longer has a blank banner at the top. But we do need a banner, so let’s update the About page.

Adding About page data and content

When we created the About page in Chapter 1, we set it up to use base.html like the home page. Because it’s using that layout, we now have access to the same banner include if we provide the same data structure to the page frontmatter. By adding the same data to the About page’s frontmatter, we can have a custom banner:

---
layout: "layouts/base.html"
title: "About us"
bannerContent: "This is a little paragraph about the
  company."
---

The page should now display a banner across the top, but let’s take this one step further. While it makes sense to keep the home page as an HTML document, authoring long-form content isn’t easy in HTML. While the frontmatter may be structured data, we can also use other types of content data in our pages. Let’s convert the page from HTML to Markdown—a more ergonomic way of authoring structured content in code.

To do this, change the file extension from .html to .md. By default, 11ty will read that as a Markdown document and use Markdown and Liquid to generate HTML from it. This means that all valid HTML and Liquid tags work in the page’s code, as well as standard Markdown syntax:

---
layout: "layouts/base.html"
title: "About us"
bannerContent: "This is a little paragraph about the
  company."
---
## The page content can go here
It can use any markdown, since we're in a markdown page. Like [an anchor](https://packtpub.com) or **bold text**.
* Or an unordered list
* With some items
1. Or an ordered list
1. With some items (no need to have different numbers in a
  Markdown ordered list)

Now we have structured page data and our page content is transformed into data, but let’s take this a step further and create unique styling for the home page banner compared to the About page banner.

Typically, a home page banner will be styled with more padding and take up more space compared to an interior page, where getting users to the content faster is important.

To accomplish this, we need to dynamically add a class to the home page banner to modify its styles. Let’s add a pageId variable to the frontmatter of the home and About pages. For the home page, set it to home, and for About, set it to about.

Then, we can modify the banner include to add a class when pageId is home. We can do this with another Liquid conditional, this time checking the value of pageId rather than just whether it exists:

{% if title or bannerContent %}
  <section class="banner{% if pageId == "home" %} banner—
    home{% endif %}">
    {% if title %}<h1>{{ title }}</h1>{% endif %}
    {% if bannerContent %}<p>{{ bannerContent }}</p>
      {% endif %}
  </section>
{% endif %}

We add banner--home as a class in the section when it matches home; otherwise, it’s just banner. This matches the class in the CSS file to set a min-height on the banner. If you want to take this a step further, you could use the pageId value itself and set styles for every page ID in your CSS.

Whitespace

Note the whitespace choices in the class list. There’s no space between banner and the conditional and there’s a space preceding banner--home. This is intentional and will render the HTML with no awkward whitespace. If you don’t mind extra spaces in your source code, you can choose to accommodate that space before the conditional. I care more about the rendered markup than perhaps I should.

We can also use pageId to set an active state on our navigation to show users what section in the navigation the current page is in.

To do that, open the navigation.html include we created in Chapter 1. For each navigation list item, we can create a conditional to check which pageId is in use and display an active class for the proper navigation item:

<nav>
    <ul>
        <li {% if pageId == "home" %}class="active"
          {% endif %}><a href="/">Home</a></li>
        <li {% if pageId == "about" %}class="active"
          {% endif %}><a href="/about">About</a></li>
    </ul>
</nav>

Now that we have a working navigation and About section, let’s expand on the home page by adding data for a standard web design pattern—the triptych.

Adding an array to the frontmatter and looping through it in a page

We’ve drastically simplified the About page and applied reusable components between pages. The home page still has a section that has a lot of repeating HTML. The triptych area—three identically styled cards next to each other—has the same markup, but different content for each card.

We could put three sets of uniquely keyed data in the home page frontmatter and write the HTML around that, but it would be better to write the markup once and allow the data to be looped through and render the repeated HTML. To do this, we can use a YAML array and a Liquid for loop.

Add the following to the frontmatter of index.html:

triptychs:
  - headline: "Triptych 1"
    content: "Triptych 1 content"
  - headline: "Triptych 2"
    content: "Triptych 2 content"
  - headline: "Triptych 3"
    content: "Triptych 3 content"

Whitespace part 2

Note the whitespace again. YAML is whitespace sensitive, so the exact spacing is important.

If we add a dash before the start of each first property, YAML will interpret this as an array. The keys in the array should line up and the next dash will denote the next item in the array.

To use this data, we'll use another built-in Liquid template tag: {% for %}.

The for tag is a paired shortcode that will loop through an array. It follows this syntax: {% for <variable-to-store-data> in <array-variable> %}. This allows you to format your code in efficient ways:

<section class="triptych">
  {% for triptych in triptychs %}
  <div class="triptych__item">
    <h2>{{ triptych.headline }}</h2>
    <p>{{ triptych.content }}</p>
  </div>
  {% endfor %}
</section>

Let’s make this even more reusable. Right now, this works in this space, but what if we want to have this style of item elsewhere? Let’s refactor it into an include and transform the data we pass into it so that it works with any data to make a new card. Make a new include named card.html. Bring the entire triptych__item into the new include and reference the include from within the for loop:

<section class="triptych">
  {% for triptych in triptychs %}
    {% include "includes/card.html" %}
  {% endfor %}
</section>

This works and might feel like we’re done, but it will only work with data under the triptych key. To fix this, we can pass specific data under specific keys to the include.

We can extend the previous code snippet to rename each variable as we pass it into the include. We set the headline variable to triptych.headline and the content variable to triptych.content to give it the proper format for the new include. This way, anywhere we want to use the include, we just pass the correct data to the correct key.

The new for loop looks as follows:

<section class="triptych">
  {% for triptych in triptychs %}
    {% include "includes/card.html", headline:
      triptych.headline, content: triptych.content %}
  {% endfor %}
</section>

The new include looks as follows:

<div class="triptych__item">
  <h2>{{ headline }}</h2>
  <p>{{ content }}</p>
</div>

The frontmatter is a great place to work with simple data, but as you may have noticed, it starts to get very complicated with just a little extra data. Let’s make the developer experience a little better by moving the data to an external file.

 

Adding data to external files

Data in the frontmatter can be helpful for writing content close to the page, but sometimes having discreet data files can keep the page files much cleaner. We can move data from the frontmatter to specific files along the 11ty Data Cascade.

Creating a template data file for the home page triptych

Let’s start by moving the triptych data from the frontmatter into a data file for the home page. To create a template data file, we create a file with a specific naming pattern. For JSON files, we use <template-name>.json or <template-name>.11tydata.json. For JavaScript data files—which we’ll dive into later in this chapter—the 11tydata string is required for template or directory data.

For this example, we’ll use a JSON file to store the array we need for the home page. Create a file in the src directory named index.json. If you’re currently running 11ty, the terminal will show an error that the JSON is not formatted properly. That’s because 11ty already recognizes the data file, but it’s blank, and therefore incorrectly formatted for JSON.

For the triptych, insert the following JSON into the file you just created:

{
    "triptychs": [
        {
            "headline": "Triptych 1",
            "content": "Triptych 1 content!"
        },
        {
            "headline": "Triptych 2",
            "content": "Triptych 2 content!"
        },
        {
            "headline": "Triptych 3",
            "content": "Triptych 3 content!"
        }
    ]
}

Once this is saved, the browser will refresh, and now we have six triptych items! When possible, 11ty will attempt to merge data from various sources instead of overriding it. So, for the triptych key, it knows that there are two arrays and adds them together. Note the template data file’s array content comes first. That’s because the template data is added first in the data cascade and then the frontmatter is added. If you insert a title string into the template data file, you won’t see the title change. That’s because the frontmatter takes precedence in the cascade and strings won’t be merged like arrays.

The array merge is a nice feature, but we don’t want six items. For now, delete the frontmatter from the home page. The home page file is now much more readable and more data can be added to the data file and not overwhelm the page template. The same could be done for data for the About page as well. Follow the naming convention with about.json and add any data you’d like.

If we had multiple pages with data files for each page, that would be difficult to manage. To fix this, we can use directory data files.

Moving the About page to its own directory

11ty allows for a deeper directory structure in the project to keep things neat but also adds additional power to pages that should be grouped together.

To start, create a new directory in the src directory. Name this directory about and move about.json and about.md into it. 11ty will recognize that the about.md file is meant to be the root of that directory and automatically uses that file for the /about/ route on our site. It will also accept index.md as the main file for this route. To keep things obvious, let’s change about.md to the index.md filename.

A note of caution on filenaming

While 11ty allows the use of the about.md filename, it’s often better to go with index.md for this file. By using about.json, we’re telling 11ty to treat the data in about.json as directory data. If we want template data for the About page, we need it to be index.md with index.json as the data file. For this example, this is unnecessary, but it can be important for bigger projects with a larger data structure.

The about.json file can now provide data for any page within the about directory. Let’s add a History page to our About section.

Create a new file in the about directory and name it history.md.

Add some Markdown to the file and save it. When 11ty rebuilds the site, there will now be a route at /about/history/. This page will only display the Markdown you added to the file. In order to take advantage of the layout and other data, the layout path needs to be added. Instead of recreating reusable data, let’s move certain data to the directory data file. Both the layout data and the pageId data may need to be used by any page in the About section, so let’s add those two pieces of data to the about.json file:

{
    "layout": "layouts/base.html",
    "pageId": "about"
}

Once that’s saved, the page will have the header and footer, as well as the correct navigation item selected. We’re still missing a banner. To add the banner, create the frontmatter in the History page. This ensures that the banner content is unique for each page:

---
title: "History"
bannerContent: "This is a little paragraph to start talking
  about the history of the company."
---
## The page content can go here
It can use any markdown, since we're in a markdown page. Like [an anchor](https://packtpub.com) or **bold text**.

We’ll dive deeper into directory data when creating a blog collection in Chapter 4.

While this is all good for a set of unique data, it’s often important to share data across the entire site—footers, metadata, and more are often powered by global data. Let’s add some data for all of our pages and templates.

 

Adding global data

Page and template data are great when adding unique data. Directory data is great for sharing data between specific pages. But what if you need to add data to every page? That’s where global data files come in.

To use global data files, we need a directory to store them. Inside the src directory, create a new directory named _data—11ty’s default data directory name. This can store multiple data files. Each file in this directory will give access to its data to any template using a key with the same name as its filename. For our site, let’s add some general site information and add the ability to access it from multiple files.

Create a new file in the _data directory named site.json. This file will have general information about the site, including the site name and the copyright date to be displayed in the footer:

{
   "name": "My Awesome Site",
   "copyright": "2022"
}

With this data in hand, let’s insert it into our templates.

In the site head—located in src/_templates/includes/header.html—we’ll update the title. Currently, it’s just a hardcoded string. Let’s have it pull the page title and the site title:

<title>{{ title }} – {{ site.name }}</title>

In the footer—located in src/_templates/includes/footer.html—let’s adjust the copyright information:

<footer class="footer">
    <p>&copy; {{ site.name }} {{ site.copyright }}</p>
</footer>

Now the information is all changeable from one location whenever it needs to be updated.

Adding dynamic global data

Keen readers will have noticed something slightly off with that last section. The copyright date is already out of date. I’m writing this book at the end of 2022, but you’re not reading it then. To change this for the site, we would need to go into our footer each year and change the date. However, 11ty’s JavaScript data files can update this for us.

While JSON can be a handy format for simple data, it can be extended by writing it as JavaScript. Any code written in a JavaScript data file will be run each time the site builds. If we update the site’s copyright data with a script, it means the site will just need to be rebuilt each year, and no content change will be needed.

What do you mean “built”?

11ty has no client-side JavaScript code generated by default. Any JavaScript we write for data files will run when the HTML for the site is generated by 11ty—often referred to as “at build time.” This happens when the default eleventy command is run in the terminal. This usually happens in your hosting provider, but can be run locally as well.

To start the process, let’s convert site.json over to site.js. This will immediately break the running of the terminal process. This is not a proper JavaScript module export.

Since the file is now a JavaScript file, it needs to be refactored to export the object instead of just containing the JSON object.

module.exports = {
   "name": "My Awesome Site",
   "copyright": "2022"
}

When you run 11ty again, it should work as it did before.

Now that this is a JavaScript file, any Node.js JavaScript can be run from within the file. For our use, we can use the built-in Date functionality in JavaScript to get the current date and save the year string as a globally accessible variable named copyright:

module.exports = {
   "name": "My Awesome Site",
   "copyright": new Date().getFullYear()
}

Now, the copyright date in the footer should display the current year instead of 2022. This is a simple example of using dynamic data in 11ty, but anything Node.js can do, 11ty’s JavaScript data files can also do. This includes things such as reading files from the filesystem, querying APIs, and transforming data.

 

Summary

In this chapter, we covered multiple ways of adding static and dynamic data to your 11ty site. After reviewing the structure of the 11ty Data Cascade, we added multiple types of data to our basic site project.

We started by adding page-specific data by using the frontmatter in each of our pages. We used this data to display different content for the banner on the home page and the About page with a singular include. We set up more differences in our layout by assigning a pageId inside the frontmatter to display different banner styles and active states in the navigation. We created a reusable card component to be used with data from the home page and renamed it for the include so that it could be used in multiple locations.

Once we had that, we needed to clean up the display of the data in the templates. We used template data files to accomplish this, moving the triptych data to a separate data file with the same name as the page.

We created a new directory for the About section to use directory data files to share data between the About page and the new History page, which is a subpage of About.

Finally, we added global data to display certain information in multiple templates—the site name and copyright date. We started with a JSON file but converted it into a JavaScript data file to pull the current date for the copyright year in the footer.

In the next chapter, we’ll discuss the hosting needs of 11ty and walk through deploying a site through a modern static site host.

About the Author
  • Bryan Robinson

    Bryan Robinson is a developer, designer and educator with a deep passion for the web and the Jamstack. He has been a developer and designer for over 15 years and has taught web development to university students, hosted technical communities, and created content for sites like CSS-Tricks and Smashing Magazine around topics like CSS Grid, Next.js, and 11ty. He's currently the Head of Developer Relations at Hygraph.

    Browse publications by this author
Eleventy By Example
Unlock this book and the full library FREE for 7 days
Start now