Choosing a Static Site Generator

Recently I found myself with what appeared to be a simple task: Find a static generator for my company's new website. Easy, right? Wrong.

We didn't need a static site, I just made that decision because we needed something, anything as soon as possible, and from previous experience, I know that I can come up with a static site quickly.

Besides that, here are a few reasons to choose a static site over a dynamic site:

  • Speed: They are fast; when you browse a static website you are asking the server for HTML and static files only, there is no database to be queried.
  • Can be hosted practically anywhere: You don't need a fancy server, static pages can be hosted even for free if you use services like GitLab pages or GitHub pages or Netlify.
  • Easy to create with today's technologies: Perhaps you don't have the knowledge or the will to build your site using a traditional CMS, especially if you just want to create a portfolio website, a simple blog, or documentation.
    Most static generators will get you a site with a default theme running within minutes.

There are also some cons:

  • Content management: Most static site generators use .yaml, .json or markdown for content and configuration. If someone less tech-savvy is going to manage the site they may have a harder time. Although, this can be alleviated using external services like Contentful or Forestry.
  • They require some dev skills: Most generators require at least some command line knowledge, with some exceptions like Publii.

What was I looking for?

I had some requirements of my own when I had to choose a generator:

  • Markdown support: I write in Markdown all the time. This was not a problem, every generator I tried supported markdown.
  • Localization: The site has a language switch and content in both English and Spanish, the latter being the main language.
    Ideally, content in Spanish would be served at root level (/) while content in English would be served under /en/. Which takes us to ...
  • Routing: I need a generator that created routes and paths without any extra configuration, but that would allow me to define custom routes in case it's ever needed.
  • Easy and quick to set up: I needed to get going fast, with a custom theme.
  • Sass compilation: I use Sass, always. I needed something that would compile my .scss files out of the box too, I didn't want to run a separate command for that.

The contenders

  • Gatsby. React-based, markdown and front-matter support using GraphQL.
  • Hexo. This one looked promising even though it's a bit more blog-oriented.
  • Gridsome. This one is somewhat new. It's basically Gatsby for VueJs.
  • VuePress. Vue-powered static site generator. Ideal for documentation sites, but capable enough to power any simple site.

Gatsby

I had to use Gatsby once in the past and it didn't go well.
But I figured that had to do with that fact that I wasn't in charge of the project, and that they chose to use a bunch of plugins that made everything feel super convoluted.

I decided to give it a shot, actually being my first choice.

[The good]

  • Easy to start: After a handful of commands I had a site running locally.
  • Markdown with front-matter support.
  • Extensive documentation.
  • A ton of "starters" available: Boilerplate Gatsby sites maintained by the community.
  • React-based, easy to extend.
    I wanted to use some reactive framework to add some functionality to the site. Easy to do here.
  • Great community.

[The not so good]

  • No i18n support out of the box. There are instead a few plugins like gatsby-plugin-i18n that are supposed to help with that, but even then it requires some tinkering. That particular plugin looked great at the start, it would let me query content by language, that's great. Until ...

[What drove me away]

The structure for multi-language pages templates was not ... great.

For each page, I would have to create 2 separate .js files:

  • index.js, for Spanish.
  • index.en.js, for English.

Besides that, I wanted to maintain all content in separate .md files. For that, I had to create 2 more files to separate Spanish and English content.
Now, keep in mind that this would be necessary for each page.
What this means is, I would have to maintain, in total, 4 files per page. That does not feel right.

Sure, these are .js files and I could import and export one from the other to make things easier, but it still didn't feel right. And I would have a bunch of extra page files just for the sake of translations. Again, not good.

Next!

Hexo

This one looked promising, it was actually the dumbest thing that drove me away.

[The good]

  • Good i18n support, I could get the routes exactly how I wanted them.
  • Markdown with front-matter, check.
  • Extensive documentation.

[The not so good]

  • The templates.
    Hexo provides the Swig template engine by default, after a quick look at their repo you'll find that project is "NOT MAINTAINED". Not good.
  • Hexo's default theme resorts to .ejs, look at this mess:
article.ejs, from Hexo's default theme.
  • Not too messy I hear you say, true, true. But when time is of the essence a new template engine is not gonna help

[What drove me away]

I could deal with the templates issue, after all, Hexo supports Pug as well.
What really made me discard Hexo was the assets compilation flow, or the lack of thereof.

Am I being nitpicky? Absolutely, but again, time is of the essence here.

Next!

Gridsome

"Gatsby meets Vue".

Gridsome is what I have been waiting for, it has all the same good stuff as Gatsby, but it uses Vue components.

There was just one issue with it, but first ...

[The good]

  • Easy to get started.
  • Markdown with front-matter support.
  • Uses GraphQL to fetch data.
  • Based on Vue, and man do I love Vue.
  • Image handling: Have you seen that nice effect on sites like Medium when an image looks blurry at first and then changes when the full-res image is loaded? That's often called Progressive image loading, and Gridsome has it built right in.

[The not so good]

  • Being new in the block, means the documentation is not complete. The basics are there, but there are a few empty topics. This should change soon though, as the docs are open source too and anyone can contribute to them.

[What drove me away]

  • It's too new. Don't get me wrong, this thing looks promising.
    I don't mind using new stuff, but it still lacks good i18n support. I'll be honest here, I tried to fix that myself but it would have taken a while, specially because their API docs are not too extensive yet.

    Gridsome didn't for me this time, but I'm already considering to move my personal website from Jekyll.

Next...

VuePress

This is the official Vue-powered static site generator, as it comes from Evan You himself, the creator of Vue. It is tailored to build documentation sites, but with some tweaking, it can be used to power pretty much anything.

The latest version is still in alpha state, but I still I gave it a shot.

[The good]

  • Easy to get started: Three commands is all it takes to get a site running with the default theme.
  • Markdown with front-matter support.
  • Built-in i18n support.
  • Vue components can be used in Markdown.
  • Markdown content can be split into slots.
  • Super easy to extend.
  • Routing is flexible, I could get the routes just the way I wanted them.

[The not so good]

  • There's no built-in support for localized route paths, but that was easy to solve with a custom mapping:
const pagesMapping = {
    pages: [
        {
            text: 'Proyectos',
            abbr: 'P',
            link: '/proyectos/',
            _maps: {
                'en': {
                    text: 'Work',
                    abbr: 'W',
                    link: '/en/work/'
                }
            }
        },
        {
            text: 'Equipo',
            abbr: 'E',
            link: '/equipo/',
            _maps: {
                'en': {
                    text: 'Team',
                    abbr: 'T',
                    link: '/en/team/'
                }
            }
        }
    ],
};

Conclusion

I might be a little biased due to my feelings towards Vue, but VuePress turned out to be the best choice for what I needed. In the end, and after spending a whole weekend trying different things, I got the most progress in the least time using it.

I'm not saying the others are bad, it just depends on your needs, the fact that VuePress was the best for me doesn't mean it's going to be the best for you too.

My suggestions

If you don't need serious localization and feel comfortable with React or Vue, go with Gatsby and Gridsome, respectively.

If you just need a simple site to document a library or plugin you are working on, then VuePress is the obvious choice.

Bonus: Forestry.

Forestry is a static CMS that works with VuePress (and a couple more static generators) and makes it easy to manage content for your static site. It feels just like a normal CMS, but it commits your content directly to your repo.
Couple that with, say, Gitlab's pipelines and you get yourself a hassle-free, manageable static site.


That's it.
If you have any suggestions regarding the mentioned static generators, or if I missed something, please let me know in the comments.

Peace!