Adding Ajax loading and pagination to WordPress comments significantly improves user experience by making comment browsing smoother. This article explains how to implement this effect using pure code, without relying on plugins.
The final result is shown below: clicking the 'Load More' button loads older comments without refreshing the page.

Prerequisites
Before starting, ensure comment pagination is enabled in your WordPress admin. Navigate to: Settings → Discussion → Other comment settings, check 'Break comments into pages' and set the number of comments per page.

Implementation Steps
1. Add the 'Load More' Button and Script
First, locate the comment list output in your theme's comment template file (usually comments.php). Find the paginate_comments_links() function or the <ol class="comment-list"> tag. Add the following PHP code after it:
$cpage = get_query_var('cpage') ? get_query_var('cpage') : 1;
if( $cpage > 1 ) {
echo '<div class="comment_loadmore">Load More Comments</div>
<script>
var ajaxurl = "' . esc_js( admin_url('admin-ajax.php') ) . '",
parent_post_id = ' . get_the_ID() . ',
cpage = ' . $cpage . '
</script>';
}
Explanation:
$cpagegets the current comment page number, defaulting to 1 (the latest comments page).- The condition
if( $cpage > 1 )ensures the 'Load More' button and necessary JavaScript variables are only output when older comment pages exist. - We securely obtain the Ajax handler URL via
admin_url('admin-ajax.php').
2. Write the Ajax Loading jQuery Script
Add the following jQuery code to your theme's JavaScript file or as an inline script in the page footer (ensure jQuery is loaded first).
jQuery(function($){
// Load More button click event
$('.comment_loadmore').click( function(){
var button = $(this);
// Decrement the current comment page to load older pages
cpage--;
$.ajax({
url : ajaxurl,
data : {
'action': 'cloadmore',
'post_id': parent_post_id, // Current post ID
'cpage' : cpage, // Comment page number to load
},
type : 'POST',
beforeSend : function ( xhr ) {
button.text('Loading...'); // Button state feedback
},
success : function( data ){
if( data ) {
// Append newly loaded comments to the existing list
$('ol.comment-list').append( data );
button.text('Load More');
// Remove button if it's the first page (oldest comments)
if ( cpage == 1 ) {
button.remove();
}
} else {
// Also remove button if no data is returned
button.remove();
}
},
error: function() {
button.text('Load failed, please retry');
}
});
return false;
});
});
Key Point: The code uses cpage-- because WordPress comment pagination defaults to reverse chronological order, with the newest comments on page 1. Clicking 'Load More' needs to load pages with smaller numbers (i.e., older comments).
3. Create the Ajax Request Handler Function
Finally, add the following PHP code to your theme's functions.php file. This function handles the front-end Ajax request and returns the comment list HTML.
// Register Ajax handler hooks for logged-in and non-logged-in users
add_action('wp_ajax_cloadmore', 'comments_loadmore_handler');
add_action('wp_ajax_nopriv_cloadmore', 'comments_loadmore_handler');
function comments_loadmore_handler() {
// Security check: verify nonce (recommended for production)
// if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'cloadmore_nonce' ) ) {
// die( 'Security check failed' );
// }
// Get and set up current post data
$post_id = absint( $_POST['post_id'] );
$post = get_post( $post_id );
if ( ! $post ) {
die( 'Invalid post.' );
}
setup_postdata( $post );
// Set comment query parameters
$cpage = absint( $_POST['cpage'] );
$comments_per_page = get_option( 'comments_per_page' );
// Output the comment list for the specified page
wp_list_comments( array(
'avatar_size' => 100,
'page' => $cpage,
'per_page' => $comments_per_page,
'style' => 'ol',
'short_ping' => true,
'reply_text' => 'Reply',
'callback' => 'your_theme_comment_callback' // Replace with your theme's actual callback function name
) );
wp_reset_postdata(); // Reset post data
die(); // End output
}
Important Notes:
- The
wp_ajax_{action}andwp_ajax_nopriv_{action}hooks handle requests for logged-in and non-logged-in users respectively. - For production environments, it is strongly recommended to add nonce verification (example commented in the code) to prevent CSRF attacks.
- Replace the
'callback'parameter value'your_theme_comment_callback'inwp_list_commentswith your theme's actual comment callback function name to ensure consistent comment styling.
Summary
Through these three steps, we have implemented a pure-code Ajax loading and pagination feature for WordPress comments. The core principle utilizes WordPress's native admin-ajax.php mechanism: the front-end makes requests via jQuery, and the back-end queries comments for the specified page and returns an HTML fragment.
This method is plugin-free, performant, and integrates better with your theme's styling. You can further customize the 'Load More' button style or add loading animations as needed.