I've recently changed my URLs with parameters to more readable URLs with the following .htaccess:

RewriteRule ^page/([A-Za-z0-9-+_\s]+)$ /index.php?n=$1 [L]
RewriteRule ^category/([A-Za-z0-9-+_\s]+)/([0-9]+)$ /index.php?p=$1&b=$2 [L]

I believe this poses problems now with duplicate content on the search engines, as index.php URLs and domain.com/page/ URLs will both be indexed.

If calls made to domain.com/page/1 get redirected to index.php?n=1 how can I redirect requests made to index.php to domain.com/page/ ?

My attempt to do so is giving me a 404 code sending me to domain2.

#RewriteCond %{QUERY_STRING} ^n=([A-Za-z0-9]+)$ [NC]
#RewriteRule ^index\.php$ http://domain.com/page/? [R=301,L]


IndexIgnore *
ErrorDocument 404 http://domain2.com

Redirect 301 /keyword.php http://domain.com
Redirect 301 /inc/keyword.php http://domain.com

Options +FollowSymlinks
RewriteEngine on

#Redirect all pages in a folder to a single URL
RewriteRule ^test/(.*)$ http://domain.com [L,R=301]

# HTTP HOST, escape . and start string with ^
RewriteCond %{HTTP_HOST} ^www\.domain\.com [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,NC] 

RewriteCond %{QUERY_STRING} ^p=h&m=([A-Za-z]+)&y=([0-9]+)$ [NC]
RewriteRule ^index\.php$ http://domain.com? [R=301,L]

#RewriteCond %{QUERY_STRING} ^n=([A-Za-z0-9]+)$ [NC]
#RewriteRule ^index\.php$ http://domain.com/page/? [R=301,L]

RewriteRule ^page/([A-Za-z0-9-+_\s]+)$ /index.php?n=$1 [L]

RewriteRule ^category/([A-Za-z0-9-+_\s]+)/([0-9]+)$ /index.php?p=$1&b=$2 [L]

2 Answers 2


You are right to think about duplicate content when you are changing a URL structure and the old URLs are already indexed.

# My attempt to do so is giving me a 404 code sending me to domain2.
#RewriteCond %{QUERY_STRING} ^n=([A-Za-z0-9]+)$ [NC]
#RewriteRule ^index\.php$ http://domain.com/page/? [R=301,L]

In that case http://domain.com/page/ would seem to be an invalid URL, but you are also removing the information contained in the query string and not passing it on to the "user friendly" URL (so all URLs are being redirected to the same invalid URL).

You also need to be careful of redirect loops, since you are internally rewriting to a URL that contains the query string (for your user friendly URL to work) but also need to redirect URLs that contain the query string to prevent duplicate content.

We can get around the redirect loop by checking against %{THE_REQUEST} which holds the full HTTP request as sent from the client and won't change after a rewrite.

So, for your first "page" URLs:

RewriteCond %{THE_REQUEST} \?n=([A-Za-z0-9]+)$
RewriteRule ^index\.php$ /page/%1? [R=301,L]

Note that the pattern [A-Za-z0-9] (taken from your example) in the URL is more restrictive than the pattern in your rewrites [A-Za-z0-9-+_\s] (which allows spaces!?) - both patterns should be the same, and not allow spaces. (Note that THE_REQUEST contains spaces, so the regex will need to change if you really really need this.)

EDIT: In view of the update below (to allow two parameters), I have added a $ (position marker) in the above RewriteCond directive to signify the end of the string. This now only allows one URL parameter.

And the external redirects should come before the internal rewrites (which you appear to have done anyway).

UPDATE: For a second parameter (as mentioned in comments), add these additional directives:

RewriteCond %{THE_REQUEST} \?n=([A-Za-z0-9]+)&y=([A-Za-z0-9]+)$
RewriteRule ^index\.php$ /page/%1/%2? [R=301,L]

This checks for exactly two parameters (n and y in that order) and redirects accordingly.

(Note the edit to the first rule above for one parameter.)

  • How would you rewrite more parameters in addition to your answer in a string like ?n=abcd&y=abcd
    – rrrfusco
    May 22, 2014 at 2:49
  • I have updated my answer for two parameters. Note that this is with respect to your comment, which uses the same URL parameter name as for 1 URL param (ie. n). So, an end of string marker ($) is now required to avoid ambiguity. If your two parameters were p and b (as in your original question) then this could be omitted.
    – MrWhite
    May 23, 2014 at 12:15

Can you use a proxy in front of your Apache? Something like Varnish can do the rewriting for you, and as you separate concerns, you lower risk of building redirect loops and the likes. And that will speed up your website...

If you can't run a proxy on your server, maybe you can consider using external services than can do it for you, plus other things. The service I'm running does, and I think does it well. See the URL in my profile.

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.