How to Create Related Posts in Jekyll on GitHub Pages
Why Related Posts Matter
Related posts are crucial for content discovery, engagement, and SEO. They encourage visitors to explore more articles, reduce bounce rate, and improve internal link structure. But Jekyll on GitHub Pages doesn't support plugins like jekyll-related-posts, so we must rely on smart Liquid logic instead.
Basic Strategy: Tag or Category Matching
The most straightforward method is matching tags or categories. Here's how to build that manually using Liquid, fully compatible with GitHub Pages.
1. Ensure Posts Have Tags and Categories
---
title: "How to Improve Blog SEO"
tags: [seo, blogging, optimization]
categories: [guides]
---
Jekyll automatically makes these available as arrays: page.tags and page.categories.
2. Add Related Posts Section
Inside your post layout (e.g., _layouts/post.html), add this code where you want the related posts to appear:
{% raw %}
Related Posts
{% assign related = site.posts | where_exp: "post", "post.url != page.url" %}
{% assign related_by_tag = "" | split: "" %}
{% for post in related %}
{% assign common_tags = post.tags | intersection: page.tags %}
{% if common_tags.size > 0 %}
{% assign related_by_tag = related_by_tag | push: post %}
{% endif %}
{% endfor %}
{% assign limited_related = related_by_tag | slice: 0, 5 %}
{% for rel in limited_related %}
- {{ rel.title }}
{% endfor %}
{% endraw %}
This script:
- Excludes the current post.
- Finds other posts sharing one or more tags.
- Limits the list to 5 items.
Improving Relevance with Tag + Category
To make it more refined, include both tag and category matches:
{% raw %}
{% assign related_by_topic = "" | split: "" %}
{% for post in site.posts %}
{% if post.url != page.url %}
{% assign common_tags = post.tags | intersection: page.tags %}
{% assign common_cats = post.categories | intersection: page.categories %}
{% if common_tags.size > 0 or common_cats.size > 0 %}
{% assign related_by_topic = related_by_topic | push: post %}
{% endif %}
{% endif %}
{% endfor %}
{% assign limited = related_by_topic | slice: 0, 5 %}
{% for rel in limited %}
- {{ rel.title }}
{% endfor %}
{% endraw %}
Alternative Method: Precomputed Related Posts with YAML
If you want more control (e.g., manually curating related posts), define them in front matter:
---
title: "Top Tools for Blogging"
related:
- /how-to-start-a-blog/
- /best-seo-plugins/
---
Then in your layout:
{% raw %}
{% if page.related %}
Related Posts
{% for rel in page.related %}
{% assign related_post = site.posts | where: "url", rel | first %}
{% if related_post %}
- {{ related_post.title }}
{% endif %}
{% endfor %}
{% endif %}
{% endraw %}
This gives you full editorial control over the related content.
Bonus: Display Related Posts by Title Similarity (Manual Fallback)
Another creative trick is to use string comparison. While Liquid doesn’t support fuzzy matching, you can do partial matches:
{% raw %}
{% assign keyword = page.title | split: " " | first %}
{% assign matches = "" | split: "" %}
{% for post in site.posts %}
{% if post.url != page.url and post.title contains keyword %}
{% assign matches = matches | push: post %}
{% endif %}
{% endfor %}
{% for match in matches limit:3 %}
- {{ match.title }}
{% endfor %}
{% endraw %}
This works if you follow consistent naming conventions (e.g., all “SEO for…” posts).
Designing the Related Post List
To make the section attractive, add excerpt and thumbnail support (if available):
{% raw %}
{% endraw %}
Limitations and Performance
- This method works best with < 500 posts due to Liquid performance limits.
- No fuzzy match unless you precompute related posts offline.
- Only supports simple logic (tags, categories, URL, title contains).
If you're dealing with a large blog or want smarter similarity scoring, consider generating a related.json file during build time using an external script (Node.js or Python), then reading it with JavaScript on the frontend.
Conclusion
Building a related posts system in Jekyll without plugins is entirely possible with Liquid. Whether you go with auto-matching by tag or curated lists in front matter, the benefit to user engagement and SEO is significant. Choose a method that fits your scale and editorial control needs, and make sure it integrates visually into your post layout.
In the next tutorial, we’ll explore building a related posts API using prebuilt JSON + JavaScript for smarter suggestions with real-time filtering!
