© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
A. LibbyBeginning Eleventy https://doi.org/10.1007/978-1-4842-8315-8_1

1. Introducing Eleventy

Alex Libby1  
(1)
Belper, Derbyshire, UK
 

Imagine the scenario – you’ve spent months building up a great blog or content-driven website using WordPress and are beginning to get some great comments from readers who visit and love what you’re writing about as content. One day, though, you wake up thinking, “my blog feels slow – surely there’s a better way to host the content, right?”

Absolutely – don’t get me wrong: WordPress is a great tool. However, people today want speed and ease of use over any technology that is slow and prone to being hacked. Enter static site generators (or SSGs) and, in particular, Eleventy!

Available from https://11ty.dev and released in early 2018, this SSG operates a different architecture to more popular frameworks such as React, making it easy to update, with minimal tooling required. It’s inherently more secure too, as we’re not relying on dynamic data connections at runtime; this makes it less attractive to hack. Throughout this book, we’ll explore how the framework works, learn how to create sites using this tool, and see how it can help provide an easier route to publishing content online with minimal effort.

In time-honored tradition, we must start somewhere – there’s no better time to familiarize ourselves with Eleventy! We’ll kick off our journey into the world of using this technology with a look at introducing the framework, what makes it so appealling, getting it installed for your chosen platform, and beginning to understand how it operates.

Note

You may see references to 11ty or Eleventy: don’t worry! They are the same thing; some people prefer to use the full name, while others refer to it by its shorter name.

What Makes Eleventy So Appealling?

Now that I’ve introduced Eleventy, what is it that makes it so attractive as an SSG?

Well, there are several factors in Eleventy’s favor, but it boils down to these points:
  • Speed – Eleventy is superfast. Period no arguments! Yes, that might sound like a bold statement, but it’s thanks to not needing to load a runtime library when hosting a site, unlike sites hosted by React or Gatsby. We don’t even have to worry about server-side rendering too, as the output from Eleventy defaults to static HTML.

  • Lighthouse auditing – For many sites, it’s near impossible to get to the coveted 100% score across all of the different facets tested by Lighthouse. Eleventy is different due to the zero-JavaScript config its architecture makes it very easy to get a 100% score across the board.

  • Template flexibility – When working with Eleventy, we need to use a template library; we are spoiled for choice with no less than ten supported by the framework! They are, in no particular order, HTML (yes, vanilla HTML), Markdown, JavaScript, Liquid, Nunjucks, Handlebars, Mustache, EJS, HAML, and Pug. We can even mix up different templating libraries too – this is particularly handy if we want to migrate from, say, HAML to Nunjucks, as Eleventy will support and compile both libraries.

    Working with templates is something we will come back to and explore in more detail in Chapter 4.

  • Simplicity – Eleventy doesn’t require JavaScript by default to run a site; we simply need to provide files written in a templating language such as Nunjucks, which it compiles into static markup and styling.

  • Eleventy is available via NPM, which means we can install any one of hundreds of packages available from NPM; these might be Eleventy-specific ones or more generic, such as date-fns (which we will use later in this book).

These are just a few of the advantages that make Eleventy such an attractive package – it may only be a few years old, but it has certainly garnered some favorable press! Enough of the chitchat, though – it’s time we got down and dirty with Eleventy: the first step is to set up our development environment, ready for building our project site.

Introducing Our Project

We will begin to build a blog site for this book – the irony is that while we can use Eleventy to create any website, the type of site that is arguably best for Eleventy is a blog site.

To keep things simple, I will focus on the core elements – it will be enough to get you started with a working site and one you can then begin to flesh out with extra features or use as a basis for future projects. At the same time, I will touch on the deployment process – given that Eleventy compiles to static HTML and CSS, we could use any one of dozens of different hosts! We’ll work through uploading to a repository before making it available to view; I’ll touch on some other examples that you can use as alternatives.

Before moving on, I touched on how many templating languages are supported by Eleventy earlier in this chapter. Although the Liquid format (.liquid) is the default format, I’ve elected to use Nunjucks for exercises in this book – this is purely out of preference. This choice should not stop you from using one of the others if you prefer – please feel free to swap to an alternative supported by Eleventy if you desire!

Okay – let’s crack on with setting up a development environment for building our site.

Implementing a Development Environment

Unfortunately, we need to do a little housekeeping admin before we get stuck into creating the basis for our project site. I know – it’s not everyone’s favorite topic, but needs must!

We need to get set up or install a few things first, so without further ado, let’s work through what is required:
  • We first need to set up our project folder – for this book, I will assume it is called myblog and is at the root of C: drive. Please feel free to alter as appropriate if you want to use a different folder or drive.

    You will see references to Windows or C: drive throughout this book – this is the author’s preferred platform. Please change as appropriate if you use Linux or macOS as your platform.

  • We also need to download and install Node.js from https://www.nodejs.org – please go ahead and install the appropriate version for your platform using default settings.

  • We also need a text editor – my personal preference is to use the cross-platform open source package, Visual Studio Code, which is available from https://code.visualstudio.com/. You may already have your personal preference, so please feel free to use that if you wish.

  • Toward the end of the book, I will go through hosting our site. For this, I will use a GitHub Pages account, as I have several existing repositories in GitHub and don’t want to add yet another hosting platform to my collection! There are other ways to host Eleventy sites, such as with Netlify, now, or Vercel; I will touch on this subject in more detail later in this book.

  • The last requirement is to download and install Git for your platform if you don’t already have it set up. We’ll use it with the GitHub Pages account.

Cool – now that we have everything in place, we can crack on and get our site set up! There are a few steps to work through – nothing complicated; let’s dive in and take a look at what we need to do in more detail.

Implementing Our First Example

Like numerous other packages, Eleventy is available via NPM; this makes it a breeze to install, although there is a small catch that we need to be aware of (more anon). Once installed, we can use it to create a couple of test pages to confirm it’s working correctly before viewing them in a browser – to see what’s involved, let’s get stuck into setting up Eleventy. At this stage, don’t worry too much if you don’t entirely get what is happening – we will explore all of it and more after the exercise.

Demo – Setting Up Eleventy

To get Eleventy installed and ready for use, follow these steps:

  1. 1.

    First, fire up a Node.js command prompt, then change the working folder to our new project area, the myblog folder we created in the previous section.

     
If you are using VS Code, then you can also perform this: Open the newly created folder “myblog” in VS Code and then click the 7th tab “Terminal” from the top menu to start a new terminal session in the current project directory. Once done, you can continue with step 2.
  1. 2.

    Next, at the prompt, go ahead and enter this command to create a package.json ready for our site: npm init -y

     
  2. 3.

    Once completed, enter this command at the prompt and press Enter:

     
    npm install @11ty/eleventy
Although you can install Eleventy globally, you should use the local install method – this reduces the risk of interoperability issues if you decide to create more projects using Eleventy. You can also install Eleventy as a dev dependency too, using the --save-dev flag. If you deploy to Netlify, you must use a local installation – a global installation will not work. For more details, please refer to https://www.11ty.dev/docs/global-installation/.
  1. 4.

    Next, enter this command at the prompt – this will verify if we’ve installed Eleventy correctly. You should see 0.12.1 or greater, returned as a value:

     
npx @11ty/eleventy --version
  1. 5.

    Next, we can now try to run Eleventy. At the prompt, enter npx @11ty/eleventy to verify it’s operating correctly:

     
Wrote 0 files in 0.03 seconds (v0.12.1)
  1. 6.

    The response we get back might seem odd, but don’t worry – this is expected! To see processed content, we first need to add two new template files. Go ahead and enter these commands at the prompt, pressing Enter after each one:

     
echo '<!doctype html><html><head><title>Page title</title></head><body><p>Hi</p></body></html>' > index.html
echo '# Page header' > README.md
  1. 7.

    With the files in place, let’s try to process our content – this time, run this command at the prompt:

     
npx @11ty/eleventy --serve
  1. 8.

    You should see something akin to this appear, where x.x.x.x will be your IP address:

     
Writing _site/index.html from ./index.html.
Writing _site/README/index.html from ./README.md.
Wrote 2 files in 0.18 seconds (v0.12.1)
Watching...
[Browsersync] Access URLs:
 --------------------------------------
       Local: http://localhost:8080
    External: http://x.x.x.x:8080
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 --------------------------------------
[Browsersync] Serving files from: _site
  1. 9.

    We should see compiled files in the _site folder, as indicated in Figure 1-1.

     
Figure 1-1

The generated test files in the _site folder

  1. 10.

    Okay – this is the last step: it’s time to view the results of our work! For this, switch to a browser, then head over to http://localhost:8080/ or http://localhost:8080/README/; if all is well, you should see something akin to the screenshot shown in Figure 1-2.

     
Figure 1-2

Our initial site, created using Eleventy

If you find Eleventy cannot start due to a port conflict, you can specify an alternative – instead of running the command in step 7, run this: npx @11ty/eleventy --serve --port=8081. It’s one of several features available in Eleventy – more details are available at https://www.11ty.dev/docs/usage/.

It might not look much or very special, but we’ve created our first site using Eleventy! All we’ve added so far is a couple of template files: we’re a long way yet from a completed product. We covered some key points over the last few pages while creating the site, so let’s take a moment to explore the code changes in detail before learning more about how Eleventy functions as a static site generator.

Breaking Apart the Code

So – what did we achieve in our first exercise?

We started creating our project folder before setting up a new NPM project to generate a package.json file. We then installed Eleventy – notice that we have to specify the namespace as part of the command. It makes updating the scripts entry in package.json more critical, as it can get tedious having to type the command each time!

We will need other NPM plugins, but we can install these as and when we need them later in the book.

We then ran Eleventy twice – the first time to verify that we had version 0.12 or greater (which we did), before running it a second time to prove it was working. This step might seem a little odd (given we’ve not created anything yet), but this is a valuable check – if it had returned anything but Wrote 0 files..., then we would have an issue.

Assuming these checks were successful, we created two templates at the root of our project area and ran Eleventy a third time to compile these files into valid HTML. We then ran Eleventy with the --serve to fire up the internal development server before viewing the generated contents on screen in our browser.

Understanding Eleventy Concepts

Now that we’ve constructed our initial site, there is one topic we should explore – some of the basic concepts around Eleventy. What makes it tick? How is an Eleventy site constructed? I’m sure you will have these questions and more to ask, so without further ado, let’s take a moment to explore some of the concepts and terminology that will help in creating Eleventy sites.

Although each Eleventy site is different in content, there are some common elements you will see that are compulsory for each Eleventy site. They are as follows:
  • Layouts and templates

  • Partials

  • Components

  • Filters and shortcodes

  • Collections

  • Custom data

  • Pagination

We’ll go through each in turn, beginning with layouts and templates.

Layouts and Templates

In some respects, it’s easy to think of this first topic as being interchangeable – after all, they are (in a sense) all about how you present your data on screen, right? While some of this may be true, both file types have a specific meaning when it comes to Eleventy:
  • A template is something we use as a generic term for content files.

  • We use layouts as special templates to wrap other content.

Creating templates and layouts is something we will explore more in Chapter 4, but in short, we would use the term “template” to refer to content such as Markdown, .Nunjucks, HTML, and Liquid files that are not layout files. We use layouts to position content on the page – they will contain HTML5 boilerplate code and a specific slot for our template content.

Using Filters and Shortcodes

I’ll bet that if you own a blog, over time, you will find yourself entering the same piece of text multiple times, right? The classic example is the date – not only do we have to consider adding it, but we also have to worry about how we format it on screen!

This example is a perfect opportunity for filters and shortcodes. These tools are available in Eleventy (along with similar ones in tools such as WordPress) and allow us to create reusable bits of code such as formatted dates. For example, we might create a shortcode in our Eleventy configuration file (eleventy.js) to return a formatted year, such as in this example:
eleventyConfig.addShortcode("year", () => {
  return `${new Date().getFullYear()}`;
});
We can store shortcodes in the Eleventy configuration file, or invoke them from an external template file (which might be in .liquid, .njk, .html, or .md format). We would then use it in our template or layouts, thus:
{% year %}
It’s important not to confuse shortcodes with filters – these are reusable functions but designed to change text or images. For example, we might enter a piece of text that we always want to be in uppercase:
<h1>{{ name | makeUppercase }}</h1>
We could create a filter in our .eleventy.js file such as this one to convert it to uppercase:
module.exports = (eleventyConfig) => {
  // Nunjucks Filter
  eleventyConfig.addNunjucksFilter(
    "makeUppercase",
    (value) => {...}
  );
}

As it happens, Eleventy already provides this function – it doesn’t matter, though: we use the same principle throughout when creating our filters.

Shortcodes and filters are not available in all templating frameworks – they are only currently supported when using Nunjucks, Liquid, Handlebars, or JavaScript templates. It is also possible to invoke shortcodes and templating logic in Markdown files (.md), although it’s worth noting that these are “template files” but not considered a templating framework. For example, we might use {% year %} in the README.md template file in the same fashion as .njk, .liquid, or .html templates.

There is one thing worth noting, though – look at the eleventyConfig function called in each example. Notice how I’ve used a generic function, .addShortcode, in one, but the name of the templating language is in the second example.

Granted, these are two different functions, but what you will find is that when it comes to using Eleventy, you can specify certain function names with or without the templating language name in them. In the filter example, we used .addNunjucksFilter, but I could equally have used .addFilter instead:
eleventyConfig.addFilter

Using the latter makes it universal so that it will work for all templating languages – it saves work if you decide to move from using, say, Nunjucks to Liquid or perhaps Handlebars at a later date.

We’ll talk more about using shortcodes and filters later in Chapter 6.

Collections

Collections are an essential part of Eleventy – these are groups of related content, such as posts or articles around a particular theme. These collections might not even be theme-driven; it’s enough to say that all posts we create can also be a collection in their own right!

We will explore this concept in greater detail in Chapter 3 when we look at sourcing data. For now, it’s enough to know that if we assign one or more tags to a post or article, then we can use something called the global collections object in Eleventy to retrieve the tagged items.

Taking a step back for a moment, let me introduce a concept for you: front matter. It is a block of YAML text at the top of each article, where we can define one or more properties of the page. We might use it to determine anything from a title to the layout or template we want to use. Keeping this in mind, this is where we could add a tag such as this:
---
tags:
- pages
---

With that in place, we can access it using our chosen templating language, using collections.pages. It will return an array of data, which we can then iterate through and manipulate as desired. It’s perfect for adding features such as links, article cards, or even products to an e-commerce website!

We will come back to using front matter at various points throughout the book.

Custom Data

Up until now, we’ve touched on creating files as our content. What if we wanted to include external data?

When using Eleventy to consume data, it’s impossible to reference data sources dynamically, but that doesn’t mean we can’t consume it! We would do so by using JavaScript data files or JSON files; these we can store in a _data folder within our site as global data files.

Assuming we can store our external data in a suitable format, we could use global data files to
  • Define and consume a JSON array

  • Return the results of a fetch operation

  • Retrieve and reformat content from a headless CMS, such as Contentful

The key to making it work is how Eleventy stores and references it – it’s stored in the _data folder and accessible using a variable that matches the file name of each data file.

Let’s say I create a list of projects, which include properties such as title, tools_used, and description. I create this as projects.json in the _data file – I can then access the data in my site using it as a projects object. Using Nunjucks, here’s an example of how I could loop through the data from this object:
{% for project in projects %}
  {{ project.title }}
  {{ project.tools_used }}
  {{ project.description }}
  ...
{% endfor %}

Looks pretty straightforward, right? I don’t even have to import the JSON file into my page; Eleventy automatically does this for me!

Pagination

Assuming you’ve started to build up a collection of data, either generated or from external sources. You will almost certainly need some means to iterate through that data in chunks to make it easier to view.

Enter pagination – Eleventy allows us to iterate through any data set (or collection) and split it into more manageable groups based on what is in the collection.

We specify the pagination rules in the front matter section (usually within the template); we can then control how we display the paginated data on screen within our template files. This process of defining pagination rules makes it super flexible for us to create a collection that contains just the data we need, as well as rendering it for our customers – this is an example of how pagination will appear in our content files:
---
...
pagination:
  data: posts
  size: 1
  alias: post
  addAllPagesToCollections: true
...
---

Don’t worry if it doesn’t mean much now – rest assured, we will cover it in more detail later in the next chapter!

Okay – let’s move on: we’ve already set up our base site; before we get stuck into building out our project, there are a few more changes we should make to help ease the development process. We’ll look at them in detail shortly, but before we do so, there is one important feature we should cover in more detail: the Eleventy configuration file.

The Eleventy Configuration File

Over the last few pages, I’m sure you will have seen references in code to something called the eleventyConfig, in the .eleventy.js file. It’s a key part of our site, and a really powerful file – what makes it so important? Put simply, it not only provides the configuration for our site, but it also offers the powerful Configuration API that allows us to use some powerful custom logic in our site.

For example, when we generate the files for our site, we might need to copy across source files such as images that are not template files. Eleventy won’t do this automatically, so we need to use a feature called Passthrough File Copy to tell Eleventy to copy these files to the output folder, as shown in this example:
module.exports = function(eleventyConfig) {
  // Output directory: _site
  // Copy `img/` to `_site/img`
  eleventyConfig.addPassthroughCopy("img");
  // Copy `css/fonts/` to `_site/css/fonts`
  // Keeps the same directory structure.
  eleventyConfig.addPassthroughCopy("css/fonts");
};
There are a host of other options we could include too – many of these will be in the return{…} statement within the file. For example, we might set this:
return {
  dir: {
    input: "src",
    output: "_site",
    layouts: "_includes/layouts",
    data: "_data",
    includes: "_includes"
  },
  templateFormats: ["md", "liquid", "njk"],
  passthroughFileCopy: true
};

These are just some of the options available to us to help configure our site; don’t worry about what they all do, as we will cover some of these in the next exercise! It goes to show though that Eleventy is a powerful tool and that it’s worth spending time fine-tuning the configuration to match our needs. Okay – with the introduction out of the way, let’s crack on: we’ve created the basis for our project, but this is only the first step in a long process! There are more tweaks we should make, which we will do now.

Performing Some Additional Changes

Although Eleventy works very well out of the box with minimal changes, it won’t be long before we need to fine-tune and develop the configuration for our site. We touched on some examples in the previous section, so let’s work through adding some of them to help with constructing our site. These changes include adding new folders and setting up some essential configuration files – let’s take a peek at what is required in more detail.

Additional Tweaks
To apply the finishing tweaks, follow these steps:
  1. 1.

    We’ve already seen how to start the Eleventy server. Who wants to type that command in all of the time? There is an easier way – for this, crack open a copy of the package.json file at the root of our project, then replace the existing scripts: {...} block with this:

     
"scripts": {
  "build": "npx @11ty/eleventy",
  "serve": "npx @11ty/eleventy --serve",
  "debug": "DEBUG=* npx @11ty/eleventy"
},
  1. 2.

    Next, we need to set up a .gitignore file for our site, ready for deploying our site. At the root of our project folder, create a new file, then crack it open and add this content:

     
# Node modules and output
node_modules
dist
# Eleventy site output
_site
  1. 3.

    Go ahead and save the file, then close it – we don’t need to keep it open for now.

     
  2. 4.

    We need to make two more changes – the first is to add a .eleventy.js file. This file is the heart of Eleventy: we use it to determine how to compile our code and where to put the finished version, ready for deployment. For this, open a new file, and add in this, saving it as .eleventy.js:

     
module.exports = eleventyConfig => {
  return {
    dir: {
      input: '.',
      includes: '_includes',
      data: '_data',
      output: '_site'
    }
  };
};

Make sure you’ve saved the last two file names precisely as written; both have dots before the file name!

  1. 5.
    The last change we want to make is to expand on the folder structure for our site. There are a set of folders we need to add; go ahead and create them using the details listed in Table 1-1.
    Table 1-1

    List of folders to create for our project

    Name of folder

    Purpose

    _data

    Should be created at the root of our project folder; this is for storing global data files.

    _includes

    Create this at the root of the project folder – inside it, create three separate folders called components, layouts, and partials. All should be at level 2, that is, immediately under _includes.

    css

    Create this at the root of our project folder – this is for holding styles. Inside this folder, create one called fonts – we will use this for some custom fonts.

    feed, img, posts

    Create all three of these folders at the root of our project folder.

    Notice that we’ve specified the root level as our source folder (.) – although this will work fine, it’s better practice to create and use a src folder for storing source files.

     
  1. 6.

    At this point, all of the changes are now complete, so go ahead and save them, then close any open files.

    We’ll keep the two test files we created earlier for now, but these we will remove once we get into creating content later in this book.

     

It might seem a ragtag bag of odd changes, but trust me – they will all become useful later in the book!

The first two changes we made relate to running commands in Eleventy: we’ve added shortcuts for common ones such as --serve, plus a .gitignore file to store names of those files or folders we want to exclude during deployment into production.

We then created a .eleventy.js file, which is the beating heart of Eleventy; we can use it to customize how Eleventy performs (and which we will add to, at various stages later in the book). The last change simply sets up a series of folders, ready for storing content and features within Eleventy, which we will use throughout this project.

Summary

Creating a website as a project is more than just putting images with text – it’s all about identity; it will be a part of you, so clearly something we need to get right! Over the last few pages, we began that long road to creating our project – let’s take a moment to review what we have learned before starting the actual development work.

We started by introducing Eleventy and exploring what makes it so attractive before swiftly moving on to setting up our development environment and installing the framework. We then dipped our toes into building our project application before diving into some of the core principles of this framework.

We then rounded out the chapter by making some additional changes to our site; we understood that they might seem to be a little “ragtag” collection, but each performs a valuable function in building our site throughout this book.

Okay – so what’s next? Ah yes: we need to start creating content for our blog! The process is very straightforward, but not all of the pages will be in the same folder. Stay with me, and I will reveal that process in the next chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.238.82.77