Recently I updated the Scott Logic blog to implement infinite scrolling using a combination of Jekyll pagination and jScroll. Both of these components are quite fussy about their respective configuration, meaning that integrating them took longer than expected. I thought I’d share my solution in this blog post, hopefully saving others from the hours I spent digging into jScroll code or cursing Jekyll!
For a quick example integration I’ve created a demonstration site on with the sourcecode available on GitHub. You can see the rendered output below:
NOTE: The above iframe
will no doubt render quite incorrectly on a mobile browser, so you might want to visit the example project’s generated site directly instead.
Pagination with Jekyll
In order to paginate the index page (index.html
) of a Jekyll site all you have to do is add the paginate property to the sites configuration:
This will cause the posts to be divided into pages and made accessible via the paginator
object. Rendering the posts from a page is quite straightforward, rather than iterating over the contents of site.posts
, instead iterate over paginator.posts
:
Generating your site using the pagination option results in Jekyll creating multiple copies of the index page, each containing the posts for the given page. The first page, index.html
resides in the usual location, whereas subsequent pages reside in numbered sub-folders starting at page2
:
This slightly peculiar structure makes the next part a little more tricky …
The paginator
object contains various other properties that can be used to render previous / next links to allow the user to navigate between the various pages. The following template can be used to render navigation links, notice the special casing for page #2 in order to navigate back to index.html
, rather than page1/index.html
, which does not exist!
With the above code in place you can support pagination with Jekyll. The next step is integration of jScroll to give infinite scrolling!
jScroll
jScroll is a jQuery plugin that works by magic, just add the following line of code to your site:
And Hey Presto! Infinite scrolling (it’s SEO friendly too *rolls eyes*). Well, that’s the theory.
Unfortunately, in practice jScroll is very sensitive to the way in which you structure the page so that it can work its magic. If your configuration or structure isn’t correct, it fails silently and the only option is to delve into the code to find out what it expects.
Don’t get me wrong, I think jScroll is very neat. It’s simple and lightweight, but relies heavily on opaque conventions. In this post I’ll describe some of the inner-workings of jScroll and show how to make it play nicely with Jekyll.
The way jScroll works its magic is actually pretty simple. When you instantiate the jScroll plugin from a DOM element, it searches for the link that is used to navigate to the next page. It then adds a few structural div
elements that it uses for content insertion and tracking scroll location. When the user scrolls to the bottom of the screen jScroll adds a loading indicator, and fetches the next page via an XHR request. The contents of the response are then added to the page.
A few things you need to ensure are:
- That the pagination links are within the DOM element used to construct jScroll. By default, it will search for the last anchor within this element and assume that the
href
attribute of this points to the next page. This is all a bit too ‘magic’ for my tastes, so I prefer to pass thenextSelector
configuration option to jScroll, so that it can unambiguously locate the next link. - jScroll hides the pagination controls when it is created. It assumes that the parent of the ‘next’ anchor element contains the pagination controls. As you can see in my template above, the
div
with classpagination
is the direct parent of the next anchor, so this structure is fine. - When jScroll fetches the next page, it will fetch an entire HTML page, e.g.
page2/index.html
. In order to update the current page it needs to identify the page fragment to extract and insert into the current page. This is achieved via thecontentSelector
configuration property.
As a result, the following jScroll configuration is suitable for paginating a Jekyll site:
One other issue I found with jScroll is that when you reach the final page, it doesn’t hide the pagination links. I fixed that in a fork of jScroll, I’ll raise a pull request shortly :-)
Hopefully this blog post will help anyone else who is trying to integrate Jekyll and jScroll. When it works, it’s really rather neat!
Remember to pop over to GitHub to see a fully functioning example.
Regards, Colin E.