Eleventy Tutorial

Creations / Tutorials / Eleventy Tutorial

Aug 15, 2023 | About 8 min reading time

Recently I've been looking for ways to reuse snippets of code on other pages without going insane trying to copy and paste them individually to each page or increasing my site's loading time with JavaScript (which I would prefer to use as little as possible). Iframes seemed neat for a bit, but ultimately not really what I was looking for.

The solution I ended up finding is a static site generator called Eleventy. Static site generators essentially are a tool you use to automate the creation of a static website (so the stuff you'll put on Neocities or wherever you're hosting your website is still the same, it's just the process of creating it that changes) from templates and raw data. Eleventy in particular seems to be fairly new, or at least I couldn't find much on it that was actually both beginner friendly and not out of date. Since I spent all of yesterday setting my site up to work with this generator, I figured I'd post a walkthrough of my process. Fair warning: I am a self-taught programmer and not by any means an expert, so there may be errors in this or better ways of doing it. If you know your way around Eleventy better than me, feel free to leave a comment in my guestbook correcting any errors you spot and I will edit this post!

By the way, if you find this useful, please consider tipping me on my Ko-Fi page!

Setup

Before starting this tutorial, you should probably be comfortable with using a terminal window (Command Prompt is what it's called in Windows usually in my experience). We'll be installing Eleventy and doing a lot of our work through there!

You'll need to make sure you have Node.js version 14 or higher. You can check this by running the following command in a terminal window:

node --version

If the command is not found or it returns a number lower than 14, go install Node.js!

If you had to install Node.js just now, I recommend closing the terminal window you had open and reopening it after Node.js is installed. I found that when I didn't, some commands weren't recognized right away.

Next, make a directory for your new project! You can do this by running this command in the terminal window (and feel free to replace eleventy-project with whatever you'd like to name it, just make sure you remember to use the name you chose for it instead of eleventy-project later on in this tutorial):

mkdir eleventy-project

Once that's done, move into that directory by running this in the terminal:

cd eleventy-project

"cd" means change directory, and "mkdir" means make directory.

Now you'll install Eleventy into this project directory! You can install Eleventy globally, but I think it makes more sense to install it for each project individually and that is what is recommended by the documentation, so we'll do things that way. In the terminal window, run this command:

npm init -y

This command is provided by Node.js and creates a package.json file for you, which is required to install Eleventy. The "-y" at the end tells it to use default values and skips the questionnaire it would otherwise give you before creating this file. Finally, to actually install Eleventy itself, run this command in the terminal window:

npm install @11ty/eleventy --save-dev

Then run this command to check that the installation worked:

npx @11ty/eleventy

Your terminal window may show a message like this after you run the above command:

[11ty] Wrote 0 files in 0.03 seconds (v2.0.1)

The reason it didn't process any files - "wrote 0 files" - is because the directory is still empty, so there's nothing to process yet. This will change as we add files to the directory.

Creating Templates

There are a couple different paths you may want to take here, depending on if you're starting from scratch or using an existing site with Eleventy. I'll list out your options for the next step below.

  • Take your existing site's index.html file and copy it over to your directory for your Eleventy project
  • Use the text editor of your choice to create a file and save it to your directory for your Eleventy project as index.html
  • Or use the following command in the terminal window to create a new index.html file:
echo '<!doctype html><title>Page title</title><p>Hi</p>' > index.html

Once you've got a basic index.html file set up, run this command again:

npx @11ty/eleventy

Your output will probably look like this:

[11ty] Writing _site/index.html from ./index.html (liquid)
[11ty] Wrote 1 files in 0.04 seconds (v2.0.1)

What Eleventy has done here is used your HTML file as a template and compiled it into an output folder (which is named _site by default, you can change this, but we'll get into that later). You can check that folder to see the generated HTML file! Right now it's not all that impressive because it's kind of just... the same HTML file we gave it to start with, but that's going to change in a moment.

If you'd like to see a live preview of the site Eleventy generates for you, use this command to set up a hot-reloading local web server:

npx @11ty/eleventy --serve

It will show the same output we got when we generated the site just a second ago, but with this at the end:

[11ty] Watching…
[11ty] Server at http://localhost:8080/

You can now open up your web browser and go to http://localhost:8080/ to see a live preview of the site! When you save your template files, it will refresh the browser to show your new changes automatically. If you'd like to stop this local web server, just hit Ctrl + C in the terminal window to cancel the process (this is generally how you terminate or kill a process that's currently running in your terminal window, at least on Windows and Linux - do not use it thinking it will let you copy text! It may work in certain terminal programs that account for this common misunderstanding, but if you have a process currently running, there's a good chance it will kill or terminate that process).

Setting Up a Github Repository

This isn't strictly necessary, but highly recommended, as working with a GitHub repository enables you to keep track of changes between versions and even revert to an older version of your project if you accidentally mess something up and can't figure out how to fix it. Plus, if you accidentally delete a snippet of code you later decide you want to put back in your project, you can just go grab it from that version of your project repository on GitHub. This walkthrough of creating a GitHub repository for an Eleventy site will help you set that up.

Layout Files

Okay, cool, we know how to use Eleventy, but we don't have it actually doing any of the useful stuff for us yet, like say, adding the same header and footer across every page without having to update them on each page individually. That's where layout files come in. You can also reuse snippets of code using partials, but we'll get to that after this!

A cool thing about Eleventy is that you don't actually have to write your input in HTML. In fact, you could have made your index.html file in Markdown instead and it would have worked the same. Eleventy knows how to process that file and turn it into an HTML file without you actually writing it in HTML.

For the sake of this tutorial, though, we're not going to be writing our templates in Markdown. Instead, we're going to use something called Nunjucks. Nunjucks is a templating language powered by JavaScript, and it feels similar to HTML but allows you to add code that's more like what you'd see in JavaScript, while still generating a static site at the end. I actually first heard of it in this tutorial on Toyhouse, where the author was encouraging others to use it for their code templates. I honestly don't know how you make it work with Toyhouse, but if you enjoy playing around with code there as well, that could be something to consider!

A Nunjucks file has the file extension .njk, so if we used that, Eleventy would automatically use Nunjucks to process it. However, we don't actually have to do that. We can write our templates in HTML files and have Eleventy process them using Nunjucks (enabling us to use Nunjucks in these HTML files) by updating our Eleventy config file.

Go into your Eleventy project directory and create a file named .eleventy.js right there, in the root of the directory. Then open it with whatever text editor you prefer to use and add the following code:

module.exports = function(eleventyConfig) => {
    return {
        markdownTemplateEngine: 'njk',
        dataTemplateEngine: 'njk',
        htmlTemplateEngine: 'njk',
        dir: {
            input: 'src',
            output: '_site'
        }
    };
};

This tells Eleventy to process Markdown, data, and HTML files using Nunjucks, so we can have the benefits of Nunjucks without having to remember to write all our files in it.

Now, go to your Eleventy project folder, and make a folder called src. This is where we'll put our input files now, so move the HTML file you created earlier in here (don't move the other files in here though). Then, in the new src folder, make a folder called _includes, and then inside THAT folder, make a folder called layouts.

Lots of folders.

Inside the layouts folder, make a file called base.html and paste in the following code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{{ title }}</title>
    </head>
    <body>
        {{ content | safe }}
    </body>
</html>

Here, putting {{ content }} tells Nunjucks that if another file uses this as a layout, their content should go in between the body tags. Adding the safe filter means it doesn't get double escaped - I'll admit I'm not fully sure what that means but I imagine your code would probably display weird if you didn't add it (EDIT: it would display as plain HTML code if you didn't have this added).

Now go back to your index.html file. At the top of the file, add the following code:

---
layout: layouts/base.html
title: Hello world
---

It doesn't actually matter what you put for the title, so feel free to change it. Remove any parts of index.html that are duplicated in the layout file, as otherwise you'll run into issues. If you don't already have the preview started up, start that now by running this command in your terminal window.

npx @11ty/eleventy --serve

You should be essentially seeing the contents of index.html wrapped in the contents of base.html. You can use this to create headers and footers that are reused across multiple webpages, without having to manually copy and paste code across twenty different HTML files or make the same edits in each HTML file individually.

One last thing before we move on: go find your package.json file in the root directory of your project and open it up. Find this line:

"test": "echo \"Error: no test specified\" && exit 1"

Replace it with:

"start": "npx eleventy --serve"

Then save the file. Now instead of writing out that long command above to start your live preview, you'll be able to simply enter this and accomplish the same thing:

npm start

Quick note: you can wrap layouts in other layouts. It's like Inception.

Partials

Another cool feature of Eleventy is being able to reuse snippets of code across different webpages. For example, I have a chatbox that I sometimes reuse on other pages besides the homepage. I can create a file called chatbox.html, put just the code for my chatbox in there, and then insert it into other pages by putting this wherever the code for the chatbox would normally appear:

{% include "chatbox.html" %}

Then to tweak the settings of the chatbox, I only need to edit chatbox.html, not all of the pages using the chatbox. Efficiency!

Some Notes

When Eleventy generates your site code (which will be in the _site folder by default, or whatever folder you've set as your output directory in .eleventy.js), pages other than index.html will automatically go into their own folders with the name of... index.html. The folder they go in gets called whatever their filename was. It's a little confusing at first and will affect the way you write filepaths or links to other pages on your site, which can now be referred to as "/folder/" (replace folder with the name of the folder holding the HTML file you want). Because they're all named as index.html, you don't actually have to specify anything besides the folder name as long as you remember to put the slashes.

Eleventy's documentation on permalinks has more information on this and how to override it if you'd prefer.

When you want to publish your site somewhere like Neocities, you simply take the contents of your output folder and upload that to your Neocities file directory.

That's going to be all for this post, I may make other posts on Eleventy in the future as I fiddle around with it more! Let me know if you have any questions (or corrections!). I referenced the following sources for this post and highly recommend that you check them out as well if interested in learning more about Eleventy: