How To Add Infinite Scroll On Single Posts In WordPress?

Infinite scroll is a feature to automatically load the 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 set up 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 to the feature demo link below, which is just a plain WordPress site using the 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 identify 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 the 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 the infinite scroll on a single post page now! You can further customize 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.

Similar Posts

Leave a Reply

Your email address will not be published.