Using a back-end or a front-end framework such as Laravel, React or Vue can become a tedious task, especially for those projects that don't need such complexity. Lately, I've been exploring some other options to build websites more simply.
Today we'll be talking about static site generators. More specifically, about Eleventy: a simpler static site generator written in JavaScript that helps transform a directory of templates into HTML.
Site generators are part of a larger architecture called Jamstack. Its core principles revolve around performance, security, maintainability, and scaling by using tools that support pre-rendering, and decoupling. It enables sites and applications to be delivered with greater confidence and resilience than ever before bringing together a few other ideas and technologies.
Requirements
Let's start by creating a simple website structure. For this post we'll be using:
- Eleventy as our site generator
- Nunjucks as our templating system
- Bootstrap 5 as our CSS framework
- Webpixels CSS as our design system
- Parcel as our build tool for JS and Sass
- Autoprefixer
- Post CSS
Installation
I won't go into detail and write about the requirements and steps you need to take before installing Eleventy or Bootstrap. This information already exists in the official documentation.
I prepared a Github repo with the full code example. You can download it and copy its contents to your project's folder, or simply press the Use this template button which can be found on the repository's page.
To see what dependencies are needed open the package.json
file.
Now, if you're ready, let's dive in. In your terminal, navigate to the project's directory and run the command:
npm install
This will install Eleventy, Bootstrap 5, Webpixels CSS, and Parcel.
Parcel is a zero-configuration build tool that will help us to compile the Sass and JavaScript files. I decided to drop Gulp or Webpack because the complexity and the maintenance were a big-time consumer.
Eleventy Configuration
Eleventy is zero-config by default but has flexible configuration options. It can also work with your project’s existing directory structure if needed.
What I love about this site generator, in particular, is that it works with multiple template languages, such as HTML, Markdown, JavaScript, Liquid, Nunjucks, Handlebars, Mustache, EJS, Haml, Pug, and JavaScript template literals.
I chose Nunjucks since it is very familiar to me and it has an easy-to-learn syntax. You can replace it if you'd like to use a different template engine.
Customizing Eleventy is easy and optional. All the configuration options are stored in the .eleventy.js
file located in the root directory.
It might look like this:
module.exports = function(eleventyConfig) {
// Return your Object options:
return {
dir: {
input: "src",
output: "dist",
includes: "includes",
data: "data",
},
templateFormats: ["html", "njk", "md", "11ty.js"],
htmlTemplateEngine: "njk",
markdownTemplateEngine: "njk",
}
};
As you can see, we are telling 11ty that we will be using Nunjucks as our templating system and we are also letting it know what folder structure we'll be having.
For this starter kit we have used passthrough file copy, and layout aliasing. However, there are many configuration options you can add. Please, head to the 11ty documentation to learn more about these.
function eleventyConfig(config) {
// Passthroughs
config.addPassthroughCopy("src/img");
// Layout aliases
config.addLayoutAlias("base", "layouts/base.njk");
}
Passthrough File Copy
If we want to copy additional files that are not Eleventy templates, we use a feature called Passthrough File Copy to tell Eleventy to copy things to our output folder for us.
Say you need to copy a new folder with your SVG files. Simply add this line:
config.addPassthroughCopy("src/svg");
Layout Aliasing
Use config.addLayoutAlias(from, to)
to add layout aliases. If you have a bunch of existing content using the base
layout and you don’t want to rewrite the full path includes/layouts/base
, map post to a new file like this:
function eleventyConfig(config) {
config.addLayoutAlias("base", "layouts/base.njk");
}
Now you can use it in your templates (e.g: index.njk) like this:
---
layout: base
---
Add the CSS styles
As I previously mentioned, we'll be using Webpixels CSS to style our site. It is a utility and component-centric design system based on Bootstrap for fast, responsive UI development. It will help us to build a modern website much faster.
You can also make use of the components and templates existing on the Webpixels website. All you have to do is to copy the HTML markup and paste it into your page.
Open the src/scss/main.scss
file and add the following lines:
@import "@webpixels/css/base";
@import "@webpixels/css/forms";
@import "@webpixels/css/components";
@import "@webpixels/css/utilities";
Webpixels CSS will automatically load the latest version of Bootstrap 5. To learn more about how to customize it read the documentation.
Include Bootstrap JavaScript plugins
Bootstrap plugins can be included individually (using Bootstrap’s individual js/dist/*.js), or all at once using bootstrap.js or the minified bootstrap.min.js (don’t include both).
For keeping things simple we will import all the plugins in the src/js/main.js
file.
var bootstrap = require('bootstrap');
Now you will be able to use the modal, the dropdown, and the offcanvas, plus a bunch more Bootstrap components. Learn about each plugin, our data and programmatic API options, and more in the official documentation
Building the Templates
To optimize the process we will be using layouts and partials to store the repeating pieces of code in one place.
Create the layout
Eleventy Layouts are special templates that can be used to wrap other content. They are located in the includes/layouts
folder.
We will create a base.njk
file inside includes/layouts
. It can contain any type of text, but here we’re using HTML:
<html lang="{{ site.lang}}">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>{{ title }} | {{ site.name }}</title>
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css">
<!-- Styles -->
<link rel="stylesheet" href="{{ '/css/main.css' | url }}">
</head>
<body>
<div id="app">
<!-- Header -->
{% include "partials/header.njk" %}
<!-- Main container -->
<div id="main-container" role="document">
<main role="main">
{{ content | safe }}
</main>
</div>
<!-- Footer -->
{% include "partials/footer.njk" %}
</div>
<script src="{{ '/js/main.js' | url }}"></script>
</body>
</html>
Here we've included our CSS and JS files. Besides, we've added Bootstrap Icons by default. You can replace it with another library if this one isn't the one you need.
Including partials
The tag {% include %}
is how a code partial is added to a page. By default, Eleventy looks for partials in the includes
folder.
We created two partials for the header and footer since these are the elements we will be using in most of our pages.
Using the layout
To denote that a piece of content should be wrapped in a template, use the layout
key in your front matter. Since we are using layout aliasing, you only need to write the name of the layout without specifying the path or the extension, like so:
---
layout: base
title: Life is Good
---
# {{ title }}
Using data
Frontmatter and Markdown are ways to provide data and content for Eleventy to process into web pages, but to better organize the data being used in a website, Eleventy can use global data files.
These are files located in a central location that can be used across all templates. These data files can be either JSON or JavaScript.
Our starter kit stores all the data into the data
folder. You can find a site.json
which was created to keep all the information needed about our current project.
{
"name": "Bootstrap Starter Kit",
"description": "Minimal starter template for websites using Bootstrap 5 and Webpixels CSS next to the Eleventy static site generator.",
"url": "",
"lang": "en",
"github": {
"url": "https://github.com/webpixels/bootstrap-starter-kit"
},
"author": {
"name": "Your Name",
"handle": "@twitterhandle",
"email": "email@example.com"
},
"date": 2021,
"copyright": "2022"
}
Later, in your pages you can use this data like this:
<h1>{{ site.name }}</h1>
Learn more about how to use data in your templates in the official documentation.
Compile Sass and JavaScript
This Bootstrap starter kit comes with a few npm scripts included to make the development and building process much easier. For this, I chose Parcel. It is very easy to install and configure, and it comes with all the features you need out of the box.
In our case, we need to compile Sass to CSS, and to optimize our JavaScript.
Working locally
Here are the commands you can use in your terminal to start working with this starter kit.
npm start
This will transform Eleventy templates to HTML, compile Sass and JS, start a local server, and watch for changes made to your files.
If you want to run the tasks separately here are the commands:
npm run serve:eleventy
npm run watch:css
npm run watch:js
Building for production
When going live you need to optimize your files. Use the following command to bundle up and minify all the CSS and Javascript.
npm run build
Going Live
You can use Netlify to quickly upload your site on the web. Create a new account or log in to, and then, simply drag and drop our dist
folder onto the web browser window to upload the contents live to the web.
Another way is to connect your Github account to automatically take the source code and deploy it. Netlify will run the npm run build
code for which will generate the dist folder.
Up Next
This is the first part of this series. To keep it clean and simple, I will dedicate one article for each major step towards our project completion.
In the following parts, we will take it a step further and prepare your site for more complex pages and features, like:
- creating a blog
- connecting Eleventy to a headless CMS like Strapi
- creating a simple e-commerce site
Follow me and subscribe to the newsletter to be the first to find out when I release them.
Top comments (0)