How To Add Jekyll Pagination Next Previous Post Link

This post will discuss how to enable and add jekyll pagination, next and previous post links with trouble shooting details.

Enable and Add Jekyll Pagination

  1. Add the following two in _config.yml file:
paginate: 5
paginate_path: "/blog/page:num/"

The first line of configure tells jekyll what number should be the maximum number of posts we would like to be displayed per-page in the generated site. And once jekyll see this line, the paginator liquid object will be exposed so we can access the pagination data, e.g., a list of posts for the current page.

The second line of configure indicates the url pattern the pagination should follow.

  1. Add the following contents to the index.html so the contents of the number (i.e., 5 in our example above) of posts for the current page would be displayed.
{% for post in paginator.posts %}
    <h1><a href="{{ post.url }}">{{ post.title }}</a></h1>
        <p class="author">
            <span class="date">{{ }}</span>
    <div class="content">
        {{ post.content }}
{% endfor %}

Pay special attention to the paginator object here in the first line of the above code, do not use site.posts instead as it contains all the site-wide posts.

  1. Add the following code to the index.html as well, so the pagination link will show in each page:
{% if paginator.total_pages > 1 %}  
<div class="pagination">  
  {% if paginator.previous_page %}  
    <a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">&laquo; Prev</a>  
  {% else %}  
    <span>&laquo; Prev</span>  
  {% endif %}  
  {% for page in (1..paginator.total_pages) %}  
    {% if page == %}  
      <em>{{ page }}</em>  
    {% elsif page == 1 %}  
      <a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">{{ page }}</a>  
    {% else %}  
      <a href="{{ site.paginate_path | prepend: site.baseurl | replace: '//', '/' | replace: ':num', page }}">{{ page }}</a>  
    {% endif %}  
  {% endfor %}  
  {% if paginator.next_page %}  
    <a href="{{ paginator.next_page_path | prepend: site.baseurl | replace: '//', '/' }}">Next &raquo;</a>  
  {% else %}  
    <span>Next &raquo;</span>  
  {% endif %}  
{% endif %}  

This part of code serves as navigation bar, it does not contain any actual post contents, but just display page links, the actual result would be something like this:

Prev 1 2 3 4 Next

Trouble shooting

1) Page 1 issue, somehow jekyll pagination decides to start with page 2, which means, there is no page1 at all, the above code tries to resolve this problem, but it does not work perfectly still, if you try to click page 1 while your current page is say page 45, the result would just be page 44. That is, the clicking of page 1 has the same effect of clicking Prev link. I probably will resolve this soon and I will update the post about this issue as well, but if anyone already got the solution, please share it in the comments, thanks in advance.

Update Solution: the problem ocurrs at the place below:

{% elsif page == 1 %}  
<a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">{{ page }}</a>  

We should use site.baseurl directly without prepending it with the previous page path, the official Jekyll document has the same error as well.

2) We should remove permalinks in each post, that is .md files in _posts folder, but we can keep the permalink configure in _config.yaml which is alright.

3) Jekyll documentation mentions that:

Pagination does not work from within Markdown or Textile files from your Jekyll site. Pagination works when called from within the HTML file, named index.html

My current understanding is Jeylly will use the index.html under root folder to generate each index.html in the page folder (e.g., /blog/page2 in our code above), and we can check _site for details, and we will see indeed, every index.html under /blog/page:num/ folder are the same and generated from the index.html in the root folder. Based on this, my question is what if I want the index.html to do some other things rather than pagination? For example, index.html only serves as home page, and it has a link to say archive.html, where archive.html serves as the first page that contain say 5 posts? How to achieve this then? This will not work if Jekyll indeed generate index.html from the root index.html, because in the case of my question, every index.html under the page folder will contain just the link.

This might be becuase I haven’t checked out all the details of Jekyll, so I will just leave it here and again, if anyone already know the answer, please leave your comment, thanks.

Update Solution: create a sub folder say ‘sub’ and create the index.html page under ‘sub’ with the nagivation code, adjust the root index.html with whatever you want (other contents that is not for navication). This directs the first page of the navigation to baseurl/sub and enable us to show other stuff on our home landing page.

Add Next and Previous Post Links

Well, if we already have the pagination, why not add next and previous post links as well? So here we go:

  1. Add the following code in the layout file used by your post (those .md files):
<div class="pagination">  
  {% if page.previous.url %}  
    <a class="prev" href="{{page.previous.url}}">&laquo; {{page.previous.title}}</a>  
  {% endif %}  
  {% if %}  
    <a class="next" href="{{}}">{{}} &raquo;</a>  
  {% endif %}  

The above code will display links of next and previous post with texts of the posts’ title. And that’s it! Jekyll already exposes what we need in the page object, so just use it.

Additionally, we can add css to customize the next and previous post link. We can directly add css code for the class pagination in the say style.scss file (note scss is a super set of css, so we can directly use whatever valid css code there). I ll leave this to the readers.


So in this post, I discussed the steps to enable and add jekyll pagination, next and previous post links as well as some trouble shooting notes, please feel free to share your comments too.

Written on December 31, 2015