WordPress: How to 301 Redirect Pagination Pages to the Parent URL

It may be anecdotal, but I’m finding that Google Search Console is becoming more comprehensive in its reporting. So much so that I’ve begun to lean on it more and more… especially to identify pages not found on the site that might negatively impact search rankings.
My site’s theme incorporates an approach where visitors can click load more if they’d like to see additional posts for the home page, category archives, tag archives, or even search results. This user experience (UX) enhancement does away with pagination, where a user (or search crawler) would iterate through pages and blog post results.
However, despite enabling this functionality on my site, Google still believes that I have pagination and that there are errors on the site where those pages are no longer found. If I went to one of those pages listed in Google Search Console, it resulted in a 404. Google believes there’s a problem with my site when there isn’t.
To remedy this, I needed to build a custom redirect in my child themefunctions.php
that takes any of those /pages/# and redirects them to their parent. One exception that I needed was my custom post type for my acronyms.
Today, I pushed this enhancement to my child theme which accommodates any of the scenarios above:
/page/{number}
– My home page is my blog archive, so this would result in a 404 with my load more feature. Now any page will redirect to my home page./tag/{tag-slug}/page/{number}
– My tag pages would result in a 404 with my load feature. Now any page will redirect to parent/tag/{tag-slug}/
/category/{category-slug}/page/{number}
– My category pages would result in a 404 with my load feature. Now any category page will redirect to parent/category/{category-slug}/
/{category-slug}/page/{number}
– My category pages strip out/category/
and would result in a 404 with my load feature. Now any category page will redirect to parent/{category-slug}/
However, my acronym pages are still indexable:
/acronym/page/{number}
still exists and can be crawled and indexed.
Child Theme Code
add_action('init', 'custom_redirect_with_exceptions');
function custom_redirect_with_exceptions() {
// Regular expression to match paths ending with /page/number
// Updated regex to capture potential author or tag path
if (preg_match('/^(\/author\/[^\/]+|\/tag\/[^\/]+|\/[^\/]+)\/page\/\d+/', $_SERVER['REQUEST_URI'], $matches)) {
$base_path = $matches[1]; // Capture the base path including potential author or tag path
// List of base paths to exclude from redirection (e.g., custom post types)
$exclusions = ['/acronyms']; // Replace with your actual CPT base paths
// Check if the base path is not in the exclusions list
if (!in_array($base_path, $exclusions)) {
// No additional check for tag or author specific logic here, base path used as is
$redirect_base = $base_path;
// Construct the new URL to redirect to the base path without pagination
$new_url = home_url($redirect_base);
// Redirect to the new URL with a 301 permanent redirect status
wp_redirect($new_url, 301);
exit;
}
// No action is taken if the URL is in the exclusions list
}
// Check if the URL is just a paginated home URL
else if (preg_match('/^\/page\/\d+/', $_SERVER['REQUEST_URI'])) {
// Redirect paginated home URLs to the home page
wp_redirect(home_url('/'), 301);
exit;
}
}
The code first checks if the URL matches a paginated format excluding specified paths. If it does, and it’s not an excluded path, it redirects to a non-paginated version of that path. If the URL is a paginated home URL, it redirects to the pagent page.
Here’s an overview of each stage of the modified WordPress redirect code:
- Action Hook Registration: The code begins by registering an action with WordPress’s
init
hook. This action is namedcustom_redirect_with_exceptions
and is set to execute when WordPress initializes. This is the typical stage to perform redirects because no output has been sent to the browser yet.
add_action('init', 'custom_redirect_with_exceptions');
- Function Definition: The
custom_redirect_with_exceptions
function is defined. This is where the main logic for redirecting specific types of URLs resides. - URL Pattern Matching: Inside the function, a
preg_match
is used to check if the current URL (found in$_SERVER['REQUEST_URI']
) matches certain patterns. Specifically, it checks for URLs ending in/page/number
and captures the preceding path, which could be a general path, an author path (/author/[name]
), or a tag path (/tag/[name]
).
if (preg_match('/^(\/author\/[^\/]+|\/tag\/[^\/]+|\/[^\/]+)\/page\/\d+/', $_SERVER['REQUEST_URI'], $matches)) {
$base_path = $matches[1];
This section captures the part of the URL before /page/[number]
, which is stored in $base_path
.
- Exclusions Handling: The code defines an array named
$exclusions
, containing paths that should not be redirected. This could be paths for specific custom post types or other special cases.
$exclusions = ['/acronyms'];
Then, it checks if the captured base path from the URL is not in the exclusions list. If the base path is in this list, the function will end without performing any redirection.
- Redirection Logic: If the URL is not excluded, the function proceeds with the redirection logic. There is no separate logic for tags or authors here because the redirection base (
$redirect_base
) is set to be the same as$base_path
, which could be any matched section from the URL.
$redirect_base = $base_path;
$new_url = home_url($redirect_base);
The new URL for redirection is constructed using WordPress’s home_url()
function, appending the non-paginated base path. Then, a 301 permanent redirect is performed to this new URL using WordPress’s wp_redirect()
function, and the script exits to prevent further execution.
- Paginated Home URL Handling: Outside of the main if condition, there’s another check for URLs that represent paginated versions of the home page (e.g.,
/page/2
). If such a pattern is detected, the script redirects to the home page without pagination.
else if (preg_match('/^\/page\/\d+/', $_SERVER['REQUEST_URI'])) {
wp_redirect(home_url('/'), 301);
exit;
}
- End of Function: If none of the conditions for redirection are met, the function completes without taking any action, and the page request proceeds as normal.
This entire flow ensures that specific types of paginated URLs (especially those for author and tag pages) are redirected to their base path, thereby improving the user experience and site structure, while allowing for exceptions as needed.