Jekyll is a great way to create static, scalable sites with ease. Not only is Jekyll a great way to make your project amazingly fast by eliminating the need for any additional server-side processing, but it also gives you the ability to deploy your site almost anywhere without much hassle.

In this post, we’ll be walking you through the process of creating a blog using Jekyll, from beginning to end.

Requirements

The Jekyll CLI

Basic HTML/CSS Knowledge

Getting Started

Let’s begin by creating a new directory where we are going to be working on our Jekyll site. Once created, open it up inside your favorite code editor. I prefer Visual Studio Code, but feel free to use any editor that you’re comfortable using.

Global Configuration

Jekyll’s global configuration is within the _config.yml file. Inside this file, we’re going to control how Jekyll builds our site, as well as any other custom variables that we want to define.

Let’s go ahead and create this file and add the following contents to it:

As you can see from this example, the site title and description are inside global configuration. Setting these variables within the global configuration makes it incredibly easy to use these values on any page within your site and change them in the future. Later, we’ll go over how to use these values inside your templates.

You’ll also notice the url and baseurl settings. For now, let’s keep them at their defaults by using an empty string.

Pages, Layouts, Includes, Oh My!

Before we dive deep into creating a bunch of files, let’s take a look at the 4 essential components that we’ll be using to create a blog with Jekyll.

Pages

Pages are the main component of the blog we’re going to be building. The best way to think of them is as separate routes to our content.

Pages consist of HTML and variables to build our site without the need to repeat ourselves. Each page uses a layout element to define most of how the page looks.

Layouts

Layouts allow our pages and posts to use a unified style without writing things twice. When utilized well, layouts make pages far simpler to create and maintain.

Includes

Includes in Jekyll are similar to includes in PHP or other languages. They allow us to break our content into several different components and re-use them in different locations as we see fit.

In this article, we’ll be using includes to define things like our header and footer content neatly within separate files.

Data Files

Data files allow us to define groups of raw data for Jekyll to process. The goal of data files is to provide a single location that we can add, remove, or update data without the need to manage the markup surrounding it.

In this article, we’ll be using data files to define our navigation menus so that they can be edited with ease.

Creating a Default Layout

To avoid repeating things over and over again, it’s a good idea to use a default layout as a base for all other layouts and pages. The default layout would contain things like headers, navigation, styles, and footers.

First, let’s create a new directory where our layouts will live and name it _layouts . Then, let’s create a new default.html file inside with the following contents:

You may have noticed that we’re using standard HTML but with a few differences:

On line 5 , we’re telling Jekyll to output the current page’s title with {{ page.title }} .

, we’re telling Jekyll to output the current page’s title with . On line 9 and 13 , we include the header and footer (we’ll go over more on this later).

, we include the header and footer (we’ll go over more on this later). On line 12, we’re using the {{ content }} variable to include any content passed to the template.

Creating Additional Layouts

Since every page won’t always be the same type of content, we’re going to want to create a few new layouts that better reflect that particular type of content.

For this article, we’re going to be creating the following layout types:

home

page

post

The Home Page Layout

Since we’re creating a blog, we’re going to want to display a list of our latest posts directly on the home page.

Let’s start by creating the layout file for our home page to use. Inside the _layouts directory, let’s create a home.html file with the following contents:

Let’s take a look throughout our home page layout and see what we can learn from it:

On line 2 , we’re setting layout as default . This is because we’re going to be using the default layout that we created earlier as a parent (remember: we don’t want to repeat ourselves if we don’t have to).

, we’re setting as . This is because we’re going to be using the default layout that we created earlier as a parent (remember: we don’t want to repeat ourselves if we don’t have to). Lines 8-14 are using what’s called a for loop . If you have any development experience, you’ll likely already understand what is going on here. If not, don’t worry. We’ll look over that line in just a moment.

are using what’s called a . If you have any development experience, you’ll likely already understand what is going on here. If not, don’t worry. We’ll look over that line in just a moment. On line 8 , we’re beginning our for loop. What this does is read a list of posts from the site.posts variable and run whatever is inside of it for every post it finds. For each of the posts, we’re outputting a block of HTML that contains the post title, the post date (converted to a human-readable string), and the post excerpt.

, we’re beginning our for loop. What this does is read a list of posts from the variable and run whatever is inside of it for every post it finds. For each of the posts, we’re outputting a block of HTML that contains the post title, the post date (converted to a human-readable string), and the post excerpt. Finally, on line 14, we’re closing our for loop.

The Post Layout

Let’s go ahead and create a new layout for posts as _layouts/post.html . Inside our layout, let’s use the following code:

These contents should all look quite familiar by now. We’re using the default layout as a base, then including the content and markup that we need to show when someone views a post.

A point of clarification that’s useful here is that the contents of line 7. What we’re doing here is taking the page’s date timestamp and passing it through date_to_string to perform a bit of additional formatting. Normally, page.date would look like this:

2019-04-15 13:44:05 -0400

By passing it through the date_to_string function, we get this instead:

15 Apr 2019

The Page Layout

Just like the other layouts, we’ll need to create a layout for pages. Let’s make a new page.html layout with the following contents:

By now, you should be able to understand what this is doing. It’s mostly the same as our post layout, except that since pages aren’t time-sensitive, we don’t need to include the date here.

Using Includes

Do you remember the includes that we used earlier inside of the default layout? Let’s go ahead and get started on those.

By default, Jekyll searches inside of the _includes directory for any files to use as includes. When we wrote {% include header.html %} inside of our default layout, Jekyll is grabbing the content inside of the _includes/header.html file and outputting it here.

Includes are a great way of breaking up your files into more manageable pieces. If we need to change the contents of our header, we only need to look at that part instead of the whole layout file.

The Header

One of the includes that we added to the default layout is the header. Let’s go ahead and create a new file at _includes/header.html . Inside it, let’s add the following content:

This header is mostly things we’ve already seen before, with a subtle difference. You’ll notice that on lines 5-9 we’re looping through site.data.navigation to generate the blog’s navigation menu.

Navigation is one way that you can simplify data storage inside Jekyll. We’ll discuss creating data files later in this article, but it’s a good idea to make a mental note of how we’re utilizing them here. It’ll help connect the dots when it’s time to create them.

Just like the header, the footer is another element that we want to utilize across all pages. Let’s create a new include as _includes/footer.html with the following content:

As you can see, this footer has a bit of static HTML inside it. Feel free to play around with the markup in here and see what you can come up with!

Working with Data Files

Data files allow us to manage additional sets of data with ease. Instead of copying and pasting large chunks of markup or manually editing template files, data files can be used to automatically generate things like navigation menus.

By default, data files exist inside the _data directory. Begin by creating the _data directory and a new data file inside it called navigation.yml with the following contents:

Inside the navigation.yml data file, you’ll notice that we’re defining each of our menu items in YAML format. Each item contains a title property that is used to display the title, and the path that the menu item will link to.

How We’re Using Data Files

Remember when we used a for loop inside our header like this?

{% for item in site.data.navigation %}

When Jekyll is building our blog, it’ll see that site.data.navigation is referenced. Since site.data means that we want to get a data file, by passing site.data.navigation , we’re telling Jekyll to read the contents of the data file named navigation .

So when we run {% for item in site.data.navigation %} , we’re telling Jekyll to get each item that’s inside our _data/navigation.yml data file and run the code inside as the item variable. This means that item.title and item.path reflects each of our navigation items, eliminating the need for any additional code!

Creating a Home Page

Now that we’ve gotten all of our layouts, includes, and data files all sorted out, what happens when someone visits our Jekyll blog? That’s what pages are for!

Let’s begin by creating an index.md file in the root of our new Jekyll blog’s directory. Inside this file, let’s add the following contents:

Since we’ve already used layouts to define how our blog looks, all we have to do is add a single front matter block to our index page. When Jekyll processes our page, it’s going to grab our layout and create our entire page from it. Simple as that!

Creating Additional Pages

We made our index page that shows the most recent posts from our blog, but what about other pages such as About? Thanks to how we’ve already structured out Jekyll blog, adding additional pages is easy.

Let’s go ahead and create our About page. The contents for this page will be located in about.md at the root of our Jekyll site. Let’s make an about.md file with the following contents:

Let’s take a look at the contents of our new About page:

Lines 1-5 should look familiar. It’s the front matter for our page, just like we’ve done with our other pages and layouts.

should look familiar. It’s the front matter for our page, just like we’ve done with our other pages and layouts. Line 2 defines the layout to use. This time, we want to use the layout that we created for pages.

defines the layout to use. This time, we want to use the layout that we created for pages. Line 3 defines the page’s title.

defines the page’s title. Line 4 defines the permalink for the page. For SEO reasons, it’s usually a good idea to set a permalink for each new page that you create. This permalink setting allows our page to be accessible at example.com/about/.

defines the permalink for the page. For SEO reasons, it’s usually a good idea to set a permalink for each new page that you create. This permalink setting allows our page to be accessible at example.com/about/. Finally, line 7 and beyond includes the contents of our page, written in Markdown.

Creating Blog Posts

Now that the guts of our blog are all set up, let’s create a new blog post. Blog posts are located inside the _posts directory and are named based on the post date in a YYYY-MM-DD-name-of-post format.

Like this content? Meet Pagely.

For example, if we wanted to write a new blog post with a date of 4/15/2019, we would create a new file named _posts/2019-04-14-my-example-post.md with the following content:

The overall content of the file should look somewhat familiar, except for a few extra items inside the post’s front matter block. Let’s go through the things that are a little different from what we’ve already seen thus far:

On line 2 , we’re telling Jekyll to use the post layout.

, we’re telling Jekyll to use the layout. On line 4 , we’ve defined the post date and time zone. Since blogs are time-sensitive collections of content, we’ll want to set this accordingly for each post that we create.

, we’ve defined the post date and time zone. Since blogs are time-sensitive collections of content, we’ll want to set this accordingly for each post that we create. On line 6, you’ll notice the categories property. This is an optional field that we can use on the front-end to sort our content in the future.

Hooray! We’ve created our first blog post! We only have a few more things to go over before our blog is ready to go live!

Checking Our Work

We’ve made so much progress, and now it’s time to take a look at what we’ve been working so hard to achieve!

Inside of a terminal window, navigate to our new Jekyll site’s directory. Once there, run the jekyll serve command.

Upon running jekyll serve , Jekyll builds our new blog and makes it accessible in a browser for us to view locally at http://localhost:4000.

Note: If this command doesn’t work, double-check to make sure you have the Jekyll CLI installed.

Adding Some Style

If you take a look at your blog using the jekyll serve command, you’ll notice that the content is there, but it’s completely unstyled. We’ll need to add a few styles using CSS to make it look like something someone would want to visit.

Storing Assets

When Jekyll builds our site, it merely copies anything that doesn’t have front matter attached to it. Because of this, let’s create another directory called assets (note that we didn’t use a leading underscore here like we would with Jekyll-specific directories). Inside this directory, we can store a multitude of things such as CSS, JavaScript, and images. For now, let’s create a directory inside assets called css .

Back when we were creating our default template, we already linked a CSS file at assets/css/main.css , so let’s create a new main.css file here now with our basic stylesheet content:

Of course, this stylesheet is intentionally quite basic and should be changed depending on your own personal preference.

Jekyll also supports writing styles in Sass, which Jekyll automatically builds for you. For this article, we’re going to leave that out for now, but look for a future post on including Sass on your Jekyll sites!

Finishing Touches

When we’re ready to launch our new Jekyll blog for the world to see, we can easily do so using NorthStack. If you’re not already familiar with NorthStack, it’s a hosting platform that can build, deploy, and serve your Jekyll site with all of the extra goodies such as caching and CDN.

To learn more about deploying Jekyll apps on NorthStack, take a look at Getting Started with Jekyll and NorthStack.