# How to bulk redirect in htaccess from old site with parameters

I'm currently updating an old website, but I don't know much about htaccess redirects. I made a script to get all the pages of the website and here are some examples:

For pages:

Redirect 301 /index.php?p=1 https://www.example.com/page_slug/


For categories I did the same:

Redirect 301 /index.php?c=1 https://www.example.com/cat_slug/


Now for the product pages. There are some products that are in multiple categories. For example product 1 is visible in category 1 and 2:

index.php?c=1&pr=1
index.php?c=2&pr=1


Those products have a canonical to

index.php?pr=1


For SEO purposes, should I redirect from c=1 and c=2 and from the url without c in it to https://www.example.com/product/product_slug/? Or should I just redirect from index.php?pr=1 to the new page?

If I have to redirect from all the categories, is there a way to write it without having to write every category for the same product (it's written with a script, so it's not that much work, but there will be a lot of lines in the htaccess file)?

Code already in the file (in an update folder):

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /update/

RewriteRule ^index\.php$- [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /update/index.php [L] </IfModule>  • @MrWhite I don't know how I missed your answer. I could have sworn this had no answers when I closed it. – Stephen Ostermiller May 4 at 19:14 ## 1 Answer For categories I did the same: Redirect 301 /index.php?c=1 https://www.example.com/cat_slug/  I'm not sure whether you are implying these redirects work OK? But this cannot possibly work... you can't match the query string with a the Redirect directive. You need to use mod_rewrite and a condition that checks against the QUERY_STRING server variable. For example: RewriteEngine On RewriteCond %{QUERY_STRING} ^c=1$
RewriteRule ^(index\.php)?$/cat_slug/ [QSD,R=301,L]  The QSD flag (Apache 2.4+) is required to remove the original query string from the redirected request, otherwise it is passed through unchanged. (On Apache 2.2 you would need to append a ? to the end of the substitution string instead.) And the same for pages. For SEO purposes, should I redirect from c=1 and c=2 and from the URL without c in it to https://www.example.com/product/product_slug/? Or should I just redirect from index.php?pr=1 to the new page? If all variations are indexed and/or being linked to then you need to redirect from all variations. However, you can do all that in a single rule, for example: RewriteCond %{QUERY_STRING} ^(c=[12]&)?pr=1$
RewriteRule ^(index\.php)?\$ /product-page/ [QSD,R=301,L]


If I have to redirect from all the categories, is there a way to write it without having to write every category for the same product

You only have what is available in the requested URL. So, if you can determine the target URL simply by looking at the source URL then yes, you can effectively "group" these rules together. However, in the examples you've posted, this is not the case.

• This one almost gives me what I want. I was working with the information I found online, but the redirect did indeed not work. With the rules you gave me, I get this url in the browser: https://www.example.com/cat_slug/?c=1. I can't seem to get rid of the ?c=1 part and the https://www.example.com/cat_slug/ is now broken and gives a 404. – ErXoR May 3 at 17:44
• Ah, sorry, you need the QSD flag on the RewriteRule directive to "discard" the original query string from the redirected request (I'm assuming you're on Apache 2.4+). – MrWhite May 3 at 17:56
• "https://www.example.com/cat_slug/ is now broken and gives a 404." - How are you routing this URL? – MrWhite May 3 at 18:05
• I altered the original post in the end with what I have already in the file. – ErXoR May 3 at 18:17
• I'm on Apache/2.4.35 – ErXoR May 3 at 18:25