Jekyll — Static Site Generation with Ruby and Liquid Templates
In this tutorial, you will learn about Jekyll. We cover key concepts, practical examples, and best practices to help you master this topic.
Jekyll is a Ruby-based static site generator that converts markdown content into static HTML using Liquid templates and frontmatter metadata.
What You'll Learn
By the end of this tutorial, you'll understand Jekyll's architecture, how to use Liquid templates, organize collections and posts, configure plugins, and deploy Jekyll sites.
Why It Matters
Jekyll pioneered the modern SSG approach and powers GitHub Pages natively. Understanding Jekyll gives you access to a mature ecosystem with seamless GitHub integration and a vast plugin library.
Real-World Use
A team blog uses Jekyll with GitHub Pages for zero-cost hosting. Team members write posts in markdown, push to GitHub, and the site auto-builds and deploys. Tags, categories, and archives are generated automatically from frontmatter.
Jekyll Architecture
graph TD
A[Jekyll Project] --> B[_config.yml]
A --> C[_posts/]
A --> D[_layouts/]
A --> E[_includes/]
A --> F[assets/]
A --> G[_data/]
A --> H[_plugins/]
C --> I[Markdown posts
with frontmatter]
D --> J[Liquid templates]
E --> K[Partials
header, footer, nav]
A --> L[jekyll build]
F --> L
G --> L
H --> L
I --> L
J --> L
K --> L
L --> M[_site/ — Static output]
style L fill:#e67e22,color:#fff
style M fill:#27ae60,color:#fff
Jekyll Configuration
# _config.yml — Jekyll configuration
title: My Jekyll Site
email: team@example.com
description: A blog built with Jekyll and hosted on GitHub Pages
baseurl: "/blog"
url: "https://example.com"
# Build settings
markdown: kramdown
highlighter: rouge
permalink: /:year/:month/:day/:title/
# Collections
collections:
projects:
output: true
permalink: /projects/:path/
team:
output: false
# Default frontmatter
defaults:
- scope:
path: ""
type: "posts"
values:
layout: "post"
author: "DodaTech"
- scope:
path: ""
type: "projects"
values:
layout: "project"
# Plugins
plugins:
- jekyll-feed
- jekyll-sitemap
- jekyll-seo-tag
- jekyll-paginate
# Pagination
paginate: 5
paginate_path: "/page/:num/"
Liquid Templates
{% comment %}
_layouts/default.html — Base layout
{% endcomment %}
<!DOCTYPE html>
<html lang="{{ site.lang | default: 'en-US' }}">
<head>
<meta charset="utf-8">
<title>{% if page.title %}{{ page.title }} — {% endif %}{{ site.title }}</title>
<meta name="description" content="{{ page.description | default: site.description }}">
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}">
{% feed_meta %}
{% seo %}
</head>
<body>
{% include header.html %}
<main>
{{ content }}
</main>
{% include footer.html %}
</body>
</html>
{% comment %}
_layouts/post.html — Post layout
{% endcomment %}
---
layout: default
---
<article class="post">
<header>
<h1>{{ page.title }}</h1>
<div class="meta">
<time datetime="{{ page.date | date_to_xmlschema }}">
{{ page.date | date: "%B %-d, %Y" }}
</time>
{% if page.tags %}
<div class="tags">
{% for tag in page.tags %}
<a href="{{ '/tags/' | append: tag | relative_url }}">{{ tag }}</a>
{% endfor %}
</div>
{% endif %}
</div>
</header>
<div class="content">
{{ content }}
</div>
</article>
Content Organization
---
# _posts/2026-06-28-getting-started-with-jekyll.md
layout: post
title: "Getting Started with Jekyll"
date: 2026-06-28 10:00:00 -0400
categories: [tutorial, jekyll]
tags: [static-site, ruby, ssg]
author: DodaTech
description: "Learn how to set up Jekyll, write content, and deploy to GitHub Pages."
image: /assets/images/jekyll-guide.jpg
---
Jekyll takes markdown content, combines it with Liquid templates, and generates a complete static website.
## Installation
Install Jekyll and Bundler:
{% highlight bash %}
gem install jekyll bundler
jekyll new my-site
cd my-site
jekyll serve
{% endhighlight %}
## Frontmatter Variables
Each page and post starts with YAML frontmatter that defines metadata:
{% highlight yaml %}
---
title: My Page
layout: default
permalink: /custom-url/
---
{% endhighlight %}
## Collections
Beyond posts, Jekyll supports custom collections:
{% highlight yaml %}
# _config.yml
collections:
documentation:
output: true
{% endhighlight %}
Create files in `_documentation/` directory and access them as `site.documentation`.
Data Files and Includes
{% comment %}
_includes/nav.html — Navigation from data file
{% endcomment %}
<nav class="main-nav">
<a href="{{ '/' | relative_url }}">Home</a>
{% for item in site.data.navigation %}
<a href="{{ item.url | relative_url }}"
{% if page.url == item.url %}class="active"{% endif %}>
{{ item.name }}
</a>
{% endfor %}
</nav>
{% comment %}
Using _data/team.yml
{% endcomment %}
{% comment %} _data/team.yml content:
- name: Alice
role: Developer
github: alicedev
- name: Bob
role: Designer
github: bobdesign
{% endcomment %}
<section class="team">
<h2>Our Team</h2>
<div class="members">
{% for member in site.data.team %}
<div class="member">
<h3>{{ member.name }}</h3>
<p>{{ member.role }}</p>
<a href="https://github.com/{{ member.github }}">@{{ member.github }}</a>
</div>
{% endfor %}
</div>
</section>
Common Mistakes
- Not including the date prefix in post filenames. Post files must follow
YYYY-MM-DD-title.mdformat. Jekyll ignores files without the date prefix. - Mixing tabs and spaces in Liquid syntax. Jekyll requires consistent indentation. Use spaces for YAML and be careful with whitespace in Liquid tags.
- Using {{ site.baseurl }} when {{ relative_url }} suffices. relative_url is safer and handles subdirectory deployments automatically.
- Forgetting to add plugins to the Gemfile. Jekyll plugins must be listed in both _config.yml and Gemfile. Otherwise the build fails on GitHub Pages.
- Ignoring the _site directory in .gitignore. The generated _site folder should not be committed. It's rebuilt on every deploy.
Practice Questions
- What naming convention must Jekyll post files follow?
- How do Liquid templates access site configuration and page metadata?
- What is a Jekyll collection and how is it different from posts?
- How do you create custom permalinks for pages and posts?
- How does Jekyll integrate with GitHub Pages for deployment?
Challenge: Build a Jekyll portfolio site with a blog section, a projects collection, custom layouts, data-driven team page, and deploy it to GitHub Pages.
FAQ
Mini Project
Create a Jekyll blog with 5 posts across 3 categories, custom layouts for posts and pages, a team data file with Liquid-driven display, tag pages with automatic listing, and deploy to GitHub Pages using the built-in Jekyll Builder.
What's Next
You've built a Jekyll site. Now explore 11ty (Eleventy) — a simpler JavaScript-based SSG that offers flexibility without framework lock-in.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro