What I'm trying to do:
Print the pagination links on the home, which uses template index.php, with pagination functions such as paginate_links(), outside The loop.

What happens instead?
Instead of getting the pagination links, paginate_links() just returns NULL.

This would be ok if there was no pagination, I.E. there are fewer posts found by the query than the max posts per page setting.

But there are actually 10 posts found (paginate_links() == 10) and only 5 are showing ($wp_query->query_vars['posts_per_page'] == 5) so it's evident that some kind of pagination is actually happening.

If I set max posts per page to 10, all 10 posts show up on the home.

My code
There's no significant code to post, but this is it:

if( have_posts() ) {
    while( have_posts() ) {
echo paginate_links();
  • 2
    "What am I doing wrong?" -- Well, to start, you aren't posting the code would allow us to answer that question.
    – s_ha_dum
    Commented Mar 16, 2014 at 1:11
  • 1
    I'm not making this an answer because I'm not clear on what you're actually trying to do, but my first thought is that is_paged() and paginate_links() don't do what you're thinking they do -- the first checks whether you're on the second page of results or later, and the second is used to output links, not to alter the query in any way.
    – sabreuse
    Commented Mar 16, 2014 at 4:14
  • 2
    Please post your code... Commented Mar 16, 2014 at 4:41
  • I know what paginate_links() does, it doesn't actually output anything, it should return the pagination links, but as I posted, it returns NULL, so something is not working. I don't have any particularly interesting code to post as I'm just trying to output the pagination links, but the function that does that just returns NULL. It's outside The loop, in the index.php template, I'm calling it from the home, so it's the site's root /
    – Petruza
    Commented Mar 16, 2014 at 5:02
  • 3
    If you are simply adding paginate_links(); with no parameters then you are doing it wrong. but again… show us your code.
    – Milo
    Commented Mar 16, 2014 at 5:19

1 Answer 1


paginate_links() is not a template/Loop tag like the_title() or next_posts_link(). It is a general purpose pagination function. It does not do anything if given zero parameters. It does not assume data from the main query, or from any other query, if passed zero parameters. It just does nothing. You can see that if you read the source for the function.

Yes, technically all parameters are optional, but the defaults output nothing which, again, you can see in the source. The default total argument is 1 but...

2017          $total = (int) $total;
2018          if ( $total < 2 )
2019                  return;


If you want to use paginate_links() you have to pass it a set of arguments appropriate to your data/query. If you want to use this with the main query, as it appears you do, there is an example in the Codex that does just that:

global $wp_query;

$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' => $wp_query->max_num_pages
) );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.