feb 19, 2023
🔗 Setup a blog with Eleventy 2.0, Tailwind and Alpine.js
Hello world! My current job is front-end developer and I wanted to have a new home for my own ideas and tinkering.
This didn't took place on a whim of a boring sunday afternoon, but took a few weeks, and it started with looking into very nice Next.js starter templates. They looked amazing but I still decided to trying to develop it with the absolute minimum setup.
As Eleventy just released the new 2.0 version I decided give it a try. It is a nice static-site generator and this new version comes with even better DX experience. I forked their official starter template from their website, 11ty/eleventy-base-blog and started building from that.
The starting point
# Installing Tailwind and Alpine.js
One great thing of doing front-end dev today is using libraries like Tailwind and Alpine.js because they allow for speedy development and make for great collaboration. I wanted to use the same stack for my blog, so first I installed them with npm.
npm install tailwindcss alpinejs --save-dev
I created index.css
and index.js
files in the src
folder and added the following to the index.js
file:
import Alpine from "alpinejs";
Alpine.start();
And as the usual Tailwind setup, I created a tailwind.config.js
file and a postcss.config.js
file in the root of my project.
// tailwind.config.js
module.exports = {
content: ["./_includes/**/*.njk"],
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
};
The content
property is used by Tailwind to know which files to scan for tailwind classes, in my case I am using Nunjucks templates, so I added the path to my njk
files.
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
and then I added to my index.css
file the following:
@tailwind base;
@tailwind components;
@tailwind utilities;
# Eleventy and its new features
Eleventy 2.0 comes with a lot of new features, from reading their official announcement, they worked hard to improve performances: dependencies are smaller, build times are faster, and the DX is better.
One improvement in this new version is that some really useful plugins are included out-of-the-box or are very easy to install. I am using the following plugins:
- eleventy-plugin-rss to generate an RSS feed
⚠️ Warning:
The Rss plugin only works with the Nunjucks template engine.
- eleventy-plugin-syntaxhighlight to add syntax highlighting to code blocks
- eleventy-img to perform build-time image transformations, it can output multiple sizes, in multiple formats, cache remote images locally
- eleventy-navigation to easily generate navigation menus
- eleventy-plugin-bundle, it lets you create small bundles where you need them, even on a per-page basis, more on this later
- eleventy-plugin-vite which lets you use Vite to bundle your assets
This sounds like a lot, but once they are installed and configured, they are really easy to use and it's difficult to bump into any issues.
It was nice to to use the eleventy-plugin-bundle
plugin to create small bundles only where it made sense.
For example, since only the blog posts rely on markdown, I needed the css that styles the content only in my post template, to do so I added the following to my post.njk
file:
{% css %}
{% include "public/css/markdown.css" %}
{% include "public/css/prism-one-dark.css" %}
{%- endcss %}
Which will be loaded inline only in the posts pages for better performance. In the <head>
of my base.njk
template file I have this:
{%- css %}
{% include "public/css/index.css" %}
{% include "public/css/utility.css" %}
{% endcss %}
<style>{% getBundle "css" %}</style>
You can also do the same to load javascript files, and use the getBundle
tag to inline the script files, but for this specific use case I noticed that the loading was smoother by using the other plugin feature, which loads the scripts in a single file.
At the beginning of this project I was trying to set a specific --pathprefix
option but I got some issue with the inlined javascript so I ended up doing this instead:
{%- js %}
{% include "public/js/index.js" %}
{% include "public/js/gradient.js" %}
{% endjs %}
<script type="module" src="{% getBundleFileUrl "js" %}"></script>
Anyways those are small wins. I will write next a post about the choices I made to ensure this blog is fast to modify and maintain.