How to build powerful sites from scratch with 11ty
Tags: web, jamstack, tutorial, 11ty
Published: 2022-02-28 02:38:11

If you've been interested in the web space recently, you've heard of static site generators like 11ty and Jekyll. These pieces of software take easily written markup such as markdown, nunjucks, and liquid and turn them into content that is ready for the web. Many developers want to author blog posts for their own site, and 11ty provides a way to do just that.

While on the surface it seems simple, theres a lot under the hood that makes 11ty a machine.

## Terms

Before starting, it's important to know terms that 11ty uses to describe their files. The names sound similar, but the differentiations are important.

- **template** - a file that contains content (written in a language like markdown)
- **layout** - pre-built wrappers for templates. Used to define a common structure for a set of templates/pages
- **front matter** - key-value pairs at the top of a template that define specific variables that are used when rendering pages in 11ty
- **data file** - purpose built files that define variables to be inherited by all templates in a defined directory.
  - Ex. in the directory `/posts`, `/posts/posts.json` would be the directory data file, and would define variables that all other template files `/posts/*` should inherit.

## Getting Started

11ty can be intimidating at first, especially if you are new to command line tooling. To start, I followed the great getting started guide at 

Here, I will demonstrate three ways to build an 11ty site, both using templates and from scratch.

## Method 1: [From scratch](https://mayormaier.github.io/11ty-hello-horses/)

> Shameless plug, I heavily leaned on the [great tutorial](https://www.youtube.com/watch?v=PPZGdolA_ns&t=7001s) by [Alex Trost](https://twitter.com/trostcodes?lang=en) and [Ben Meyers](https://twitter.com/BenDMyers) when completing this project.

One nice thing about 11ty is that you can start out VERY basic, then build up in complexity.
To start,

1. initialize a new npm package `npm init` and install 11ty `npm install @11ty/eleventy`
2. create some template files `somethingCool.md` and throw them in the project root
3. run `npx eleventy --serve` and watch your templates turn into HTML in the `_site` directory

Now lets kick it up a notch.
First lets provide some organization to our project.

1. create an `.eleventy.js` file
2. add `return { dir: { input: "src" } };` in a new `module.exports()` function

```js
const embeds = require("eleventy-plugin-embed-everything");

module.exports = function(eleventyConfig) {
    eleventyConfig.addPlugin(embeds);
    eleventyConfig.addWatchTarget('_site/assets/*.css');
    eleventyConfig.setBrowserSyncConfig({
    files: ['_site/assets/*.css']
    });
    
    return { dir: { input: "src" } };
}
```
An example `.eleventy.js` file. NOTE: this file contains additional plug in modules that you probably don't have installed yet. Only use this configuration if you have the defined modules installed.

3. create a new directory called `src`
4. move your precious templates to the new `src` directory

Now, lets add some additional structure to our pages. When eleventy builds a page, it focuses on minimal HTML. No `<head>` information is included.

1. in your `src` directory, add a `_includes` subdirectory. This is where you will store your layout files.
2. create a new layout file. you can specify where the content should be inserted with `{{content}}`
3. specify this layout to be used in the front matter of a template using the `layout` key:

```markdown
---
layout: layoutFilename
---

- cool
- markdown
```

Lastly, lets add a plugin to this site. We will be installing the [eleventy-embed-everything](https://www.npmjs.com/package/eleventy-plugin-embed-everything) plugin.

1. install the plugin with `npm install eleventy-plugin-embed-everything --save`
2. add the plugin to the `.eleventy.js` file

```js
const embedEverything = require("eleventy-plugin-embed-everything");

module.exports = function(eleventyConfig) {
  eleventyConfig.addPlugin(embedEverything);
};
```

Now you can embed media into the page simply by dropping its url on to the page.

[More information](https://www.11ty.dev/docs/getting-started/)
[Source repository](https://github.com/mayormaier/11ty-hello-horses)

## Method 2: [Based on a template](https://mayormaier.github.io/11ty-base-blog/)

The 11ty community has developed a plethora of templates that accomplish the initial configuration of 11ty quite well. Many of these sites contain a lot of useful tools and features, but on occasion this can bloat the final size of the project. The output files however remain flat and slender.

The first step that I took when configuring this template was to modify the metadata of the site to match my details (name, url, email, etc.)

![Modified configuration items](https://i.imgur.com/ww1RrOT.png)

Next, I modified the pathPrefix variable in the `.eleventy.js` file. This allows the site to be deployed to GitHub pages without explicitly defining the pathPrefix in page links (which would break the site in development).

Lastly, I added my articles to the `/posts/` directory. Because much of the configuration has already been completed, it is pretty much plug and play for all of the articles. If additional subdirectories/categories are desired, more configuration is necessary.

After inserting my articles, I specified some template metadata for each article. These vary slightly from the custom built template as different data variables are used, however they generally accomplish the same thing.

![Template data in the front matter](https://i.imgur.com/el03eOF.png)

[More Information](https://eleventy-base-blog.netlify.app/)
[Source Repository](https://github.com/mayormaier/11ty-base-blog)

## Method 3: [hax11ty](https://mayormaier.github.io/11ty-hax11ty-blog/)

hax11ty combines the powerful library of web components found in HAXCMS with the simplicity of static sites. Just like 11ty, it takes in template files, and outputs them as HTML. Just like in Method 2, utilizing a pre-built 11ty configuration saves a lot of time when you need to get a site off the ground quickly. With a clean theme and the addition of web components, hax11ty takes static sites to the next level.

For example, adding the `<video-player>` tag to our markdown yields a rendered video-player component on the page.:

```markdown
- things
- and
- stuff

<video-player source="https://www.youtube.com/watch?v=dQw4w9WgXcQ"></video-player>
```

![Page with the rendered video-player component](https://i.imgur.com/oTX4MeQ.png)

## Data Structure

When using 11ty, there is a clear division between source content and static HTML site files. 11ty will locate the content for your site, written in any of the supported templating languages, then convert it into HTML and place it into the `_site` directory. Within the `_site` directory, there is an exact clone of the directory structure where all of the source files lived previously. This `_site` directory is key, because this is the directory that includes the HTML files needed to power a website. The `_site` directory can be zipped and uploaded to a website hosting platform.

![Template files (source)](https://i.imgur.com/cAx5e8J.png)

![Output files](https://i.imgur.com/D4gpoxf.png)

These HTML files are generated through a process that 11ty calls **[the data cascade](https://www.11ty.dev/docs/data-cascade/)** The data cascade dictates the order of priority for sources of layout and style data for the static HTML files. While extremely technical, the cascade basically begins by applying global data to the template files, and then overwrites these data files as it moves deeper into the directory. Data files with the same name and same directory as the templating files are given the highest priority.

Lastly, the YAML front matter in each templating file is applied, which overwrites values further up in the data cascade. This is helpful for applying specific properties, such as a permalink, to individual files.

When a website goes live, the folder structure that contains the markdown files transfers directly to the generated static HTML files. So, for example, if a particular markdown file is located at `/src/welcome.md` then the subsequent HTML file will appear at `_site/src/welcome/index.html`.

One caveat to 11ty is that it does not automatically copy non-supported file types (anything other than files written in the supported templating languages) into the `_site` directory. In order to request that these files are copied into the `_site` directory, use the `--formats =` flag on the command line to specify certain file types.

[More information](https://elmsln.github.io/hax11ty/)
[Source Repo](https://github.com/mayormaier/11ty-hax11ty-blog)