Technology9 minute read

Overview of Popular Static Site Generators

Static websites offer a host of advantages over dynamic pages in many scenarios, but they can be impractical and tedious to maintain.

In this, Toptal Front-end Developer Silvestar Bistrovic demonstrates how the four most popular static page generators can help.


Toptalauthors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.

Static websites offer a host of advantages over dynamic pages in many scenarios, but they can be impractical and tedious to maintain.

In this, Toptal Front-end Developer Silvestar Bistrovic demonstrates how the four most popular static page generators can help.


Toptalauthors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.
Silvestar Bistrović
Verified Expert in Engineering
11 Years of Experience

Silvestar is a fearless web developer, JAMstack enthusiast, and WordPress coder. His focus is performance and pixel-perfect implementation.

Read More

Expertise

Share

All static page generators have a single and seemingly straightforward task: to produce a static HTML file and all its assets.

There are many obvious benefits to serving a static HTML file, such as easier caching, faster load times, and a more secure environment overall. Each static page generator produces the HTML output differently.

static site generators illustrated

However, the purpose of this post is not to dive in and discuss the intricacies of their mechanism, but to compare the feature set each framework offers and highlight the unique aspects and features of every framework.

In this post, we will take a closer look the following static page frameworks: Jekyll, Middleman, Hugo, and Hexo. These are by no means the only generators out there, but they are the most commonly used ones, backed by large communities and lots of useful resources.

Let’s take a closer look at each of them and compare their basic features:

  • Jekyll
    • written in Ruby,
    • supports the Liquid template engine out of the box;
  • Middleman
    • written in Ruby,
    • supports ERB and Haml template engines out of the box;
  • Hugo
    • written in Go,
    • supports Go template engine out of the box;
  • Hexo
    • written in JavaScript,
    • supports EJS and Pug out of the box.

Note: It is worth pointing out that each of these static page generators can be customized and extended using plugins and extensions, allowing you to cover most or all of your needs.

Setting up Static Site Generators

The documentation for each of these frameworks is comprehensive and nothing short of excellent and you can grab it here:

Jekyll documentation

Middleman documentation

Hugo documentation

Hexo documentation

If you simply follow the installation guides, you should have the development environment ready within a matter of minutes. Once installed, you can start a new project by running commands from the terminal.

For example, this is how you start a new project in different frameworks:

Jekyll

jekyll new my_website

Middleman

middleman init my_website

Hugo

hugo new my_website

Hexo

hexo init my_website

Configuration

Configuration is usually stored in a single file. Each static website generator has its specifics, but many settings are the same across all four.

You could specify where are source files stored or where to output built sources. It is always useful to skip data that will not be used in the build process by setting exclude or skip_render option. You could also use the config file to store global settings like project title or the author.

Migrating to a Static Generator

If you already have a Wordpress project ready to go, you can migrate it to a static page generator with relative ease.

For Jekyll, you could Jekyll Exporter plugin. For Middleman, you could use a command line tool called wp2middleman. You can use Wordpress to Hugo Exporter for Hugo migration, and for Hexo, you could read our guide on how to migrate from Wordpress to Hexo that I wrote last year.

The principle is nearly identical and quite straightforward — first export all content to a suitable format, and then include it in the right folder.

Content

Static page generators use Markdown for the main content. Markdown is powerful and one can learn it quickly. Writing content in Markdown feels natural because of its simple syntax. The document looks clean and organized.

content in static page generators

You should place articles in a folder specified in the global configuration file. Article names should follow convention specified by the generator.

In Jekyll, you should place an article in the _posts directory. Article name should have the following format: YEAR-MONTH-DAY-title.MARKUP. Other generators have similar rules, and they provide a command for creating a new article.

Here are the commands for creating a new article in Middleman, Hugo, and Hexo:

Middleman

middleman article my_article

Hugo

hugo new posts/my_article.md

Hexo

hexo new post my_article

In Markdown, you are limited to a particular set of syntax. Luckily for us, all generators can process raw HTML as well. For example, if you want to add an anchor with a specific class, you could add it as you would in a regular HTML file:

This is a text with <a class="my-class" href="#">a link</a>.

Front Matter

Front matter is a block of data on top of the Markdown file. You could set custom variables to store the data you need to create better content. Instead of writing HTML in Markdown, which could lead to a cluttered and ugly document structure, you could define a variable in the front matter.

For example, this is how you could add tags to your article.

tags:
   - web
   - dev
   - featured

Templates in Static Page Generators

Static page generators use a templating language to process templates. To insert data into a template, you need to use tags. For example, to display the page title in Jekyll, you could write:

{{ page.title }}

Let’s try to display a list of tags from the front matter in our post in Jekyll. You need to check if a variable is available. Then, you need to loop through tags and display them in an unordered list.

{%- if page.tags -%}
 <ul>
   {%- for tag in page.tags -%}
     <li>{{ tag }}</li>
   {%- endfor -%}
 </ul>
{%- endif -%}

Middleman:

<% if current_page.data.tags %>
 <ul>
   <% for tag in current_page.data.tags %>
     <li><%= tag %></li>
   <% end %>
 </ul>
<% end %>

Hugo:

{{ if .Params.Tags }}
 <ul>
   {{ range .Params.Tags }}
     <li>{{ . }}</li>
   {{ end }}
 </ul>
{{ end }}

Hexo:

<% if (post.tags) { %>
 <ul>
   <% post.tags.forEach(function(tag) { %>
     <li><%= tag.name %></li>
   <% } ); %>
 </ul>
<% } %>

Note: It is a good practice to check if a variable exists to prevent a build process from failing. It could save you hours of debugging and testing.

Using Variables

A static page generator provides global variables available for handing in templates. Different variable type holds different information. For example, a global variable site in Hexo holds information about posts, pages, categories, and tags of a site.

Knowing the available variables and how to use them could make a developer’s life easier. Hugo uses Go’s template libraries for templating. Working with variables in Hugo could be a problem if you are not familiar with the context, or “the dot” how they call it.

Middleman doesn’t have global variables. However, you could turn on the middleman-blog extension that would allow you to get access to some variables, like a list of articles. If you want to add global variables, you could do that by extracting data to data files.

Data Files

When you want to store data that are not available in Markdown files, you should use data files. For example, if you need to save the list of your social links that you want to display in the footer of your site. All static page generators support YAML and JSON files. Additionally, Jekyll supports CSV files, and Hugo supports TOML files.

Let’s store those social links in our data file. Since all generators support YAML format, let’s save the data in the social.yml file:

- name: Twitter
  href: https://twitter.com/malimirkeccita
- name: LinkedIn
  href: http://github.com/maliMirkec/
- name: GitHub
  href: https://www.linkedin.com/in/starbist/

Jekyll stores data files in _data directory by default. Middleman and Hugo use data directory, and Hexo uses source/_data directory.

To output the data, you could use the following code:

Jekyll

{%- if site.data.social -%}
 <ul>
   {% for social in site.data.social %}
     <li><a href="{{ social.href }}">{{ social.name }}</li>
   {%- endfor -%}
 </ul>
{%- endif -%}

Middleman

<% if data.social %>
 <ul>
   <% data.social.each do |s| %>
     <li><a href="<%= s.href %>"><%= s.name %></li>
   <% end %>
 </ul>
<% end %>

Hugo

{{ if $.Site.Data.social }}
 <ul>
   {{ range $.Site.Data.social }}
     <li><a href="{{ .href }}">{{ .name }}</a></li>
   {{ end }}
 </ul>
{{ end }}

Hexo

<% if (site.data.social) { %>
 <ul>
   <% site.data.social.forEach(function(social){ %>
     <li><a href="<%= social.href %>"><%= social.name %></a></li>
   <% }); %>
 </ul>
<% } %>

Helpers

Templates often support data filtering. For example, if you want to make the title uppercase, you could do it like so:

{{ page.title | upcase }}

Middleman has similar syntax:

<%= current_page.data.title.upcase %>

Hugo uses the following command:

{{ .Title | upper }}

Hexo has different syntax, but the result is the same.

<%= page.title.toUpperCase() %>

How Static Page Generators Handle Assets

Asset management is handled differently across static page generators. Jekyll compiles assets files wherever they are placed. Middleman handles only assets stored in source folder. The default location for assets in Hugo is assets directory. Hexo suggests placing assets in global sourcedirectory.

image alt text

SASS

Jekyll supports Sass out of the box, but you should follow some rules. Middleman also supports Sass out of the box. Hugo compiles Sass through its LibSass transpiler. Hexo does it via plugin.

ES6

If you want to use modern JavaScript features of es6, then you should install a plugin. There might be more than one version of a similar plugin, so you might want to check the code or see open issues or latest commit to finding the best one.

Images

Image optimization is not supported by default either. Also, like es6 plugins, there is more than one plugin to optimize images. Do your homework and try to find the best plugin for the job. Alternatively, you could use a third party solution. In my blog that is build with Hexo, I am using Cloudinary free plan. I developed a cloudinary tag, and I am providing responsive and optimized images via Cloudinary transformations.

Plugins, Extensions

Static page generators have potent libraries that allow you to customize your website. Each plugin serves a different purpose. You could find a wide range of plugins, from LiveReload for a better development environment to generating Sitemap or RSS feed.

You could write a new plugin or extension. Before you do, check if a similar plugin exists. See Jekyll plugin list, Middleman extensions, and Hexo plugins. Hugo doesn’t have plugins or extensions. However, it does support custom shortcodes.

Shortcodes in Markdown

Shortcodes are code snippets that you could place in Markdown documents. Those snippets output HTML code. Hugo and Hexo support shortcodes. There are built-in shortcodes, like figure in Hugo:

{{< figure src="/lint/to/image.jpg" title="My image" >}}

Hexo youtube shortcode:

{% youtube video_id %}

If you cannot find a proper shortcode, you could create a new one. For example, Hexo doesn’t support CanIUse embeds, and I developed a new tag that supports CanIUse embedding. Don’t forget to publish your plugin on npm or official generator site. The community will be grateful if you do.

CMS

Static page generators could be overhead for a non-technical person. Learning how to use commands or Markdown is not something that is easy for everybody. In that case, a user could benefit from Content Management System for JAMstack sites. In this list, you could find a system that best suits your needs. Know that it takes some time to configure the CMS, but longterm you and other users could benefit from publishing content more efficiently.

Bonus: JAMstack Templates

If you don’t want to spend too much time on configuring your project, you could benefit from JAMstack templates. Some of these templates are already preconfigured with CMS which could save you much time.

You could also learn a lot by examining the code. Try to install a template, compare it to others and choose the best one for you.

Wrapping Up

Static page generators are a fast and reliable way to build a website. You can even build non-trivial and highly customized websites with a generator nowadays.

For example, Smashing Magazine moved to JAMstack last year, and they managed to speed up their site significantly. There are other successful examples of static websites and they all share the same principle — to produce static resources and deliver them over Content Delivery Networks for faster loading and a superior user experience.

There is much more you could do with your static website: from using Wordpress REST API as a backend to using Lambda functions. There are excellent solutions even for simple websites, like using HTTPS out of the box or handling form submissions.

I hope this overview of static page frameworks helped you realize their potential and consider using them next time you think of a new project.

Understanding the basics

  • What is a static web page?

    A static web page is composed of fixed content, coded in HTML. It delivers the exact same HTML to every user. This absence of automated generation makes static pages extremely fast.

  • What is a dynamic web page?

    A dynamic web page relies on servers to dynamically build each page when a user requests to access it. This allows the page to display different content every time it is viewed.

  • What is the difference between static and dynamic websites?

    Unlike a static web page, a dynamic page relies on server-side scripting. This allows for a greater degree of flexibility and easier content management. Static pages tend to be faster, more reliable, and require far fewer resources.

  • What is a static site generator?

    A static site generator (sometimes abbreviated SSG) creates a static HTML page using source files, thus allowing for a hybrid approach. In theory, this means you can reap some benefits of static pages, without giving up the practicality of a CMS.

Hire a Toptal expert on this topic.
Hire Now
Silvestar Bistrović

Silvestar Bistrović

Verified Expert in Engineering
11 Years of Experience

Josipovac, Croatia

Member since April 6, 2017

About the author

Silvestar is a fearless web developer, JAMstack enthusiast, and WordPress coder. His focus is performance and pixel-perfect implementation.

Read More
authors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.

Expertise

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

Join the Toptal® community.