How To Add Infinite Scroll On Single Posts In WordPress?

Infinite scroll is a feature to automatically load next article when readers reach the bottom of the first article. It is a useful feature to increase engagement on your website. The effect is more obvious on mobile devices, where it is very convenient for visitors to keep scrolling for more articles, thus retain more visitors.

Because of this reason, recently I received a request to setup infinite scroll on a WordPress website. By Googling around, I found that there are some plugins to support infinite scrolling on WordPress main page. However, I couldn’t find a quick solution to fulfill my requirements below:

  • WordPress website
  • Infinite scrolling on single post page
  • Able to dynamically change browser URL when visitor scroll up/down among different articles

So I’ve decided to develop the feature myself and would like to share with the rest on how to do it with two simple steps. You can refer the feature demo link below, which is just a plain WordPress site using default Twenty Sixteen theme.

Infinite scroll demo page

Step 1: Identify your article content template

First, look for your theme’s single page article template. It is the HTML template to load your single page article. For Twenty Sixteen theme, the file is at /template-parts/content-single.php. For other themes, you might need to spend a little bit more effort. Below are a few tips to idenfity the file:

  • The filename usually similar to content-single.php and under template folder
  • Try to search for keyword ‘<article’ within your theme folder. WordPress single page article template usually wrap with ‘<article></article>’ HTML tag

Once you’ve found the single page article template file, insert one line of code above ‘<article>’ tag and another two lines of code below ‘</article>’ as shown below:

<div class="centil-post-header" style="display: none;" url="<?php echo esc_url(the_permalink()); ?>" title="<?php echo esc_attr(the_title()); ?>"></div>
<article>
...
</article>
<?php $centilNextPost = get_next_post(); ?>
<div class="centil-infinite-scroll" style="display: none;"><?php echo $centilNextPost->ID; ?></div>

Step 2: Append Ajax function in theme’s functions.php

The second step is to append below codes into your WordPress theme’s functions.php file. Other than the line which is highlighted in RED below, most likely you can directly copy & paste these codes. For the highlighted RED line, you’ll need to modify it to target your single page article template file earlier.

function centil_infinite_scroll($pid){
  if (is_single()) { ?>
    <script type="text/javascript" >
      jQuery(document).ready(function($) {

        $(window).scroll(function() {
          var footerPos = $('footer').last().position().top;
          var pos = $(window).scrollTop();

          // Load next article
          if (pos+(screen.height*4) > footerPos) {
            if ($(".centil-infinite-scroll").first().hasClass('working')) {
              return false;
            } else {
              $(".centil-infinite-scroll").first().addClass('working');
            }

            var centilNextPostId = $(".centil-infinite-scroll").first().text();
            var data = {
              'action': 'centil_is',
              'centilNextPostId': centilNextPostId
            };

            // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
            jQuery.post('<?php echo admin_url("admin-ajax.php"); ?>', data, function(response) {
              $(".centil-infinite-scroll").first().replaceWith(response);
            }, 'html');
          }

          // Update new URL
          var currUrl = $(".centil-post-header").first().attr("url");
          var currTitle = $(".centil-post-header").first().attr("title");

          if ($(".centil-post-header").length > 1 && history.pushState) {
            for (var i=0; i<$(".centil-post-header").length; i++) {
              if (pos+(screen.height/2) >= $(".centil-post-header").eq(i).next().position().top) {
                currUrl = $(".centil-post-header").eq(i).attr("url");
                currTitle = $(".centil-post-header").eq(i).attr("title");
              }
            }
          }
          if (location.href != currUrl) {
            history.pushState({}, currTitle, currUrl);
          }
        });
      });
    </script>

  <?php }
}
add_action( 'wp_head', 'centil_infinite_scroll' );

function centil_infinite_scroll_callback() {

  if (isset($_POST['centilNextPostId']) && $_POST['centilNextPostId']) {
    // The Query
    $the_query = new WP_Query(array('p'=>$_POST['centilNextPostId']));

    // The Loop
    if ( $the_query->have_posts() ) {
      while ( $the_query->have_posts() ) {
        $the_query->the_post();
        get_template_part( 'template-parts/content', 'single' );
      }
    }
    /* Restore original Post Data */
    wp_reset_postdata();
  }

  wp_die();
}
add_action( 'wp_ajax_centil_is', 'centil_infinite_scroll_callback' );
add_action( 'wp_ajax_nopriv_centil_is', 'centil_infinite_scroll_callback' );

That’s it! Your WordPress site should be able to use infinite scroll on single post page now! You can further customise these codes to include loading animation and others. The sky is the limit. :)

I hope this is helpful to you and please feel free to leave your comments/suggestions if you have any.

7 thoughts on “How To Add Infinite Scroll On Single Posts In WordPress?

  1. Thanks a lot for this awesome tutorial on how to add infinite scroll on single posts.But what should i do if don’t want to edit content-single.php for the step one of the tutorial.

    1. Hi Bilal, based on the method that I proposed, you can’t. Since those 3 lines of inserted codes are the one which control new posts addition to the bottom of your scroll.

  2. Hello
    you’re amazing, the only tutorial that work’s!!
    thank you so much for this.
    I stile have a question.I implemented this in a custom premium theme.
    The problem for me is that it call newer pots, for example i’m in a 2 december post, next will come the 3 dec..etc..
    and i need to get back, not forward..like 1dec, 29 nov, 28nov and so on.
    could you tell me if you know how to do this??i tried many thing with the history.pushState but don’t get it to work..
    many thanks !!!

    1. Hi virtual, the scrolling should load older posts from the bottom, instead of newer posts. I am sorry that I am not sure what causing it to load newer post in your theme.

  3. You can test the working of the plugin yourself, simply open any single WordPress post on your website and then scroll to the bottom of the page. You will notice next posts loading automatically without any click or tap.

Leave a Reply

Your email address will not be published. Required fields are marked *