Setting up this blog, and creating a development environment that I was happy with, took longer than I expected, so I thought I would document the process and other learnings gained along the way.

This assumes that you have read Jekyll’s getting started guide and the quick start instructions on the Jekyll homepage, and have got your new blog generated.

NOTE: I used Jekyll 3.6.2 to originally generate this blog, so your mileage may vary depending on what version you use and when you read this post.

Choosing a theme

If you are hosting outside of Github, then you can get themes from many different sites, but if you are going to use Github Pages for hosting, then you are limited to their supported themes.

After generating a few different test blogs and applying different themes, I found that Minima, the default theme, is the one that works most seamlessly out-of-the-box: it includes all the layouts that a newly-generated site wants by default, as well as integrations for Disqus comments and Google Analytics. This ease of use, coupled with my desire to tinker with the CSS, made the minimalistic Minima a straightforward choice, but I would encourage you to experiment and pick one that best suits the look you want for your site.

Creating a Development Environment

Before starting any coding on the blog itself or making any content, I wanted to make sure I had a development environment I was comfortable with, so here is how I set mine up.

Live Reloading

Hitting refresh every time you want to see your changes reflected on a web page isn’t fun, so let Hawkins and Grip handle that for you.


Hawkins’ live reload applies to any content file in the Jekyll application itself. Installation and usage of the Hawkins gem is well documented on its README file, so I will just simply add that I’ve set it to watch draft blog posts (markdown files in the _drafts/ folder) as well by running my Jekyll server with the following command:

bundle exec jekyll liveserve --drafts


Hawkins does not cover any Markdown in a Jekyll application’s README file, so if you change it often, or just want a process to monitor it, install Grip (I use Homebrew), and run it in a separate terminal window:

brew install grip
grip --browser

The --browser flag will open a tab in your web browser immediately at http://localhost:6419/ and display the application README file. The page gets live-reloaded as changes are made, but just be warned that if you perform more than 60 live reloads per hour, you will need to authenticate your Github API requests with your Github credentials.


I’m quite fastidious about code style and quality, but do not want to have to be too cognizant of it while developing, so I want a team of robots to look over my shoulder and let me know when the code I am writing is not up to “community standards”. That team of robots, in this case, takes the form of a set of linters for each of the different file types primarily used in a Jekyll blog: CSS (SASS), HTML, and Markdown.

Find the lints

Since Jekyll is written in Ruby, I started searching for lints at Ruby Gems, where I found SCSS-Lint, Markdown Lint, and no options available for HTML. I found configuring Markdown Lint confusing, and SCSS-Lint recommends using other Javascript-based linting tools over itself, so I came to the conclusion that it was probably best to use front-end language linters that were actually written in front-end languages. They ended up being:

Install the lints using npm, and then make sure to update your shims for Node if you’re using a version manager for npm (I use asdf):

npm install -g sass-lint htmllint-cli markdownlint-cli
asdf reshim nodejs

Run the lints

Now that the lints are all installed, there needs to be a way to run them when files change. For Ruby and Rails projects, I always use Guard, so I chose it due to my familiarity with it, and because I didn’t want to have to learn how to use another front-end-based task runner at this time. Since the lints are not Ruby gems and hence do not have their own Guard plugins, I used Guard::Process to run the lints as command line processes.

To install Guard and Guard::Process, first add them to the Gemfile:

group :development do
  gem "guard", "~> 2.14"
  gem "guard-process", "~> 1.2"

Next, install the gems, and then generate a Guardfile for task configuration:

bundle install
bundle exec guard init

Open up the Guardfile with your favourite text editor and insert the following configuration:

guard "process",
      command: ["htmllint", "_includes/*.html", "about.html"],
      name: "htmllint" do

guard "process",
      command: ["markdownlint", "_posts", "_drafts", "", ""],
      name: "markdownlint" do

guard "process",
      command: ["sass-lint", "--verbose", "--no-exit"],
      name: "sass-lint" do

htmllint needs specificity on what HTML files to lint, otherwise Jekyll-generated HTML files in the _site/ directory also get linted, which just contributes unnecessary noise to the linter output. There are no Markdown files generated in the _site/ directory, but markdownlint also needs a list of files for command line arguments just the same, simply due to them being a required argument for the CLI.

Once configuration is complete, open up a terminal, and run Guard to have it watch your files:

bundle exec guard

Development Environment Summary

So, whenever I open up my Jekyll blog project, I will always currently have four processes running to help me along with development:

  • Editor: Vim (substitute out your favourite text editor here)
  • Server: bundle exec jekyll liveserve --drafts
  • Guard: bundle exec guard
  • Grip: grip --browser

Overriding Styling

Customising styling of a Jekyll theme is well documented in the Overriding theme defaults section of Jekyll’s documentation, and in the Customization section of the Minima theme’s documentation, so I will just add that since I want to have complete control over the SASS files, I did the following:

  • Copied over the contents of the Minima _sass/ directory to my local project (this, of course, means I don’t benefit from any updates that may be done to the Minima gem’s styles)
  • Linted the files with sass-lint, fixed any issues, and built up a set of SASS rules I wanted in a .sass-lint.yml file
  • Began adding my own minor tweaks to the styles

Overriding include files

I wanted to add an Apple Touch Icon and remove some footer links from the blog, which means I needed access to the application <head> and <footer> tags.

So, I created a local _includes/ directory and began copy and pasting the relevant files from Minima’s _includes/ directory into it, selectively editing the files locally. I have no doubt I will continue to do this over the course of the blog’s life.

Custom Domain Setup

Since I had my own custom name domain, I wanted to use it with the Jekyll blog on Github Pages rather than the default domain of <username>

Luckily, Namecheap, my registrar for, has a fantastic article in their knowledge base that took me through all the steps I needed to link my domain to Github Pages. Although specific to Namecheap, I would wager the information is generic enough to help anyone else wanting to do the same thing.

SSL Setup

At this point, the site may be on a custom domain, but not having the green secure padlock in the address bar, even for a static blog site, won’t make the site look great in search rankings. So, at least for now, get Cloudflare to provide a signed SSL certificate on the blog’s behalf.

Good instructions on creating a Cloudflare account and enabling SSL on a Jekyll site hosted on Github Pages can be found here and here.

No Foreign Plugins

As a post-script to this post, I thought I’d share the result of my time barking up the wrong tree when wanting to have Jekyll use ENV variables.

I wanted to use icons from Font Awesome on my About page, and I wanted to load them from the Font Awesome CDN so I wouldn’t have to download them all into my project directory. Loading them from the Font Awesome CDN requires registering an account, upon which you are allocated an Embed Code.

I mistakenly thought that the Embed Code was “secret information”, and hence should not be stored in the blog git repository but instead loaded into an environment variable using a Ruby gem like dotenv (this is, of course, not true since the Embed Code will be directly visible in HTML files and exists for these reasons).

Anyway, I followed a guide for using ENV variables with Jekyll that involved creating a Jekyll Plugin Generator which can inject values computed at build time into template variables. I deployed the additions out to Github Pages, but it did not seem to work.

Further internet searching led to the realisation that the Github Pages gem only supports a limited list of plugins and always starts Jekyll in safe mode, meaning user-defined plugins are never run.

So, as long as a Jekyll site is hosted up on Github Pages, no custom plugins can be used.


Who would have thought getting a static site and its development environment up and running “properly” would be so much work? Not me, hence this post, so hopefully it can serve as some reference to someone else setting up their own Jekyll site.

Leave a comment