Using page as front page, why does /page/### work?

In WordPress you have 3 main kind of “views”:

  • singular pages
  • archives
  • search

“Standard” home page is just a somewhat special archive page, a static front page a somewhat special singular page.

When you use the endpoint page in front page url, WordPress internally sets the query variable page to a specific number (would be paged for regular pages).

The problem is that paged is a query var that in WordPress makes sense only for archive and search views, in fact there’s no pagination for a single result in database.

In short, WordPress recognizes that the url is formally correct, but ignore the query var it sets.

In fact, if you try to do same thing with any other page (that is not front page) the behavior is the same.

In short, those urls even if are not the “canonical” urls don’t result in 404 because they correspond to a valid set of query vars, that returns a non-empty result.

With singular posts, this does not happen because WordPress, for posts, does a redirect the the “canonical” url.

WordPress does not do the same for front page and regular pages, because a lot of people use them as entry point for archives of posts, where pagination makes perfectly sense.

So in a costs / benefits balance WordPress prefer do not redirect pages to their canonical url by default.

Even because, regarding SEO, this is not something that really has bad effects, unless you have all around the web links that point to the home page url with /page/xxx appended.

And in that case, if such urls are not valid anymore, should be your care 301 redirect them.

By the way, you can force WordPress to apply canonical redirect also for pages and front page:

add_action('template_redirect', function() {
    if (
        (is_page() && get_query_var('paged'))
        || (
             is_front_page()
             && get_option('show_on_front') === 'page'
             && get_query_var('page')
        )
    ) {
        wp_safe_redirect(get_permalink(get_queried_object_id()), 301);
        exit();
    }
}, 99);

As alternative, you can also force 404 on those urls. IMO it has no real benefit for SEO over the 301 redirect, but has negative effects on users that don’t se the page anymore.

By the way that’s the code:

add_action('template_redirect', function() {
    if (
        (is_page() && get_query_var('paged'))
        || (
             is_front_page()
             && get_option('show_on_front') === 'page'
             && get_query_var('page')
         )
    ) {
        global $wp_query;
        $wp_query->set_404();
        status_header( 404 );
        nocache_headers();
        locate_template(array('404.php', 'index.php'), true);
        exit();
    }
}, 99);