Welcome to the MakeUseOf Guide to Using a Static Site Generator. In this guide we’ll describe what a static site generator (SSG) is, why you’d want to use one, and how to build a brand new site with it. Some of the details we’ll explore:
Table of Contents
- Introduction to Static Site Generators (SSGs)
Why Should You Use An SSG? | How Do SSGs Work? | What Popular SSGs Are Available? | Selecting an SSG
- Preparing to Install Jekyll
Advantages of a Local Install | Advantages of a Remote Install | Prerequisites
- Jekyll Installation
Installing Ruby on Linux | Installing (Updated) Ruby on macOS | Installing Ruby on Windows | Installing Jekyll
- Project Setup and Structure
Creating a Jekyll Project | Getting to Know the Jekyll Structure
- Jekyll Content Authoring
Previewing Your Site | Updating the About Page | Updating the Site Configuration | Creating New Content in Markdown
- Building and Deployment
Build | Deploy
- Jekyll Theming
- Jekyll Plugins
Introduction to Static Site Generators
The past several years have seen a resurgence in static websites. Many modern websites use a content management system (CMS), which involves a combination of scripting and database content to build its pages dynamically.
In contrast, the pages for static sites are created, then uploaded to a web host. It sounds kind of old school, doesn’t it? Yes, but that’s a good thing.
Why Should You Use An SSG?
In the early days of the internet, web pages were created by crafting each page as a file, then uploading the files to a server. In today’s world of databases and fancy admin panels, this may seem a little dated. But a combination of two trends has led to the rising popularity of SSGs.
- Firstly, many non-technical writers who work with the web (like bloggers) have made lightweight markup languages like Markdown very popular. As people became comfortable producing content in these formats, SSGs became a convenient tool to transform it into a website.
- Secondly, the complexity of CMS systems sometimes causes performance and security issues (e.g. for simple blogs without a ton of functionality, a static site is attractive compared to the overhead of a CMS).
There are other benefits to SSGs, including the ability to work offline and a very fast site at the end of the day. Where static site generators don’t excel is in creating very interactive websites. If you plan to allow users sign up to comment on your site, or even create their own pages, an SSG may not be the best option. Likewise if you’re looking to sell products, allow users to message each other, or collaborate on documents. But if you’re looking for a simple way to get content in front of your audience, SSGs are a great option.
How Do SSGs Work?
Modern CMSes use a flow similar to the following:
- The site visitor requests a web page from the server.
- The server accepts the request and determines what the user is looking for.
- The server assembles the content using scripts which mainly query a database.
- The server sends the content back to the user in the form of a web page, which displays in the browser.
In contrast, static sites forgo all that complexity by building pages beforehand. Then, a visitor’s browser simply asks for the page, and the server returns said page.
Therefore, you can think of SSGs as essentially publishing tools. You create content, run an SSG, and it converts that content to web pages. You then upload those pages to a web server using any number of available methods.
Sound good? If you’re intrigued, let’s take a look at some of the popular SSGs out there, and see what they’ve got to offer.
What Popular SSGs Are Available?
You can peruse the listing to easily see what programming language the SSG uses, and drill down to a summary of its features. Based on those listings, let’s examine some leading SSGs based on the below attributes.
- Programming Language: This describes the language in which the SSG tool itself is written. This is very important for CMS applications, because the web server environment will need to support it. It’s still somewhat important for SSGs, but you generally have more flexibility in what you can and can’t install on your own machine.
- Templating Language: The template language is the language used to construct the structure of pages, as well as perform some automation (e.g. displaying the tags assigned to a particular page). This may be important if you’re already familiar with one and not another.
- (Native) Input Formats: What text markup formats you can use to draft your content.
- Features: There are other useful features the SSG may contain. One common example is if it’s “blog aware,” which allows you to add tags and dates to content files and have resulting pages arranged in a blog-like structure.
This table summarizes the above for five leading SSGs:
Selecting an SSG
Like any application, you should select one of the available generators based on 1) how well it supports your needs and 2) some initial testing. Looking at the above table, three of its options jump out at me as good ones.
Jekyll is the most popular of them, and the most broadly supported in terms of available themes, plugins, etc. On the other hand, I like the greater content models in Hugo, as well as the possibility of using Org-Mode as an input. The ability to export a site as a PDF book via GitBook is also appealing.
Ultimately I’ve decided to go with Jekyll, as I can achieve some of its missing capabilities via plugins. But the deciding factor is that it’s written in Ruby, and web hosts are more likely to support Ruby than Hugo’s Go programming language. (“But wait, I thought this was a local program!” It is, or at least can be. As we’ll see in the next section, there are pros and cons to this.)
Preparing to Install Jekyll
Now that we’ve settled on Jekyll, let’s get everything set up. The following sections will help you decide where you want to install the generator itself, as well as what prerequisite software you’ll need.
Unlike a CMS, you have some flexibility as to where you install the static site generator application itself. Remember, these aren’t systems that actually serve the pages up to site visitors. They take content in one format and convert it to HTML. As a result, you can choose to install the SSG either:
- Locally (i.e. on the same machine(s) where you’re authoring content)
- Remotely (i.e. on the server where your site lives)
Advantages of a Local Install
The number one advantage of installing your SSG locally is the ability to easily preview before you publish. Your SSG is taking your plain-text content and spitting out HTML versions that have all sorts of visuals applied. It’s very useful to be able to build and preview your site in a browser (more on this later) before you worry about copying to a server. The below image shows the Hugo server running — note how it builds all the content, then starts a web server and provides you the URL to view it:
As mentioned, a local install may be the only option available to you. Your web hosting environment may not support the base programming language of the SSG. For example, without support for Ruby our Jekyll commands can’t run, and therefore you can’t build your site. You should have no problem installing prerequisites on your own machine however, unless you don’t have adminstrative rights.
Advantages of a Remote Install
On the other hand, you may choose to install the SSG on the server. In this case your workflow looks something like: 1) write raw content, 2) move raw content to server, and 3) run the SSG to convert raw content to HTML. Some of the benefits of this approach are as follows:
- One set of prerequisites: Installing the SSG in one place means you’ll only need to work through its installation once.
- One install to administer: Like all software, SSGs will release new versions, and you’ll have to update if you want those sweet new features. If you work with your SSG on multiple machines, you’ll have to update each of them individually. But basing your SSG on a central server means you’ll only have to update once.
- Platform independence in authoring: If you work on a variety of devices, a remote SSG means all you need to worry about locally is authoring. And since you’re authoring in plain text, you can use pretty much any device you like. For example, you could draft posts using a text editor on your Android phone, then proof them and add graphics on a Windows machine. And you could even keep everything in sync with one of the many cross-platform file-syncing solutions out there.
On one hand, the ability to preview the site before you publish any changes far outweighs the benefits of a remote install. So if you’re choosing just one, go for the local install.
But bear in mind though that the two aren’t mutually exclusive. There’s nothing preventing you from installing locally (e.g. on your Windows machine) for a normal “default” workflow, but also maintaining an install on your server for emergency posts from your mobile.
In order to make use of an SSG in general, you’ll need the following:
- An editor capable of writing content in plain text. Distraction-free editors are a good choice (Lightpaper for the Mac is pictured in the above image).
- A web hosting environment.
- Internet access to transfer content to your hosting environment.
If you’re the type of person who’s considering an SSG over one of the “point and click” site-building services, you likely have all these things already. In addition, you’ll need to meet software requirements. For Jekyll, these are:
- Ruby version 2.2.5 or greater
- RubyGems, a format for packaging Ruby-based applications
- GCC and make, an open source software compiler (don’t worry, you won’t need to worry about this at all, but Jekyll does use it in the background)
Installing Ruby on Linux
On Unix-based operating systems like Linux, prerequisites are a snap: a couple of simple command-line installs. On Ubuntu and its derivatives, the following APT command will get the Ruby language set up for you:
sudo apt install ruby ruby-dev
This will install the Ruby language as well as development tools, which are required to deal with some Gems. Gems are the Ruby package format, and installing some of them will actually build them in place. But don’t worry, the installers take care of all this.
Once Ruby is in place, you can install Jekyll as described in the “Installing Jekyll” section below.
Installing (Updated) Ruby on macOS
macOS does come with Ruby installed out of the box. Unfortunately, that version (at least as of High Sierra) is 2.0.0, and so is not sufficient to run Jekyll.
The most straightforward way to install is via the Homebrew project, which provides a command-line tool to install many useful open source programs. It’s not unlike MacPorts, which we’ve examined on MUO in the past.
First, get Homebrew base installed by pasting the following into the Terminal application. It will download and run an installer, which will further explain the process as it goes along:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Next, use the brew command to install an updated version of Ruby that will support Jekyll:
brew install ruby
At this point make sure you close and re-open Terminal — it will pick up the updated Ruby version (shown in the below image). Then do the install with the command in “Installing Jekyll” below.
Installing Ruby on Windows
Windows isn’t a formally supported target for Jekyll. Nevertheless, there are several ways to get it installed, some arguably less painful than the one for Macs.
- Firstly, you can install via a standard .EXE installer. The RubyInstaller project supports the latest 2.5.0 release. Double-clicking the file (shown in the above image) will run a familiar install wizard.
- Alternately you can use Chocolatey, a package manager for Windows, to install Ruby. Follow our previous guide to install Chocolatey, then install Ruby with the command choco install ruby.
- Finally, if you’re running the latest Windows 10 you can install Ubuntu from the Windows Store. Then you can install Ruby using the APT command mentioned above, in addition to all the open source goodness Ubuntu provides.
Once you have Ruby installed, you can use the gem command on all three platforms to install Jekyll and all its dependencies (around 25 in all):
gem install jekyll
Note: On Ubuntu, prepend the above with sudo to install system-wide. While a user-only install is possible, I found it to be problematic.
Finally you can confirm Jekyll’s installation and version with the following:
If this worked, you can move onto the next section and get your first Jekyll site set up.
Project Setup and Structure
Creating a Jekyll Project
Now that you’ve got Jekyll installed, your first step will be to set up a project. This represents a single site you want to create and manage using Jekyll. The following command will create a new project in your current directory:
jekyll new awesome-site
This will create a new directory called awesome-site. Let’s dig in and familiarize ourselves with it.
Getting to Know the Jekyll Structure
The Jekyll project structure contains a number of key files and sub-directories, as follows:
- _posts: As the name suggests, this is where you’ll place blog posts. Blog posts differ from “regular pages” in that they will contain a date that helps to sort them, as well as optional categories to organize them. In the Content Authoring section we’ll examine this more closely.
- _config.yml: This is your site’s configuration file, written in YAML format. YAML is a markup language used for structured information, and is a common format for configs. We’ll change some of these when the time comes to start authoring our content.
- 404.html: As with other systems, the 404 page displays when visitors request unknown URLs.
- Gemfile: This is a Ruby configuration file. We’ll add to this later when installing additional components, but for right now don’t make any changes to this.
- index.md: If you’re familiar with web servers in general, this should look familiar. When a user goes to a URL (like “www.makeuseof.com”), a typical web server will attempt to load up either “index.html” or “index.php.” This Markdown file will be converted into the “index.html” of our static site.
You may notice one thing missing from this list… pages! How can you have a site without pages?
You’re free to create other files and folders for your site. As long as they don’t start with an underscore they’ll be considered “content folders.” You can place these “raw” source files either in the root of your project (such as the “about.md” file shown in the above image) or in these arbitrary folders. All that’s missing is for us to actually write some content. We’ll buckle down in the next section and do just that.
Jekyll Content Authoring
Previewing Your Site
The first thing we can do is to see how the site looks out of the box. As discussed, one of the advantages of installing Jekyll locally is using its built-in web server to easily preview our site. The following command will start that server, and let you know how to point your browser to it.
Note: It is important to issue Jekyll’s commands from your project’s directory (i.e. “/home/aaron/Documents/awesome-site/” in the below example). Otherwise you’ll get all sorts of errors about missing things that only seem that way because you’re not in the right place.
As the output says, we can open this up now in a browser using http://127.0.0.1:4080. And now there’s a site welcoming us to Jekyll, as shown in the below image.
Updating the About Page
From the above image, we can see an “About” link in the header menu. Clicking that brings up a page with a bunch of junk about Jekyll and its Minima theme.
But this is my site! Let’s change this to personalize it. We can add some Markdown to the “about.md” file in the root of our project. Note also the “front matter” at the top of the file, where the “/about/” URL is specified.
Refreshing our browser tab (Jekyll’s server will pick up our changes in real time), our welcome message appears right there at the top. Perfect!
But now other things become noticable. The site’s title is “Your awesome title” instead of “My awesome title.” And there’s some nonsense about “_config.yml” in the site’s description. Let’s fix them.
Updating the Site Configuration
The _config.yml (it’s actually important and not nonsense) file holds some important information about our site, as shown in the below image:
Finding and adjusting things are straightforward here, let’s 1) change the title, 2) change the description, and 3) remove the Github link. Unlike the page changes, we’ll need to restart the server to pick up the updated config file with Ctrl + C (to stop) and jekyll serve (to start it again):
But fiddling with YAML isn’t what we were going for. No, we want the ability to create content in formats like Markdown.
Creating New Content in Markdown
As mentioned earlier in this guide, the way to create content for most static site generators is in Markdown. This very popular lightweight markup language makes it easy to create web pages in a text editor. We’ve covered it a number of times before on MUO, including the reason’s it’s worth learning, and solid editors for Windows, Mac, and Linux. But if you’re completely new to Markdown, Michael’s super Markdown overview should be your first stop to learn the ins and outs.
Once you’re comfortable putting some Markdown together, we can move on to creating your first post. Create a new plain text file with the name “YYYY-MM-DD-your-title.md” via whatever method you like, where the first part of the name represents the date. Place the file in the “_posts” directory, then open it with your favorite text editor.
Raw Jekyll source files are mostly standard Markdown, with the exception of the front matter. This is some configuration that appears at the beginning of of the file in YAML format (see, told you it was popular). The most basic thing you can provide via front matter is the post’s title. You should also select one of your theme’s available layouts (“post” in the below example). Place these into your Markdown file at the very beginning between two sets of three dashes:
--- title: "Testing Out Some Headings" layout: post ---
After closing the front matter with three dashes, you can write the remainder of the content in standard Markdown. It’s best not to use any H1 tags directly, because Jekyll will apply those to the title you’ve defined above. But adding some lower headings (second- and third-level) and other text (including a bulleted list) gives us a fairly fleshed out page.
At this point, you can begin accumulating posts. If all you want from your Jekyll site is a simple, journal-style blog, well, you’ve got it. Some further steps you might want to consider taking include (the links will take you to resources with more detail):
- Creating other static pages like the “About” page we revised earlier. Remember, you can put the source files for these either in the root of the project, or in sub-folders you define.
- Categorizing pages in the front matter with the “category” keyword. Then, create landing pages that filter each of your categories.
- Organize the pages into a site tree using the “permalink” keyword in the front matter. This allows you to, for example, specify that the “about.md” in the root of your project actually gets an address of “awesome-site.com /about/“.
With this knowledge in hand, you have everything you need to create a website to serve as a portfolio, personal blog, or even a small business site. The problem is, up until now, it’s still confined to your desktop. In the next section we’ll explore what happened when you built your site (you didn’t even know you did that, did you?). We’ll also look at some methods to get the built, or “generated” site, onto the web.
Building and Deployment
Take a peek at the above screenshot — on the fifth line you’ll notice the output “Generating…”
In order to serve your site, Jekyll first needs to build it. This entails converting all the Markdown to HTML, and assembling pages as required (such as the category pages we mentioned earlier). The jekyll serve command also builds the project for you. This is why we’ve only had to refresh our browser to see changes.
We can also build the project manually with the following command:
Building your project creates a sub-directory called _site. It contains the “live” version of your site (we’ll discuss how to do this in the next section). It contains a structure similar to, but slightly different than, the main project structure:
In the course of building the project Jekyll will take steps including:
- Converting Markdown to HTML.
- Adding “included” elements, such as headers and footers, to the pages of the site.
- Replacing dynamic snippets in the templates with their values. An example is creating a page by looking for all blog posts and filling a list with their dates and titles.
- Creating navigational where necessary, such as the folders for post categories (“jekyll” in the above image) or a menu entry for the “About” pointing to “awesome-site.com /about/“.
At the end of this process, you’re able to simply push the contents of the “_site” directory to a web hosting environment.
The sites generated by Jekyll don’t require any fancy database installation to work. All you need to do is get all the content of the “_site” directory onto your web host. There’s a number of methods you could use to do this, including:
- Straight manual copying. No fuss, no muss. Just remember to use SFTP and not regular (insecure) FTP.
- File syncronization. If you can find a sync tool that supports SFTP (or regular FTP if you must), you can set it to sync the “_site” directory with your web root. Bear in mind that it should be a one-way sync, from your machine to the web host. Rsync is an option available on all platforms, and the Grsync UI makes it easy to use as well.
- Source control. Lastly, for something that changes as quickly and often as a blog you should be managing the “raw” content with source control. One deployment option is to also set the “_site” directory under source control. It allows you to “git push” updates to your hosting environment whenever you create or revise content. Or if you’re really clever, you can try a post-commit hook on your source directory that uses rsync to copy updated content up to your web host.
At this point, you have everything you need to create a website. But that’s not to say we’ve covered everything. For instance, the default Minima theme is a little, well… lacking. Let’s jazz it up with something a little sharper.
The most difficult thing about getting a new theme for your Jekyll site is choosing from among all the options. There are hundreds available. Try the Jekyll Themes site for a nice, browsable gallery of themes. Once you decide on one, follow the instructions on its website to install it.
Note: Many themes are packaged as Ruby gems, which means you can take advantage of the “gem install” command we used earlier. However this is still a work in progress. Alternately, some themes may have you install manually.
Since big, vertical sidebar menus are cool, we’ll install the Hydeout theme. (You’ll find many references to the classic novel throughout the Jekyll ecosystem.) It’s packaged as a Ruby gem, so you can install it using the same command we used to install Jekyll in the first place:
gem install jekyll-theme-hydeout
Then create a new Jekyll site, and change the following two to 1) take into account the gem containing the theme, and 2) actually apply the theme to the current site. First, change the following line in the Gemfile:
Now, change the setting in _config.yml to use Hydeout (using the gem name, “jekyll-theme-hydeout”) signifying the site’s active theme:
Now re-start the Jekyll server (remember, we touched the config file), and see your awesome new theme:
Themes aren’t the only way you can spruce up your site. Jekyll plugins help to add functionality ranging from new input and output options, auto-generation of tables of contents, or embedding a Spotify web player. It can even provide some of the functions that we’d highlighted as disadvantages of SSGs, like comments (e.g. the gem “disqus-for-jekyll” enables the Disqus service).
We’ll install an administration panel for our site, making it into something like a “static site CMS.” The “jekyll-admin” gem has this functionality… all we need to do is install it:
gem install jekyll-admin
And then enable it in our Gemfile according to the developers instructions:
Done! Go to your site’s new administration panel at yoursite:4080/admin:
To recap, in this guide we’ve learned:
- How SSGs take plain text content and transform it into nicely-formatted web pages
- What the important attributes of SSGs are, and how to select one that works for you
- How to install the Jekyll static site generator on Windows, Mac, and Linux
- How to start your first Jekyll project, and what its structure looks like
- How to create content for your site using the Markdown language, and preview the results
- How to take the output of Jekyll and get it from your local machine to a web host
- How to install and select a new Jekyll theme for your site
- How to install and use add-ons to add functionality to Jekyll
Armed with this knowledge, you should be able to use Jekyll to get a basic, content-centric website running quickly and easily. Furthermore, that site will be fast, secure, and easy to manage. You can work on your content wherever you are, whether you have internet access or not, and preview your work just as if you were online.
You can host your site on just about any web host, even using very affordable and “bare bones” plans. At the same time, you can use modern, great-looking themes, and even add some of those CMS features through plugins.
What do you think of SSG-based sites? Is it right for you? Or does it all sound too complicated, and you’d rather just stick with WordPress? Let us know in the comments!