Has anyone implemented infinite scrolling on a Hugo website?

TL,DR: I want to implement infinite scrolling in all my list.html templates if JS is enabled, and fall back to regular link based pagination if JS is disabled.


I am trying to implement infinite scrolling on my hugo website if javascript is enabled, and fall back to standard pagnation link that says “Load More Stories” if javascript is disabled.

You can see an example here.

In that site, if you have javascript enabled and keep scrolling down, you will see new stories loading, that are actually in 2nd and then 3rd page respectively.

Now if you disable javascript using a plugin like quick javascript switcher, you will see a button at the bottom that says “Load More Stories” and if you click that, the next “Page” will be loaded, with a url like http://www.viralnova.com/2 or http://www.viralnova.com/3 (depending on where you are in the scrolling.)

Has anyone implemented such a thing in a hugo site, or in any of the existing sample theme?

Thank you, any help is greatly appreciated. I’m happy to hire someone in the Services section if that what it will take.


1 Like

Extremely late reply here. I’m looking to implement it while “reading” blog posts and not on list pages. So I may be hacking this thread a bit, for that I am sorry.

Have you checked the implementation of infinite scroll in these themes?

GridSide (This one actually has what you’re looking for in its Post section)

There are some considerations that should be worked through:

  • URL should change after one has scrolled through a blog post
  • HTTP Header respons 200 OK should preferably be triggered
  • One should take care to research that Googles Crawlers index every post
1 Like

Since Hugo generates static websites, which have been being built as early as the Web is old, searching for an implementation of the following may help you find what you’re looking for: http://imakewebthings.com/waypoints/shortcuts/infinite-scroll/. Good luck!


I found that the infinite-scroll package by Mettafizzy is perfect for this use-case. It works off of paginated content to create an infinite scroll. If JavaScript is disabled the user would just continue to use the paginated content.

The library is free to use in open source projects. There is a license fee for commercial projects. See more detail on licensing.

In my case I have 7 stories per page to avoid loading lots of large images. The markup is like so:

Blog content markup

<ul class="card-list">
  <li class="card">
    <!-- Content goes here -->
  <li class="card">
    <!-- Content goes here -->
  <li class="card">
    <!-- Content goes here -->
  <li class="card">
    <!-- Content goes here -->

<!-- Pagination goes here -->

Customized pagination

I added a pagination-next class to the next button so the infinite scroll JS could find the next page of content, which it will load and append to my list. The library automatically increments page numbers to add the appropriate content as the user scrolls. It even updates the URL and relies on the history API to enable back/forward buttons on the browser.

<li {{ if not $pag.HasNext }}class="disabled"{{ end }}>
  <a href="{{ if $pag.HasNext }}{{ $pag.Next.URL }}{{ end }}" aria-label="Next" class="pagination-next">
    <span aria-hidden="true">&raquo;</span>


The beauty of this approach is the simplicity of the infinite scroll library. It just requires a little bit of info about how your pagination is set up, then takes care of the rest.

const InfiniteScroll = require('infinite-scroll'); // installed via NPM

const elm = document.querySelector('.card-list');

const options = {
  path: '.pagination-next',
  append: '.card'

const infScroll = new InfiniteScroll(elm, options);



I also struggling with this issue.
I think infinite scrolling can be done by vanilla javascript.(In my case, using jquery for my convenience)
In this code, you can get an idea for your needs.
This may not best practice but at least it works for my case

// render all summaries
<div class="summary__container">
     {{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }}
     {{ range $pages }}
          {{ .Render "summary" }}
     {{ end }}
// in your javascript code. you can use two curly braces in javascript code if you using partials templates
// like this {{ $rowsPerPage := .Site.Params.rowsPerPage }}
var summaries = $('.summary__container').children();
var rowsPerPage = JSON.parse({{ $rowsPerPage | jsonify }});
var sliceIndex = rowsPerPage;
var maxSliceIndex = summaries.length - 1;

// render first page at first.
$('.summary__container').html($('.summary__container').children().slice(0, rowsPerPage));

// since i'm using jquery and perfect scrollbar, this part depend on you
yourScrollDownEventListener.on('scroll-down', {
    if ($(this).scrollTop() + $(window).height() > $(document).height() - 600) { // if you are near the bottom
            if (sliceIndex < maxSliceIndex) { // don't want rerender if there is no more pages or article
              sliceIndex += rowsPerPage;
              $('.summary__container').html(summaries.slice(0, sliceIndex));


Instead of trying to implement infinite scroll with jQuery please have a look at https://themes.gohugo.io/

Source code the Themes Site located at: https://github.com/gohugoio/hugoThemesSite

You will see that every theme’s page in the list is already present and only images are loaded on scroll by using the lazysizes plugin.

In my opinion this is a fine workaround to infinite scrolling that has the bonus of not changing constantly the size of a desktop browser’s scrollbar, which is a bit distracting.

Also please note that since this is an old thread I am closing it.

If you require further assistance feel free to open a new support ticket.

1 Like