How to add Pagination to a WordPress Page?

Pagination in WordPress is not useful just to provide a better on-page user experience but it also benefits in reducing page load times. In this guide, we’ll demonstrate how to implement pagination to a WordPress custom page template that lists posts from a specific category. Adding pagination to a WordPress page template is a straightforward process using WP_Query and the WordPress’ paginate_links() function to display pagination controls: Copy the below code and add in a file of your theme directory (e.g. news.php)

<?php
/*
Template Name: News
*/
?>
<?php get_header(); ?>
<?php
// Step 1: Define the arguments for the WP_Query
$args = array(
    'post_type' => 'post',                // 1. We're fetching WordPress posts
    'category_name' => 'news',            // 2. Filter posts by the "news" category
    'posts_per_page' => 3,                // 3. Show 3 posts per page
    'orderby' => 'date',                  // 4. Sort the posts by the date they were published
    'order' => 'DESC',                    // 5. Show the newest posts first
    'paged' => get_query_var('paged') ? get_query_var('paged') : 1,  // 6. Handle pagination (move to the next page of posts)
);


// Step 2: Create a new WP_Query object with the defined arguments
$query = new WP_Query($args);


// Step 3: Check if there are posts to display
if ($query->have_posts()) :
    // Step 4: Start a list to display the posts
    echo '<ul>';
   
    // Step 5: Loop through each post and display it
    while ($query->have_posts()) : $query->the_post();
        // 6. Show the title of the post with a clickable link to the post page
        echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
    endwhile;
   
    // Step 7: Close the list
    echo '</ul>';


    // Step 8: Add pagination controls (Next and Previous pages)
    $big = 999999999; // need an unlikely integer
    echo paginate_links( array(
        'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
        'format' => '?paged=%#%',
        'current' => max( 1, get_query_var('paged') ),
        'total' => $query->max_num_pages
    ) );


else :
    // If no posts are found, show a message
    echo 'No posts found.';
endif;


// Step 9: Reset post data (to avoid interfering with other loops on the page)
wp_reset_postdata();
?>
<?php get_footer(); ?>