Support Home > Appearance > Infinite Scroll

Infinite Scroll

Instead of having to click a link to get to the next set of posts, infinite scrolling pulls the next posts automatically into view when the reader approaches the bottom of the page.

Unlike many of the features in Jetpack, Infinite Scroll only works with themes that support it. Since each theme is constructed a bit differently, the Infinite Scroll feature needs information about the theme to function properly.

NOTE: Most themes nowadays have Infinite Scroll support built in already! To check to see if your theme supports Infinite Scroll, go to JetpackSettingsWriting in your site’s Dashboard and look under the “Theme enhancements” section.

Infinite Scroll supported by the theme

If your theme does not have Infinite Scroll support built in, read on for detailed instructions on adding support to your theme, plus using CSS to customize the look.

Infinite Scroll not supported by the theme

Adding Support

Jetpack Infinite Scroll is not supported for block themes.

For classic (non-block) themes, enabling Infinite Scroll is very similar to adding support for post thumbnails or editor styles, since we make use of add_theme_support(). By providing a few key pieces of information when calling add_theme_support(), Infinite Scroll will seamlessly integrate with your theme. Here is how it’s done for the Twenty Twelve default WordPress theme:

add_theme_support( 'infinite-scroll', array(
 'container' => 'content',
 'footer' => 'page',
) );

With that you get a fully functioning Infinite Scroll experience.

container

The container parameter is the core of adding Infinite Scroll to your theme: it specifies the ID of the HTML element to which Infinite Scroll should add additional posts to. The default value is content, but can be any valid CSS ID that appears in the supported theme and is appropriate for appending posts to. Usually, this’ll be the parent container of the posts in your theme.

footer

One of the issues with Infinite Scroll is that you can’t access the footer of a page, since whenever you approach the end, new posts are loaded. Our infinite scroll comes with a fixed footer that slides in once you scroll down the page. The footer parameter helps blend this footer with your theme design. By passing another ID, the infinite scroll footer will match its width so that it fits perfectly in your design. If you pass a false value instead, no new footer would be added.


There are also other parameters you can tweak—here is an example showing all the default values for each configuration option:

add_theme_support( 'infinite-scroll', array(
 'type' => 'scroll',
 'footer_widgets' => false,
 'container' => 'content',
 'wrapper' => true,
 'render' => false,
 'posts_per_page' => false,
) );

Breaking down each option:

type

type accepts two different values: scroll or click. This controls the default Infinite Scroll behaviour. scroll will cause posts to be loaded automatically when the visitor approaches the bottom of the current list of posts, while click shows a Load more posts button, letting the user control when more posts are loaded.

scroll is the default, but if a theme has footer widgets, this could be overridden to click so the widgets are accessible.

footer_widgets

The footer_widgets argument accepts a variety of values and indicates whether or not a theme has footer widgets. If footer widgets are present, the scroll type will be set to click so the widgets are accessible.

At its simplest, either a boolean true or false can be set if the footer should always or never be shown, respectively.
Additionally, either a string representing a sidebar ID ('sidebar-1', for example), or an array of sidebar IDs will be accepted by the footer_widgets argument. The Infinite Scroll code will check if the sidebar(s) contain widgets and set the footer_widgets argument accordingly.

Whenever possible, we highly recommend providing sidebar IDs if a theme places widget areas below the post list. Doing so provides the best experience for the theme’s users by dynamically determining whether the scroll type should be scroll or click. That said, if a theme specifies click as the type from the outset, then the footer_widgets argument can safely be omitted.

If all of those options weren’t enough, the infinite_scroll_has_footer_widgets filter is available for advanced logic. The filter must return a boolean value, and could be used to detect the presence of nav menus, or a visitor using a mobile device.

wrapper

The wrapper argument behaves similarly to footer_widgets, in that it accepts a few different values. This argument determines whether or not each set of additional posts is contained within a div element when appended to the container specified in the preceeding argument.
If a boolean value (true or false) is specified, either a div with the class infinite-wrap is placed around the additional posts, or it isn’t.

To wrap the posts in a div with a custom class, set the wrapper argument to a string representing the custom class.
Please note that the wrapper argument only accepts a single string with no whitespace.

It is generally good practice to wrap the appended posts in a div, unless doing so will result in invalid markup. For example, if a theme uses a list element (ol, ul) to display posts, the wrapper should be disabled so that div elements don’t appear where they don’t belong.

Render

Infinite Scroll uses a standard WordPress loop to render the additional posts it appends, and utilizes template parts in the content-{post format}.php form. If a theme includes at least content.php, then the render argument can be omitted. Below is the default rendering function Infinite Scroll uses:

while( have_posts() ) {
the_post();
get_template_part( 'content', get_post_format() );
}

If greater customization is needed, or a theme doesn’t use the content template parts, a function name should be specified for the render argument and that function will be used to generate the markup for Infinite Scroll. The function must include the while() portion of WordPress’ loop and can utilize any function available to the theme when it renders posts.

posts_per_page

By default, the type argument controls how many posts are loaded each time Infinite Scroll acts. For the scroll type, seven (7) posts are loaded each time Infinite Scroll is activated. For the click type, a site’s “Blog pages show at most” value found under Settings → Reading is used.

If, however, a theme’s layout expects a certain number of posts, the posts_per_page argument will override the defaults discussed in the preceding paragraph. This control is beneficial, for example, in a theme with a three-column layout where greater or fewer than three posts would result in an uneven layout.

Examples

With as wide a variety of themes and themers as exists, we aimed to provide enough control over how Infinite Scroll behaves as is necessary to support many themes. That said, our experience on WordPress.com showed that generally, each theme needs very few configuration options. To demonstrate, we’ve provided the Infinite Scroll configuration of WordPress default themes.

Twenty Twelve

/**
 * Add theme support for infinite scroll.
 *
 * @uses add_theme_support
 * @return void
 */
function twenty_twelve_infinite_scroll_init() {
    add_theme_support( 'infinite-scroll', array(
        'container' => 'content',
    ) );
}
add_action( 'after_setup_theme', 'twenty_twelve_infinite_scroll_init' );

For those unfamiliar with the Twenty Twelve theme, it uses content-{post format}.php template parts and has no widget area below posts, so we’ve omitted the footer_widgets and render arguments. In reality, since the container value matches the default, that argument could be omitted as well; we’ve left it for clarity.

Twenty Eleven

/**
 * Add theme support for infinity scroll.
 */
function twenty_eleven_infinite_scroll_init() {
    add_theme_support( 'infinite-scroll', array(
        'container' => 'content',
        'footer_widgets' => array( 'sidebar-3', 'sidebar-4', 'sidebar-5', ),
        'footer' => 'page',
    ) );
}
add_action( 'after_setup_theme', 'twenty_eleven_infinite_scroll_init' );

Twenty Eleven comes with footer widget areas, which wouldn’t be reachable when you scroll down as new posts would be added whenever you reached the bottom. To solve this, we pass an array with the IDs of those widget areas to footer_widgets. Now, if one of those sidebars has a widget, our Infinite Scroll plugin will detect it, and switch to the click type automatically (where you click to load more posts on demand), so your footer content is still perfectly accessible. If your theme has footer widgets, consider this approach as you greatly improve the experience of your users.

Twenty Ten

/**
 * Add theme support for infinity scroll
 */
function twenty_ten_infinite_scroll_init() {
    add_theme_support( 'infinite-scroll', array(
        'container' =>'content',
        'render' => 'twenty_ten_infinite_scroll_render',
        'footer' => 'wrapper',
    ) );
}
add_action( 'after_setup_theme', 'twenty_ten_infinite_scroll_init' );

/**
* Set the code to be rendered on for calling posts,
* hooked to template parts when possible.
*
* Note: must define a loop.
*
function twenty_ten_infinite_scroll_render() {
get_template_part( 'loop' );
}

Twenty Ten uses a slightly different template structure to render posts, so we need to provide a custom render function to infinite scroll.

Do It With Style

The last missing piece is how to make Infinite Scroll blend perfectly with your site design. Infinite Scroll relies on the theme supporting body_class, and it provides theme developers with the utmost flexibility to improve the experience by using some specific body classes: whenever Infinite Scroll is active there will be an infinite-scroll class available on body; if the Infinite Scroll type is “scroll”, there will also be a neverending class too. Once the last post in a blog has been loaded, there will be an infinity-end class added. With these, you can hide your regular footer and navigation links, and show them again when Infinite Scroll is finished. Example:

/* Hides navigation links and site footer when infinite scroll is active */
.infinite-scroll #navigation,
.infinite-scroll.neverending #footer {
 display: none;
}
/* Shows the footer again in case all posts have been loaded */
.infinity-end.neverending #footer {
 display: block;
}

There are also two elements that you’ll want to style so that they fit in with your theme:

span.infinite-loader is the loading indicator that is displayed while new posts are being retrieved. It is inserted as a child of container, and it is possible that after it is no longer needed, it will be hidden rather than removed from the DOM. Ensure that your CSS handles both cases.

div#infinite-handle is the Load more posts button shown for type=click. You can ignore this if your theme will always use type=scroll and will never have any footer widgets.

JavaScript Events

Inevitably, there are situations in a theme that require some JavaScript interaction after posts are added. One such example is in a theme that uses jQuery Masonry and needs to trigger that library to position the additional posts. Recognizing this need, we trigger an event after posts are appended. To make use of this event, simply catch the post-load event when it fires on document.body:

( function( $ ) {
 $( document.body ).on( 'post-load', function () {
 // New posts have been added to the page.
 } );
} )( jQuery );

Add custom arguments to the Infinite Scroll query

Some themes and plugins add extra arguments to post queries, often to change the way the posts are sorted or loaded. You can use the infinite_scroll_query_args filter to add those extra arguments to Infinite Scroll as well. In the example below, we’ll add 2 custom ordering parameters, order and orderby:

/**
 * Sort all Infinite Scroll results alphabetically by post name
 *
 * @param array $args
 * @filter infinite_scroll_query_args
 * @return array
 */
function jetpack_infinite_scroll_query_args( $args ) {
 $args['order'] = 'ASC';
 $args['orderby'] = 'name';
 return $args;
}
add_filter( 'infinite_scroll_query_args', 'jetpack_infinite_scroll_query_args' );

Troubleshooting

I have Infinite Scroll set to Load more posts as the reader scrolls down, but instead it shows an “Older Posts” button.

Does your theme have footer widgets? If you have any widgets in the footer widget area, Infinite Scroll will switch to using the “Older Posts” button automatically, to ensure that the footer widgets can be viewed on your site. If you want posts to load as you scroll down, you can place widgets in an alternative widget area, such as the sidebar. If your theme has only footer widget areas, you may wish to look for a different theme with more widget area options.

Other notes

Recognizing that this feature requires theme support to be useful, we’ve bundled support into Jetpack for the default WordPress themes prior to the Twenty Twenty-Two theme. (Twenty Twenty-Two and Twenty Twenty-Three are default WordPress themes as well, but they are block themes, which are not compatible with Infinite Scroll.)

If you are using an Infinite Scroll-compatible default theme, you can enable the Infinite Scroll and enjoy this feature immediately. If you are using one of the Automattic themes from WordPress.org, they should be updated already with Infinite Scroll support (the feature card will provide a prompt to users who can upgrade themes if the active theme has an update available).

Privacy Information

Infinite Scroll is deactivated by default. If you ever need to activate it, toggle the Load more posts using the default theme behavior setting in the Theme enhancements section at Jetpack — Settings — Writing.

Data Used
Site Owners / Users
In order to record page views via Jetpack Stats (which must be enabled for page view tracking here to work) with additional loads, the following information is used: IP address, WordPress.com user ID (if logged in), WordPress.com username (if logged in), user agent, visiting URL, referring URL, timestamp of event, browser language, country code.
Site Visitors
In order to record page views via Jetpack Stats (which must be enabled for page view tracking here to work) with additional loads, the following information is used: IP address, WordPress.com user ID (if logged in), WordPress.com username (if logged in), user agent, visiting URL, referring URL, timestamp of event, browser language, country code.
Activity Tracked
Site Owners / Users
Page views will be tracked with each additional load (i.e. when you scroll down to the bottom of the page and a new set of posts loads automatically). If the site owner has enabled Google Analytics to work with this feature, a page view event will also be sent to the appropriate Google Analytics account with each additional load.
Site Visitors
Page views will be tracked with each additional load (i.e. when you scroll down to the bottom of the page and a new set of posts loads automatically). If the site owner has enabled Google Analytics to work with this feature, a page view event will also be sent to the appropriate Google Analytics account with each additional load.
Data Synced (Read More)
Site Owners / Users
We sync options that identify whether or not the feature is activated and whether or not Google Analytics is integrated with this feature.
Site Visitors
None.
  • Table Of Contents

  • Contact Us

    Need more help? Feel free to contact us.