How I Set Up a Project With Eleventy
Tags: jamstack, eleventy
Published: 2021-08-15 00:07:23

## Introduction

This is a quick overview on my typical setup for an 11ty project. I really like how it is set up and want to share it with other people.

## File Structure

```
.
├── assets
│   ├── favicon.ico
│   └── ... (img, pdf, etc.)
├── dist
│   └── ... (output static files)
├── node_modules
│   └── ...
├── pages
│   ├── _data
│   │   └── global.js
│   ├── _includes
│   │   ├── _footer.njk
│   │   ├── _head.njk
│   │   └── _nav.njk
│   ├── _layouts
│   │   └── default.njk
│   ├── 404.njk
│   ├── index.njk
│   ├── pages.json
│   ├── uikit.njk
│   └── ...
├── styles
│   └── style.scss
├── .eleventy.js
├── package.json
├── package-lock.json
└── README.md
```

## Eleventy Config File (.eleventy.js)

```js
const pluginSass = require("eleventy-plugin-sass");

module.exports = (eleventyConfig) => {
  // Copy our static assets to the output folder
  eleventyConfig.addPlugin(pluginSass, {});
  eleventyConfig.addPassthroughCopy({ assets: "./" });

  return {
    dir: {
      input: "pages",
      output: "dist",
      layouts: "_layouts",
    },
  };
};
```

## NPM Installs and Scripts

Obviously, you need to install Eleventy. I use it as a dev dependency rather than loading it globally. 

I install `rimraf` in order to clean my output directory everytime I build the site. By default, Eleventy won't clean out files in the output directory if you move them or delete them.

I Use `cross-env` to set environment variables (development or production). This is used in my global data so I can show or hide certain things depending on if I am in development mode or production. For example, I may use vue.js in development to use the browser dev tools, then use vue.min.js in production.

```
npm install --save-dev @11ty/eleventy rimraf cross-env eleventy-plugin-sass
```

I use three scripts in my `package.json` file. 

```json
"scripts": {
  "dev": "npm run clean && cross-env ELEVENTY_ENV=dev npx @11ty/eleventy --serve --output=dev",
  "clean": "npx rimraf ./dist ./dev",
  "build": "npm run clean && cross-env ELEVENTY_ENV=prod npx @11ty/eleventy"
}
```

## Global Data

Using `cross-env` combined with the `package.json` script you can set an environment variable and use it in your template file. For nunjuks, just use `{{global.env}}`.

```js
// ./pages/_data/global.js

module.exports = {
  env: process.env.ELEVENTY_ENV
}
```

## Pages Global Data

One of the things that I have found a lot of people want in Eleventy is to set a default layout for the project. In Eleventy's documentation, it says that you can add a `<directory>.json` and it will use that data as the default data for every template page in that directory. The issue is in the root of the project you can't specify that. If you use a directory like `pages` as your input directory, then you can set a `pages.json` and use global data there. The most used one is the layout for me. Most all of my layouts should use "default". You can easily override these in the template front matter. Here is my example:

```json
{
  "layout": "default",
  "description": "default description for project",
  "title": "Default Project Title"
}
```