I have two custom rewrite rules:

add_rewrite_rule('foo/bar/?', 'index.php?post_type=foo', 'top');
add_rewrite_rule('foo/bar/([a-z]+)/?', 'index.php?post_type=foo&bar=$matches[1]', 'top');

Which gives me posts that match a custom variable bar. However, I want to handle pagination too, thus when a number succeeds /bar/ wordpress should treat it as a page number. I wrote:

add_rewrite_rule('foo/bar/([0-9]+)/?', 'index.php?post_type=foo&paged=$matches[1]', 'top');

In my custom function which is attached to pre_get_posts, I process the page number:

if($query->get('paged')) {
    $query->set('paged', intval($query->get('paged')));

However, when user accesses, say, foo/bar/2, wordpress automatically appends /page/2/, (e.g. in the address bar I get the following URL: foo/bar/2/page/2/).

Although the pagination itself works fine (I get the desired records as expected for each page) this /page/n/ messes up my links on the page and it is an unnecessary duplication in my url. How can I get rid of it?

  • I don't think you need that rule on pre_get_posts - it says "if value is set, set it", and it is set earlier by WP_Query->parse_query() Commented Sep 23, 2013 at 18:33

1 Answer 1


The function redirect_canonical() is 'responsible' for your problem.

Your default WordPress pagination (with core functions) is not gonna work if you do this, but you can filter out the pagination for your particular custom url:

add_filter( 'redirect_canonical', 'wp230913_canonical', 10, 2 );

function wp230913_canonical( $redirect_url, $requested_url ) {
    if ( preg_match( "#foo/bar/[0-9]+/page/[0-9]+#", $redirect_url ) ) {
        return $requested_url;

    return $redirect_url;

My recomandation is to change the pagination base for the whole site, changing $wp_rewrite->pagination_base

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.