Skip to main content

How to build a blog with Jekyll

Build a blog with Jekyll
(Image credit: net)

This tutorial is for people who have heard of static site generators and have decided they want to have a go at building their own site using one. Here's we'll be showing you how to start a blog using Jekyll.

A basic knowledge of Terminal is good, although you should be able to follow along as the commands are all fairly simple. Sites on GitHub Pages are powered by Jekyll behind the scenes, so when used along with GitHub Pages, it creates a way to host and manage your website for free (see our list of the best web hosting services for other options).

This tutorial assumes you are on a Mac; as Jekyll is a Ruby program, it is possible to run it on Windows but it is not officially supported. If you are following along on Windows, hop over here for help getting Ruby set up.

After completing this tutorial, you will have created a Jekyll blog and learnt how its features and templating language can build a personal blog. This is a great starting point to develop your own site.

Find the files for this tutorial here.

01. Getting set up

On a Mac you should have Ruby installed by default but let's check by typing ruby -v in your Terminal.

Now we can actually get Jekyll running in the site, make sure you are in the directory you want to build your site in and simply type gem install jekyll bundler; your computer will then go and grab all the dependencies needed to run a site.

02. Serve locally or build

There are two main commands you will use with Jekyll – serve and build. To run your site locally type jekyll serve in your command line. This will run a version on http://127.0.0.1:4000 that you can preview your changes on. If you already have gem and other dependencies installed on your machine, this command may fail due to a mismatch in dependency versions; in this case, try bundle exec jekyll serve instead. Running the same but with the word build just compiles the site. 

03. Get the starter files

Copy the files supplied with this tutorial at this point to give you a basis to work from. This will give us a homepage, blog list, detail page and the assets structure for the site. Refresh your page at http://127.0.0.1:4000 and you will see we now have some basic pages to build from. Let's have a quick overview of how a Jekyll site works.

A Jekyll site is structured in an easy to follow way. Any collections (types of posts) are held in their own folder, as are layouts and includes. You will notice a '_site' folder – this is the folder that Jekyll uses when you run a jekyll build command.

Generate CSS

Join us in London on 26 September for Generate CSS – click the image to book your ticket

(Image credit: Future)

04. Configuration

Build a blog with Jekyll: Configuration

Jekyll gives you a great structure to work with and an easy-to-manage config file

(Image credit: net)

Open _config.yml in your text editor and add your own details; one key area to check is to set your base URL. This is the folder that your site is loading in. The config file is similar to using Global Options combined with your wp-config file if you were building out a WordPress theme. 

You can control core information such as titles and meta descriptions, your email and social accounts and then all the information the site needs to compile such as collections and any plugins used. You can use a mixture of HTML and Markdown for pages, depending on what it is that you want to achieve. However, custom pages such as your homepage and list pages will generally be HTML, whereas posts and other general pages that use a set template will be Markdown.

05. Front matter

Front matter is a snippet of YAML at the top of a file. Jekyll uses it to hold variables. Look in the about.md file and you can see we set the title, which layout to use, the author and any related images. 

06. Liquid tags

Build a blog with Jekyll: Liquid tags

Liquid tags offer an easy way to work with templates and are also used in Shopify themes

(Image credit: net)

Jekyll uses Liquid – a templating language that uses objects, tags and filters. We use the object tag surrounded by double braces {{ }} to output front matter variables and a brace and percentage sign for logic {%  %}.

07. Build your navigation

Rather than a static navigation, we use the power of config files to separate the content from the template. We will hold out navigation items in the 'data' folder as a config file and then loop through them in navigation.html. We can just enter whatever pages and links we want going forward without going back to the template. Make sure you are really careful with whitespace when editing your config files such as navigation.yml or front matter at the start of a post because a stray space will cause an error.

The config file is already set so enter the following code in your 'navigation.html' include file:

{% for item in site.data.navigation %}
     <a href="{{ site.baseurl }}/{{ item.link }}" {% if page.url == item.link %}class="current"{% endif %}>{{ item.name }}</a>
   {% endfor %}

We are using Liquid logic tags to look in the navigation config file and loop out a link and name for each entry, basically just a standard for loop.

08. Create the home page

On our homepage we are going to list our latest blog post as a hero and then have a snippet from our about page with a link through. Let's start with the hero block. Open index.html and then add the following code:

{% assign post = site.posts.first %}
<div class="c-hero" style="background: url({{post.thumbnail_image.large | relative_url}})bottom center / cover no-repeat;">
   <h1 class="c-hero__title">{{ post.title }}</h1>
   {{ post.intro | markdownify  }}
   <a href="{{ post.url }}" class="btn--hero">Read the full Post</a>
</div>

You will see that we first assign the latest post and then reference the thumbnail image set in the post's front matter. The post intro uses a Liquid filter markdownify to convert the Markdown to HTML.

With that in place, let's add a teaser from the about page too. Add the following:

<div class="c-feature">
   {% for page in site.pages %}
       {% if page.url == '/about.html' %} 
           <img src="{{ page.profile_image.small }}" alt="Profie Picture" class="c-feature__image" />
           <div class="c-feature__text">
               <h2><a href="{{ page.url }}">{{ page.title }}</a></h2>
               <p>{{ page.intro }}</p>
           </div>
          
       {% endif %}
   {% endfor %}
</div>

This time we are using a for loop to check through the pages in the site. We are using page.url to filter out the about page and then we use a similar templating style to the hero in order to output the pages' information.

09. Blog list

Build a blog with Jekyll: Blog list

A simple card layout for the rest of the posts in the site that uses CSS Grid and Flexbox

(Image credit: net)

With the homepage created we can move onto the blog list page. To create the list page, we again use Liquid tags to give us the logic to loop through all the files in the 'posts' folder.

The hero is done for you because it follows the same process as the homepage. Underneath the hero in 'blog.html', add the following:

<div class="constrain">
   <h1>The best of the rest</h1> 
   <section class="card-list">
           {% for post in site.posts offset:1 %}
           <div class="card">
                   <img src="{{ post.thumbnail_image.small }}" />
                   <div class="card-details">
                   <h3>{{ post.date | date:"%d %b" }} - {{ post.title }}</h3>
               <a href="{{ post.url }}" class="btn">Read More</a>
                   </div>
               </div>
           {% endfor %}
          
   </section>
</div>

Again we use a for loop to go through the posts collection. But as we have already looped out the latest in the hero we offset this loop to start on post two. A Liquid filter is used to convert the date to a format of our choosing.

10. Blog detail page

Not long to go now: we nearly have all the basic elements together. One important aspect left to address is navigation. When you are reading a blog post you need a way to cycle through and read more. We can add some nice pagination to our site using a page variable. Open post.html in the layouts folder and add the following:

<div class="c-pagination">
   {% if page.previous %}
   <div>
       <h3>Previous</h3>
       <p>{{page.previous.title}}</p>
       <p><a  class="btn"  href="{{ site.baseurl }}{{page.previous.url}}">Read Post</a></p>
   </div>
   {% endif %}
   {% if page.next %}
   <div>
       <h3>Up Next</h3>
       <p>{{page.next.title}}</p>
       <p><a  class="btn"  href="{{ site.baseurl }}{{page.next.url}}">Read Post</a></p>
   </div>
   {% endif %}
</div>

We use the page.previous and page.next variables to check if there is a post to click on to. If there is then we can output a block and include the title and link of the post.

11. Build and publish

GitHub Pages renders the Sass files for us, so when you run jekyll build the compiled files are created in the _site folder. No gulp files or webpack here, just nice lean styles! You can even minify the Sass output as a setting in the main config.yml file for the site. The contents of this directory can be transferred to your chosen hosting. One thing to be aware of is that GitHub Pages actually supports Jekyll so you can build and host a site using your master branch as the source. You can find more information on this here

This article was originally published in issue 320 of net, the world's best-selling magazine for web designers and developers. Buy issue 320 here or subscribe here.

Related articles: