$paged is not set when a Static Page is set as the Front Page

Description

If a static page is set as the front page of your WordPress site, and you request paginated content from the page via its URL (with permalinks enabled or disabled, doesn't matter), the $paged variable is not set.

This causes custom pages (those ones displaying posts), to always go to Page 1, even if you click other pages. ( This is happening because $paged is set to null, and if it's set to null, it always goes to page 1).

Also, get_query_var('paged'), also returns null, when it should return page 2 (if you clicked on page 2 for example).

After inspecting $wp_query, I noticed that the correct paginated value is stored on

$wp_query->query['paged']

So, I have to do the following on all my themes on header.php, so the pagination doesn't break:

global $wp_query, $paged;
$paged = $wp_query->query['paged'];

This sets $paged again,with the correct value from $wp_query and fixes the bug. Since $paged is null whenever a custom page is selected as your homepage.

Change History (14)

To further clarify, I'm not sure if or why the 'paged' query var is set within $wp_query. A single post with paginated content uses the 'page' variable, while paginated multiple posts uses 'paged'. So $page I imagine stores exactly what you want.

If that sounds right, then the only thing that we may need to investigate is why paged is still being set deep in the query and not exposed in the query var, which doesn't sound right.

A single post with paginated content uses the 'page' variable, while paginated multiple posts uses 'paged'. So $page I imagine stores exactly what you want.

Exactly. When using a static front page it is expected that the page query variable is set and paged isn't. The confusion is due to the fact that /page/XX style pretty permalinks are used for page_on_front, see #12391 for why this happened. Also #13840 and comment 10 in particular.

If that sounds right, then the only thing that we may need to investigate is why paged is still being set deep in the query and not exposed in the query var, which doesn't sound right.

The reason it is set in the $query property is due to the use of /page/XX which passes paged=XX to WP_Query. The code introduced in [13494] for #12391, and removed in the patch here, switches this to the page query variable, but doesn't modify the $query property. I don't think we should modify this because it is still the input.