15 years ago, training up on Django, I built a blog. It’s what webdevs did back then. It was much faster than Wordpress but the editing always fell short and the database design got in the way more than it helped. Dogfooding your software means every problem is yours. I had a glossy coat but the jelly and chunks arrested my writing process.
SSGs are perfect for blogs and brochure websites
Static site generators churn content through templates into a static website that you can just upload to a simple webserver. This is unlike Django or any other dynamic language, where you host a running process and database on an expensive server 24/7 to generate HTML on demand. You’re just serving files, for free.
Most sites don’t need fresh fresh HTML for every request. They don’t change often enough. A blog or a business’ brochure website might get updates anywhere from a couple of times a day to only once or twice a year. With a static site generator, you can make your edits and regenerate the site.
It’s also secure. There’s nothing to hack running on my domain like there might be in a Wordpress install. There’s no database to run injection attacks against. There’s no indication where the source is hosted. Cloudflare assumes much of liability for me (as well as the buildchain) and if I’m worried about them, it only costs me 20 minutes messing around with DNS to move to another host.
I’ve used a few SSGs professionally: Jekyll, Hugo and Nuxt.
Why pick 11ty over those?
Jekyll is glacial on Cloudflare’s CI/CD environment; about 3 minutes a build. Hugo is Fast but can be a nightmare to work with when things go wrong. Absolutely user-error, but I’ve wasted days at a time banging my head on Hugo. Both Jekyll and Hugo being non-JS options have their own take on asset management. I’m also a Vue developer so Nuxt is great for me, but force-feeding users a bundle of Vue, Nuxt and routers and whatnot, just for a blog? It’s silly. It does have top-shelf asset management though.
11ty was a perfect balance between Hugo and Nuxt. I get all my favourite frontend tools (PostCSS, PurgeCSS on here) with a generator that isn’t trying to force-feed my users a massive script bundle.
More, I get to pick the markup language I write in. I can use Markdown, Liquid, Handlebars, Nunjucks, Moustache, and many, many more. Even plain old HTML, or a mix. I can bundle images with the blog posts (like Hugo leaf bundles). I can paint extra styles on the page if I want to.
I have freedom. I can do anything, on any page.
It’s been 3 weeks, 2 days since my initial commit on this site’s repo and since finishing the conversion I’ve written more posts than I did in the previous decade, and I’ve also converted two Jekyll sites over too. Each took about an afternoon. Perfect URL parity, nothing ostensibly different, just a [much] better toolchain.
What took longest was editing and upgrading 285 blog posts, spanning back to the early Naughties.
Fast Enough™ for developers
Build performance only matters to a point. On this seven year old laptop, 11ty generates this whole blog, 400 pages, in well under two seconds:
Copied 403 files / Wrote 539 files in 1.46 seconds (2.7ms each, v1.0.1)
It’s a second faster on my desktop, and on a real 23 page brochure website, it’s only 0.3s.
11ty is fast but whatever I use only has to be faster than me switching to my browser. Hugo is insanely fast but so what? Anything less than 2 seconds is Fast Enough™. That’s what I mean.
No added bloat for visitors
Many Javascript-based SSGs bundle in client code too. Sometimes this makes sense: You might use Next and Nuxt to build component rich SPAs, but for blogging and brochure stuff, an extraneous 100KB of swarf delivers a poor user experience.
This may explain why I’ve actively sought out non-JS SSGs like Jekyll and Hugo before.
11ty is one of the few JS SSGs that doesn’t force script on your users. If you want “pure” HTML, that’s what you’ll get. If you’re economic with your CSS, images and fonts, it’s easy to juice the performance stats.
Comes with batteries…
You don’t have to pick between Markdown and Pug, Liquid or Nunjucks. You get them all, and more. Frontmatter can be in YAML, TOML, HAML, JSON even build-time javascript. So what? So what?! You wouldn’t say that if you’d ever wasted a day trying to work out what the hell a Hugo site was doing because of a typo in a template whose syntax was so thick and unwelcoming, kings built castle walls with it.
11ty is simple and flexible.
There’s also a huge pile of community 11ty plugins too.
… But you can use your own
If you don’t get on with something in 11ty, you use something else, or rip it; do your own thing.
The Eureka moment for me was when I got into a fight with the markdown engine. I wanted to extend it to handle some of the custom things I did in my old blog posts, that I’d implemented in Django. Code to generate Youtube embeds, special floats, <aside>
sidebars, etc. It would have been a nightmare to upgrade every post.
Using markdown-it
and markdown-it-container
I completely replaced the Markdown engine with something I could hack on. Here’s a real “explainer” snippet I have and use:
It’s important to stress that neither of those projects are for 11ty. They’re just two of a million projects sitting on npm for anyone to use. 11ty just makes it easy to use any of this stuff on your pages.
Adding template-filters for all the bundled template languages is also made really simple:
eleventyConfig.addFilter("striptags", v => v.replace(/(<([^>]+)>)/gi, ""))
If you’ve ever used opinionated software before —perhaps even your own— you’ll appreciate that 11ty isn’t just getting out of your way, it’s going out of its way to make your life easy.
What’s not so good?
I’m three sites into 11ty now, I’ve seen how I work with it and I’ve bumped into a few things I’m not gushing about:
-
Pagination is good and frustrating in equal measure. Collections seem like a good idea, filtering them into new collections is easy enough, but actually paginating them can be a bit of a mess. To show a tag page, for example, you actually use pagination to filter the collection to that tag. But then you can’t [easily] re-paginate that data, so I just show all posts from that tag rather than 15.
If I had hundreds of posts in any one tag, this’d be a problem.
-
For all my complaints with Jekyll and Hugo’s wonky asset pipelines, 11ty’s is completely decoupled.
I use
eleventy-plugin-postcss
to call PostCSS at roughly the right time (and update on changes) but I could just as easily handle that externally. There’s nothing in 11ty (obvious to me anyway) to ingest that back into the templates.- You can’t easily inline classes that only get used on one page.
- You can’t easily hash the filenames and update the links that call them after generating the post HTML (that’s important with PurgeCSS).
- Media handling could be tighter. The Image plugin is official, but this should be part of the project IMO, and not rely on this hairy shortcode.
It’s important to stress that I’m using 11ty in order that I don’t need bundles, but some of these complaints would be assuaged if the system could parse bundle manifests, so I could use external tools rather than just a dumb static assets and have the right filenames pulled in (at the right time).
-
A scoped include like Django’s would solve a couple of problems I’ve hacked around:
{% include 'template' with variable=value %}
Saneef points out that this is possible by leveraging the macro functions in Nunjucks. It’s a bit of a mouthful. I’d prefer a first-party solution (which I guess would actually have to come as part of the Nunjucks), but again it’s interesting to see just how flexible this thing is.
-
Named/keyword arguments in shortcodes would also be nice, so I don’t have to provide every option to just use the last, but I guess this would require some thinking to overcome the lack of support for destructured parameters in ES6.
These are small complaints, maybe already with solutions I’ve just not seen yet.
I’ve still managed to transfer three sites to 11ty in a couple of weeks and I wouldn’t have done that if I didn’t think it worked well enough. I’m really happy with 11ty. I’d heartily recommend it to anyone.