How To Add Numeric WordPress Pagination

How To Add Numeric WordPress Pagination

WordPress Pagination Done Right

In this post I’m going to provide you how to add numeric WordPress Pagination to your blog roll page, without relying on any plugins. The numeric pagination code I am going to provide is the code used on this site (if you click blog at the top, and scroll to the bottom you will see what I’m talking about). I am writing this post because I find more often than not, people have a difficult time adding pagination to an existing site. I always come across at least one or two posts a day in the Support Forums asking something like “How do I add pagination to my blog page?”, “How can I add those numbers to the bottom of my blog page so users can navigate between posts?” or “How can I split my blog into multiple pages?”. It seems most people prefer the numeric WordPress pagination as opposed to the default ‘Previous Page’ and ‘Next Page’ pagination with no real feedback of the current page the user is on.

The basic pagination with the two links ‘Next Page’ and ‘Previous Page’ are easy to implement, and the codex pages on them are great, but they don’t look all that great. And think about when a user reaches your page, finds an article on page 8 and leaves. They come back only to realize they have to continuously hit ‘Next Page’ until they reach the proper page containing that post. Imagine how frustrating and annoying that would be. This is poor UX design and should be avoided, as it could potentially deter users from coming back in future.

Initial Setup: The Custom Query

The first, and most important step of the pagination process, is to make sure that you have set up your custom WP_Query properly and the query is returning post data. Here is a basic example of a query being run:

Note: The code above is for example use only. The styles will be all messed up if you copy and paste it directly as is. You can adjust it as needed if you choose too. Also take not of the variable that we are storing our query in, $custom_query, as this will be used to display pagination for that specific query.

At the top of our query take not of the $paged variable being set, and then being used inside of our custom query. This is necessary to dictate to WordPress which page of the pagination we are currently on. Without these two declared, the numeric WordPress pagination will fail every time.

Pagination Styles

These styles go directly into your theme or child themes main .CSS file. These styles are what dictate the way the pagination is rendered on the front end of our site.

I’ve added comments throughout the CSS declarations for easily swapping out the colors to match your theme, or changing the styles to the needs of your site. Go ahead and paste the above code into your themes main .CSS file.

The Pagination Function

The code below is all of the code required for our pagination to function properly. This is what processes the returned query data, and spits out our pretty pagination. Copy and paste this code directly into your Functions.php file, as is. Nothing needs to be changed.

Display The Numeric WordPress Pagination

Now everything is set up. Wherever you want the numeric pagination to appear on your page, place the following block of code directly in your theme or template file: (Keeping in mind the name of our variable that we have stored all the post data returned by our query in, $custom_query. If you’ve named your query variable something different, remember to swap it out for the correct name or nothing will display.)

Your numeric WordPress pagination should now appear and you should be seeing something like this:
How To Add Numeric WordPress Pagination


Thanks for dropping by to check out our latest tutorial. If you’ve followed the directions outlined above you should now have functioning numeric WordPress pagination on your page. If you’ve found this tutorial at all useful or helpful, I’d love to hear about it in the comments.

About the Author

Evan Herman

Evan is a full time WordPress developer at Yikes Inc. where he makes all sorts of cool things with WordPress. When he’s not there you can find him developing awesome plugins, blogging about WordPress or hanging out with his three cats and amazing girlfriend in Philadelphia, PA.

  • agnes

    I am noobs in any kind programming, is there any way to filter content on wordpress sidebar so only contents with specific (certain) categories (or tags) will be displayed ?
    let say, I (will) have a blogs about cooking, I dont want the article about “food history” to be appeared in my sidebar, I just want this article to show up on my main page

    • Hi Agnes,

      There are a ton of plugins that can create custom queries for you using only a short code. Take a look in the WordPress plugin repository. I’m sure their are other plugins that display custom categories or tags in the sidebar. Do a search for a recent post widget plugin.


  • Kevin

    Hi Evan,

    Thanks for providing this example. Whenever I click on a page greater than 1 the correct posts are shown; but I see “Page not found” in the html title.

    • Kevin

      Nevermind — I found it’s a WP issue if you use posts_per_page

      • Ah, I wasn’t sure what the reason could be. Thanks for posting the resolution!

      • Fernando

        Hi, how did you end up fixing this? I’m having the same issue, please let me know, thanks.

  • i was added it to my custom template… navigation is appearing fine and page url is updates to like blog/page/1/ but issue is on changing the pagination the page content remains static doesn’t changes… can you tell possible issue in that?

  • Nice tutorial, helped me crack pagination on custom post templates. Just add a semicolon after first line while defining paged variable !! Many thanks

    • Thanks for taking the time to leave a reply! I’m glad that this post helped you better understand the WordPress query and setup a paginating system! In the next couple of weeks I should have a new, updated version of this tutorial.

      I’ve also gone ahead and updated the code to add a semi-colon to the first line. Thanks for catching that!


  • Rohit Kumar

    I wrote this much code to display custom posts(all dummies) to show up on a single page. Only ‘posts_per_page’ => 5 seems to be working as posts appearing are only 5 or whatever number i set. I could not get pagination. In fact it is not even showing! please help

    (show_Cposts.php file)

    ‘post_type’ => ‘do_custom’,
    ‘order_by’ => ‘post_date’,
    ‘paged’ => $paged
    $posts = get_posts( $args );
    foreach ( $posts as $post ) : setup_postdata( $post ); ?>
    <a href="”>

    } ?>

  • Rohit Kumar

    please check this code. i wanted to show some dummy custom posts over a single page in wp. it seems that only ‘posts_per_page’ => 5, is working properly as i could get the number of posts i set here. But no pagination by using the above process with this simple code. Pagination not even showing.

    • Hi Rohit,

      the code that you provided is simply a WordPress query and loop. I don’t see the code there to display your pagination.

      I don’t see the code referenced in the article:


      • Rohit Kumar

        sorry but i have checked what you said.
        this: pagination($custom_query->max_num_pages); is on line 25.
        And as i used $posts to fetch posts that is why i used ‘pagination($posts->max_num_pages);
        or should i use some other way?!

        • If the pagination is not displaying properly when passing in ->max_num_pages, but works when you pass in $pages->10, then something is most likely wrong with your query.

          It sounds like the query isn’t returning any posts, so therefore the pagination is not displaying properly.

      • Rohit Kumar

        one thing to add here is: i am able to call pagination function.
        the line ‘ $pages = $wp_query->max_num_pages;’ in functions.php is giving total posts equal to null. But when i pass static value to $pages like $pages->10, everything goes fine. what do you think? where could be the error?

    • Rohit Kumar

      i am new and didn’t knew that. Let me try it. and thanks for replying.

  • quantum-mech

    Hi Evan,

    How do I set Pagination for Page Post Type,

    currently I am using something like this

    $descendants = get_pages(array(‘child_of’ => $ancestor_id));

    $parent = get_the_title($post->post_parent);

    $pagelist = get_pages(‘sort_column=menu_order&sort_order=asc’);

    $pages = array();

    foreach ($pagelist as $page) {

    if (($page->post_parent == $ancestor_id) ||

    ($page->post_parent == $post->post_parent) ||

    ($page->post_parent == $post->ID))


    $pages[] += $page->ID;



    $current = array_search($post->ID, $pages);

    $prevID = $pages[$current-1];

    $nextID = $pages[$current+1];

    <a href="


    <a href="



    • Hi Quantum-mech,

      It looks like the code you’ve provided is using get_pages() which is set to query all pages on your site.

      You’ll notice in the code above we’re using WP_Query() ( to query posts based on the post_type set in the database. If using WP_Query you can simply pass ‘post_type’ => ‘page’ to the query arguments.


      • quantum-mech

        Hi Evan,
        Thanks for prompt reply.

        You meant I can use this based on your code above ?

        $args = array(

        ‘posts_per_page’ => 1,

        ‘paged’ => $paged,
        ‘post_type’ => ‘page’


        How do I define to Ancestor Id though ?

        Many thanks!

        • Hi Quantum-Mech,

          The easiest way to get ancestor IDs is by using the built in function get_post_ancestory( $post_ID ); ( You should pass in the parent page ID and the function will return an array of all the ancestor posts of the parent page.

          Or alternatively, within WP_Query you can pass in a pagename parameter which accepts the slug of the parent page. For example, if your parent page was named ‘Checkout’
          you could retreive all child pages of ‘Checkout’ by doing something like the following:

          $args = array(
          'posts_per_page' => -1,
          'paged' => $paged,
          'post_type' => 'page'
          'pagename' => 'checkout'

          $query = new WP_Query( $args );


          • quantum-mech

            Thanks Evan, Ill try that out!

  • Tanoy Bhowmick

    Thanks a ton !! Your code rescued me. This works fine!

  • Pause

    Thanks dudue

  • Alex

    Thanks for providing this info! I’ve followed every step to the letter and am having no results. I’d attach the pastebin, but it doesn’t seem to recognize that file type. Here is the code in the page I’m trying to activate this in. Any idea what’s going wrong?

    global $data;
    get_header(); ?>
    <div id="main" class="”>

    <div id="post-frame" class="”>


    ‘wcblog’, ‘posts_per_page’ => 2);
    $loop = new WP_Query($args);

    if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); /* Queue posts */?>

    <div id="post-article" >

    <div id="post-article" >

    <a class="meta-section" href="”>

    <a class="blog-title" href="”><h3 >

    } ?>

  • Amarjeet Singh

    Thanks Buddy πŸ™‚

  • superkams

    hello evan, im having a problem when i put ‘offset’ => #

    the offset is working but the pagination will not working anymore

  • intra


    I’ve followed your tutorial. works fine. I have the page counter, and the pages number. But the next / previous / last buttons are not displayed. do you know why ?
    would be really helpful if you can get back to me !

    • Nelly

      Intra help me okay. I’m done implementing the codes except the last one:
      } ?>

      where or how do I implement that code?

  • Pingback: wordpress custom numeric pagination next / previous / last not showing - WordpressHub()

  • Max Yenin

    I added the code to the page and then pagination appeared, but when I click on page/ 2/ error 404 appears. Could you help me to solve this problem?

  • Hey, thanks for this. But the scroll jacking on your site is obnoxious,

    • Thanks Phil. Looking into it.

  • Robert Allen Baker

    Hi Evan, this is awesome, thank you. Saves downloading a plugin.

    Question, How do I add classes to the page number links themselves? (1 2 3 4 5…)

    • Hey @robertallen919:disqus you can easily add classes to the number containers on line 30 in the code above.

      echo ($paged == $i)? ““.$i.”“:”“.$i.”“;

      You can add additional classes alongside ‘current’ and ‘inactive’. That line is the numbers wrapped in a tag.

      Let me know if that helps!

  • Luan Tonin Galvan

    Great Tutorial! Thanks! You saved-me

    • Awesome! So glad I could help out πŸ™‚

      Have a great day!

  • Poonam Bhosale

    Thanks. It works Fine.

  • Mahesh Kumar

    Wow Awesome Tutorial…

  • Jawwad Rizwan

    Thanks So Much .. it works 100%
    Saved my lot of time … πŸ™‚