How to Paginate WP_Query Results in WordPress Easily
To paginate
WP_Query results in WordPress, use the paged parameter to set the current page number and pass it to your query. Then, use functions like paginate_links() or the_posts_pagination() to display navigation links for users to move between pages.Syntax
The key to paginating WP_Query is the paged parameter, which tells WordPress which page of results to show. You also set posts_per_page to control how many posts appear on each page.
- paged: The current page number, usually from the URL query.
- posts_per_page: Number of posts to show per page.
Example usage:
php
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args = [ 'post_type' => 'post', 'posts_per_page' => 5, 'paged' => $paged ]; $query = new WP_Query($args); ?>
Example
This example shows how to create a paginated list of posts. It gets the current page number, runs a WP_Query with pagination, loops through posts, and then displays pagination links below.
php
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args = [ 'post_type' => 'post', 'posts_per_page' => 3, 'paged' => $paged ]; $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); echo '<h2>' . get_the_title() . '</h2>'; the_excerpt(); endwhile; echo paginate_links([ 'total' => $query->max_num_pages, 'current' => $paged, 'prev_text' => '« Prev', 'next_text' => 'Next »' ]); else : echo '<p>No posts found.</p>'; endif; wp_reset_postdata(); ?>
Output
<h2>Post Title 1</h2>
Excerpt text...
<h2>Post Title 2</h2>
Excerpt text...
<h2>Post Title 3</h2>
Excerpt text...
« Prev 1 2 3 Next »
Common Pitfalls
Common mistakes when paginating WP_Query include:
- Not setting the
pagedparameter, causing the query to always show the first page. - Using
get_query_var('page')instead ofget_query_var('paged'). - Not resetting post data with
wp_reset_postdata()after the custom query. - Conflicts with permalink structure causing pagination URLs to break.
Example of a wrong and right way:
php
<?php // Wrong: missing 'paged' parameter $args_wrong = [ 'post_type' => 'post', 'posts_per_page' => 5 ]; $query_wrong = new WP_Query($args_wrong); // Right: include 'paged' parameter $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args_right = [ 'post_type' => 'post', 'posts_per_page' => 5, 'paged' => $paged ]; $query_right = new WP_Query($args_right); ?>
Quick Reference
| Parameter | Description | Example Value |
|---|---|---|
| paged | Current page number for pagination | 2 |
| posts_per_page | Number of posts shown per page | 5 |
| post_type | Type of content to query | 'post' or 'page' |
| paginate_links() | Function to display pagination links | paginate_links(['total' => 10, 'current' => 2]) |
| wp_reset_postdata() | Resets global post data after custom query | wp_reset_postdata() |
Key Takeaways
Always set the 'paged' parameter in WP_Query to enable pagination.
Use get_query_var('paged') to get the current page number from the URL.
Display pagination links with paginate_links() or the_posts_pagination().
Reset post data after your custom query with wp_reset_postdata().
Check your permalink settings if pagination URLs do not work correctly.