A vortex of posts that is formed by multi colored post-it notes.

Experimenting with Jekyll Relatable Posts

  • Adam Douglas

For quite some time I’ve wanted to add related posts for each post on this website, but I just haven’t gotten around to it out of frustration. To me the list of related posts should be actually relatable to the post a user is currently viewing. Ultimately you want to expose more posts of interest that may otherwise be buried in the sea of content. Doing so also helps search engines with indexing, which then just makes it easier for people to discover your wonderful content.


Jekyll has a built-in site variable “site.related_posts”, that contains a list of up to ten related posts. The unfortunate part is the list is not related posts, but rather a list of recent posts. Having this feature built-in is wonderful, however not fitting to what I’m wanting to achieve.

I realize there is another option by running Jeklly with --lsi parameter or by adding configuration option lsi: true. Going this route does require the classifier-reborn plugin. I prefer to limit the use of plugins if at all possible, so I’ve not experimented with this option. Apparently it is quite a slow process, though I still question if it will actually return related posts instead of recent posts.

Building My Own

At first, I thought this should be quite simple to create my own using an include file that would be loaded from the post layout file. Though after spending quite some time messing around with it, I’m not sure that it is as simple as it sounds, or it may be it’s just me complicating the situation.

My initial thought was to create three variables that would be put within the front matter of each post to determine how the related posts would be generated, and then maybe a few site variables for ease of configuration later.

The liquid code below will generate related posts based upon the following criteria.

  • Generated based upon a post category, tag or title
    • Post title is case-sensitive
  • Up to five related posts can be listed
  • Duplicate posts are ignored
  • Generation ends once the counter reaches maximum related posts (e.g. 5)
  • A post front matter must have at least one of the variables defined
    • related_by_category
    • related_by_tag
    • related_by_title

The following is the include file “_includes/related_posts.html” code.

{% if page.related_by_category.size or page.related_by_tag.size or page.related_by_title.size -%}
<div class="card-footer">
    <p class="fw-bold mb-2">Related Posts</p>
    <ul class="related-posts">
{% assign counter=0 -%}
{% for post in site.posts -%}
    {%- if post.url != page.url -%}
        {% if page.related_by_category and post.categories contains page.related_by_category -%}
            <li><a href="{{ post.url | relative_url }}">{{ post.title }}</a></li>
            {% assign counter=counter | plus:1 -%}
        {% elsif page.related_by_tag and post.tags contains page.related_by_tag -%}
            <li><a href="{{ post.url | relative_url }}">{{ post.title }}</a></li>
            {% assign counter=counter | plus:1 -%}
        {% elsif page.related_by_title and post.title contains page.related_by_title -%}
            <li><a href="{{ post.url | relative_url }}">{{ post.title }}</a></li>
            {% assign counter=counter | plus:1 -%}
        {%- endif -%}
    {%- endif -%}
    {%- if counter == 5 -%}
        {% break %}
    {%- endif -%}
{%- endfor -%}
{% endif %}

The include file easily integrated by adding the following code into the desired layout file (e.g. post.html).

{% include related_posts.html %}


Using my own solution each post must be manually configured with one of the following variables followed by an associated value (e.g. related_by_tag: mastodon) to have the related posts feature.

  • related_by_category
  • related_by_tag
  • related_by_title

The Problems

This method does work, and quite quickly based on my tests. Unfortunately I see a few problems.

  1. No protection if two or more variables are set
    • related_by_category
    • related_by_tag
    • related_by_title
  2. Related posts listed are always going to be the most recent or oldest
  3. Related posts that are in between recent, and oldest are never exposed
  4. Requires manual configuration per post
  5. No ability to list relatable yet random posts
  6. Maintenance requires manual editing per post
  7. A post with only one duplicate relatable post will output related posts with no items
  8. A post with no relatable categories, tags or titles will still output related posts with no items

I would prefer to have this done automatically based upon the categories, and/or tags of a post. However, how does one achieve this yet still keeping the categories, and tags in control. What I mean by this is, not allowing for endless categories and tags. For example, if I have a post with tags #100DaysToOffload, #mastodon, and #linux I would want to ignore the tag #100DaysToOffload, and #linux as those are not as relatable to the content. Maybe I’m not creating the categories or tags properly, and that is why I have my self uncertain as to what to do. If the categories, and tags are figured out, then one could do it based upon how many categories, and tags match the post, so it is the most relatable as possible.


I’m not looking for perfection, but I would like to come up with a solution that eliminates problems 2, 3, 4, 5, and 6. In the end I need a solution that is easy to use, and maintain over time. As it stands now, I consider this attempt incomplete.

You can see how this looks thus far by viewing the following posts with related posts enabled.

What are your thoughts? Let’s continue the conversion by contacting me.

This is post 69 of 100, and is round 2 of the 100 Days To Offload challenge.

    • change 100DaysToOffload message