Skip to main content

Bootstrap pagination in WordPress theme

In this tutorial I will create WordPress navigation that is styled with Bootstrap 3. If you are tired of using plugins that you constantly need to update, maybe this would be a good solution for you which you can include in your base theme.

Process is actually very simple, I will use WordPress paginate_links function.
If you want to know more you can check all info on WordPress codex so I will get straight to the point here.

The function you need to place in your functions.php file is:

function vb_pagination( $query=null ) {

  global $wp_query;
  $query = $query ? $query : $wp_query;
  $big = 999999999;

  $paginate = paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'type' => 'array',
    'total' => $query->max_num_pages,
    'format' => '?paged=%#%',
    'current' => max( 1, get_query_var('paged') ),
    'prev_text' => __('«'),
    'next_text' => __('»'),

  if ($query->max_num_pages > 1) :
<ul class="pagination">
  foreach ( $paginate as $page ) {
    echo '<li>' . $page . '</li>';

This function accepts one argument named ‘query’ so you can use it with your custom queries.
When using with standard $wp_query in index.php or archive.php for example, you only need to paste your functions name and just in case wrap it in ‘function_exists’.

if ( function_exists('vb_pagination') ) {

Custom WP_Query

When you are working with custom query then you need to pass argument to function.
Example with custom query named $my_query would look like this:


if ( get_query_var('paged') ) {
   $paged = get_query_var('paged');
} else if ( get_query_var('page') ) {
   $paged = get_query_var('page');
} else {
   $paged = 1;

$my_args = array(
  'post_type' => 'my-post-type',
  'posts_per_page' => 6,
  'paged' => $paged

$my_query = new WP_Query( $my_args );

if ( $my_query->have_posts() ) :
   while ( $my_query->have_posts() ) :
   $my_query->the_post(); ?>

   <h2><?php the_title(); ?></h2>
   <p><?php the_excerpt(); ?></p>

<?php endwhile;

if ( function_exists('vb_pagination') ) {
  vb_pagination( $my_query );
} ?>

<?php else: ?>
  <h2>Not found</h2>
<?php endif; ?>

I found this solution as simple and effective way to speed up my theme development.
It is saved in my default library which is included in all my themes and I don’t have to worry about pagination no more, don’t have to use plugins and don’t have to set any options.
You would additionally maybe just need to adjust CSS to blend it in your page design.


Here you can download this code as php file to include it in your theme or you can download it as Sublime Text Snippet.

Further reading


  1. Hi,
    your code is very useful, i used your code to make a static homepage with my custom post type. but i got one problem with the active link on pagination.
    Ex: in every page the active link of pagination is the first.
    there’s a way to resolve it?

    thank you

    1. Hi,

      You have 2 queries on same page.
      Try adding wp_reset_query(); and wp_reset_postdata(); before second query.
      Or first try to remove top query and see if that is the problem.


    2. I have just tested your code on my localhost, it works fine.
      Check with page inspector which ‘li’ element has class ‘current’ when you go to next page, maybe it’s CSS issue.

    3. I’m in the second page but the current class is always in the first link. :((
      My theme is roots, probably it’s a theme error?
      Which is your right code? Without the first query or with the reset function?
      Thank you

    4. Mhm, my theme is also roots.
      As you can see on my site it is working, I have the same code on this site.
      Try to move it from home to some other custom page.

    5. thank you Vlado, but i still have not solved the problem. :((
      I’m asking on roots forum, and I’ll let you know if it will solve.

    6. Try deactivating plugins if there are some.
      Check whats happening with ‘get_query_var(‘page’)’, is it always 1 on all pages.

    7. you need to print_r( $my_query ) to see what’s happening with query.
      Then you can see whats wrong, maybe you need to update permalinks.

    8. HI,
      i finally solved my problem.
      this is the solution:


      ‘posts_per_page’ => 6,
      ‘paged’ => $paged

      query_posts( $my_args );



      thank you!

  2. This is much cleaner code than the wp-pagenav plugin. Thanks for posting this code snippet. Here onwards i am going to use this code in all my upcoming niche WordPress themes.

  3. Simple and useful, thank you!!
    I added an if statement to introduce the bootstrap active state

    foreach ( $paginate as $page ) {
    if (strlen(strstr($page,’0) {
    echo ” . $page . ”;
    echo ” . $page . ”;

Leave a Reply

Your email address will not be published. Required fields are marked *

Please don’t paste any HTML, Js or PHP code into comments box, use or similar service to share code examples.

Characters left: 1000