1

We use self-hosted Wordpress and earlier we were using paginated posts in our article like.

www.example.com/some-article.html
www.example.com/some-article.html/2
www.example.com/some-article.html/3

Now even after we have removed pagination, the www.example.com/some-article.html/2 and www.example.com/some-article.html/3 URLs are still opening with same full content as is on www.example.com/some-article.html.

And I find Google is still indexing several of those paginated URLs, despite the canonical URL on those 2 paginated URLs rightly pointing to www.example.com/some-article.html.

I think maybe it's because several bloggers have linked to us using our old paginated urls /2 and /3 and Google is still following those links.

Can someone provide me a solution, either via .htaccess code or functions so that if someone opens www.example.com/some-article.html/2 or www.example.com/some-article.html/3 they get redirected to www.example.com/some-article.html.

or if that's not possible then at least if someone opens www.example.com/some-article.html/2 or www.example.com/some-article.html/3 then it gives 404 Not Found error.

Any help would be highly appreciated.

Current .htaccess code is:

# BEGIN WordPress
<IfModule mod_rewrite.c>
# Rewrite HTTP to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
2

To redirect these URLs, you can do something like the following at the top of your .htaccess file, before the WordPress front-controller:

RewriteRule ^(some-article\.html)/ /$1 [R=301,L]

This checks for /some-article.html followed by a slash (and optionally anything else). And redirects to /some-article.html (the value of the $1 backreference). The $1 backreference simply saves typing/duplication (and in doing so lessens the chance of introducing errors).

To be more specific and match only /some-article.html/N (where N is any digit) then change the RewriteRule pattern to ^(some-article\.html)/\d. Or to match just the specific URLs you mentioned (ie. /2 or /3) then use ^(some-article\.html)/[23] instead.

NB: First test with a 302 (temporary) and only change to a 301 (permanent) redirect when you are sure it's working OK.

google is still indexing several of those paginated urls, inspite canonical url on those 2 paginated urls

Google still indexes non-canonical URLs, it's just that they shouldn't normally appear in organic search results. A site: search is not a normal search (if that is what you are using to check for indexed URLs) and often returns non-canonical and even redirected URLs.

UPDATE#1:

...we have to fix this problem with about 500 articles

Then you can probably just generalise the regex, if your URLs end in .html and you want to redirect all previously paginated URLs. For example:

RewriteRule ^([\w-]+\.html)/\d /$1 [R=301,L]

\w is a shorthand character class that matches any word character. ie. a-z, A-Z, 0-9 and _. I've also included a hyphen in the encompassing character class.


UPDATE#2:

It seems (having discussed this in chat) that the actual URLs you are requesting contain an additional path-segment (a WordPress "category") of the form: /<category>/<article>.html. So you will need to modify the above directive to something like the following instead:

RewriteRule ^([\w-]+/[\w-]+\.html)/\d /$1 [R=301,L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
# Rewrite HTTP to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Note that you should avoid modifying the directives inside the # BEGIN WordPress section - this is maintain by WordPress (or at least it tries to), so any modifications you make might be overridden later.

Your custom directives should go before the # BEGIN WordPress section.

For example:

# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Redirect old paginated URLs
RewriteRule ^([\w-]+/[\w-]+\.html)/\d /$1 [R=301,L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

You do not need to repeat the RewriteEngine On directive (although it's not necessarily an "error" to do so). The last RewriteEngine directive takes priority and controls the entire file, so earlier RewriteEngine directives are effectively ignored.

  • Actually, we have to fix this problem with about 500 articles so it won't be possible to put all those 500 urls in htaccess. Need the code some other way! – samjoezzy Aug 5 at 13:43
  • or may be if someway we can auto-add noindex, nofollow to all pages which have /2 or /3 in url. – samjoezzy Aug 5 at 13:44
  • I've updated my answer to include a more generic solution to match "any" article. This assumes all URLs are at the root (no other path segments). Presumably all these .html URLs are handled by WP? – MrWhite Aug 5 at 13:50
  • Ok I added the code in my htaccess but it didn't worked..when I open urls with /2 or /3 its opening same like earlier..not redirecting. Here is my htaccess code..do note that it also contains http to https redirect code – samjoezzy Aug 5 at 13:55
  • 1
    Thanks, Mrwhite the code you provided is working awesome. You are a real genius. And thanks for the additional help about where to put the http to https redirect code. – samjoezzy Aug 5 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.