Editor’s note: This guide was originally published in November 2008. It has since been updated for accuracy and to reflect modern practices.
If you’ve ever had to do URL redirects for one of your websites, you’ve probably been overwhelmed with all of the different ways to do it. This code can be confusing and, as a result, can be extremely frustrating to figure out.
However, once you do set up URL redirects several times and become familiar with the .htaccess file, the process becomes fairly easy.
In this guide, I’ll walk you through a few dynamic HTTP redirections, based on our agency’s work with dozens of eCommerce clients.
But, first, let’s go over some important background information.
What is a 301 Redirect?
A 301 redirect is a permanent redirect — meaning that, when a user tries to access an old or outdated URL, the redirect sends their browser to another, more relevant webpage instead.
Redirects are obviously important for user experience; after all, dead URLs are hardly attractive to visitors.
But they’re also key for your SEO strategy, as well.
When you set up a 301 redirect (or any redirect, for that matter), you tell a search engine’s crawlers that the original content has been moved. That way, the search engine can better maintain its indexes and continue to serve relevant content to its users.
What is a Dynamic URL?
A dynamic URL occurs when the contents of a webpage change based on variable parameters provided to the server, creating an individual unique URL each time.
This type of URL is often used on eCommerce websites to create category pages where a user can filter down the product list to look at items with specific features.
For example, on a clothing website, you might be looking at the t-shirt page, but want to look at a specific color, size, or cut. A dynamic URL would be used to build a t-shirt category page with your specific filters.
You can see an example in the screenshot from DollarDays.com below, where we’ve filtered shoe products by features and price to generate a unique URL:
This is opposed to a static URL, in which the content and URL of a page don’t change and remain the same.
What is an .htaccess File?
An .htaccess file is a website file that controls the configuration of your website. By making edits within this file (rather than in the server configuration directly), you can make important changes to your site.
Keep in mind: Because you’ll directly edit the code in this file, it’s easy to make a mistake that ripples across your site and impacts your users’ experience. So, we recommend using caution and paying close attention to detail when editing this file.
When to Use a 301 Redirect
In short, a 301 redirect should be used when a URL is no longer needed or is being removed from the site.
Let’s say you run an eCommerce website and will no longer offer a certain product, whether because you’re changing your offerings or because the product is out of stock and will never return. Using a 301 redirect on this URL will indicate to users and search engines that this product will no longer be offered on your site — and that they should instead refer to the new page you are sending them to for similar products.
You can also use 301 redirects when you’re migrating to a new eCommerce platform and, as a result, your website URLs need to change. Again, you’d create a 301 redirect to tell users and search engines what the new placement of the webpage will be on the new website.
How to Do a 301 Redirect in .htaccess
The method you use to complete a 301 redirect will vary, depending on the server that your website runs on. In most cases, the .htaccess method is used on Apache servers, but you can use it on other servers, as well.
In addition, because there are so many different server configurations, you might have to try several methods to find the one that works best for your site. In the examples below, I share the strategies that I’ve successfully used for our clients’ sites.
1. Redirecting a Single URL
For one of our clients, I wanted to redirect https://www.example.com/page.php?id=68 to https://www.example.com/content/page. After attempting the tried-and-true processes, I had to experiment a bit.
Using regex (regular expression), this is the format that finally worked for me:
RewriteCond %{QUERY_STRING} ^id=1$
RewriteRule ^$ https://www.example.com/content/page? [R=301,L]
To use the same strategy for your site, take your URLs and plug them into the appropriate areas outlined in the image below:
Note that after the question mark in the URL, you’ll find an ID. While this might look different for your URL, you can change the input in the redirect accordingly.
For example, your URL might be page.php?page_num=68. If this is the case, you’ll just replace id=68 with page_num=68 in the redirect code.
When using this method, don’t forget to add the question mark to the end of the new URL that you’re trying to redirect to.
2. Redirecting a Group of URLs
What if you’re redirecting several dynamic URLs at once?
For a proper dynamic redirect, your .htaccess should look like this:
RewriteCond %{QUERY_STRING} ^id=1$
RewriteRule ^page.php$ https://www.example.com/content/page? [R=301,L]
RewriteCond %{QUERY_STRING} ^id=72$
RewriteRule ^page.php$ https://www.example.com/content/page2? [R=301,L]
RewriteCond %{QUERY_STRING} ^id=46$
RewriteRule ^page.php$ https://www.example.com/content/page3? [R=301,L]
3. Redirecting URLs with Multiple IDs
If you have URLs with multiple IDs, you can simply expand the expression:
Old URL: https://www.example.com/page.asp?id=4&mscsid=49
New URL: https://www.example.com/page.asp?id=4&mscsid=49
RewriteCond %{QUERY_STRING} ^id=4&mscsid=49$
RewriteRule ^page.asp$ https://www.example.com/content/page1? [R=301,L]
4. Redirecting a Group of URLs in One Statement
If you wish to streamline your redirects, you might choose to redirect many URLs within a single statement. Here’s what you can do:
Old URL: https://www.example.com/page.php?id=1111
New URL: https://www.example.com/content/page_name
RedirectMatch 301 ^page.php?id=(.*).htm$ https://www.example.com/content/$1.html
5. Redirecting a URL without an ID
What if your older URLs don’t have IDs? How can you redirect them?
Don’t panic; there is a solution.
Old URL: https://www.example.com/?/page/55c9/
New URL: https://www.example.com/newpage.php/page/55c9/
RewriteCond %{QUERY_STRING} ^/page/55c9/$
RewriteRule ^$ https://www.example.com/newpage.php/page/55c9/? [R=301,L]
Note: Whichever method you use to complete your 301 redirects, if your URL includes a hash (#), it will not redirect properly.
Other Helpful Resources
To learn more about dynamic HTTP redirections and URL rewrites, we recommend the following resources and tutorials:
In addition, Wordpress offers multiple plugins for editing your .htaccess file.
As you’re implementing your redirects, if you can’t find an answer to your unique situation, I recommend asking the folks over at WebmasterWorld.com, in the Apache forum. In my experience, that community is great at troubleshooting any redirect errors you might encounter.
If redirecting dynamic URLs is part of a pre- or post-migration process for your eCommerce site, our SEO team is always happy to help. Contact us today for a free strategy proposal to minimize your lost traffic and improve your organic performance.
I’ve been searching for a reliable solution to redirect my dynamic URLs, and this blog post delivered exactly what I was looking for. The explanations are concise, and the code snippets make implementation a breeze. Highly recommend this resource!
I use WordPress. One of the boring thing in WP is that the filter url structure. Can it be changed for better seo performance.
Example:
From
https://www.example.com/?filter=longest
to something like
https://www.example.com/longest
or From
https://www.example.com/?filter=most-viewed
to something like
https://www.example.com/most-viewed
In general, filtered URLs are something you usually wouldn’t want to be indexed in the first place. Our team isn’t familiar with doing something like you’ve mentioned, but this post might help answer your question: https://wordpress.stackexchange.com/questions/358425/seo-friendly-filter-urls
Hi Jo,
Looks like you didn’t even read my post, because neither of the methods you tried are what I wrote about.
Try
RewriteCond %{QUERY_STRING} ^id=11$
RewriteRule ^$ https://www.mywdomain.com/new.html? [R=301,L]
Hi Alex
Pls help
I’m trying redirect this url
https://www.mywdomain.com/?id=11 to https://www.mywdomain.com/new.html
Ive tried:
1)RewriteRule ^new.html ?id=11 [NC]
2)RewriteCond %{QUERY_STRING} ^id=11$
RewriteRule ^(.*)$ mynew.html.html[R=permanent,L]
1) allows me to acces the same web page via both urls. I was hoping to be redirected to https://www.mywdomain.com/new.html when I type https://www.mywdomain.com/?id=11 in the browser.
2) Send me a 404 error
Thanks in advance
Jo
thanks for the great article.
I have made a redirection following your guideline and it works,
BUT it adds ? in the end of the new url.
Here is my code:
RewriteCond %{QUERY_STRING} ^main_page=product_info&products_id=301$
RewriteRule ^index.php$
/shop/index.php?route=product/product&product_id=301? [R=301,L]
I think it’s because I still have a ? in my new url and it doesn’t understand what the second one is for…
Thanks for your help!
You’re probably right, because ? is the equivalent of a question mark. A question mark needs to be encoded in a URL for it to work properly.
Here’s a quick explanation of the “why”.
https://www.blooberry.com/indexdot/html/topics/urlencoding.htm
So in your case, I’m not completely positive how you can fix it, but maybe you can try replacing it in the .htaccess with ?. If that doesn’t work, what about adding the html code of a question mark in it’s place, similar to the ampersand in your URL, ?
I’ve also heard that making the final URL absolute could help fix the problem so you could try adding the https://www.yoursite.com/ etc. to the final URL.
RewriteCond %{QUERY_STRING} ^main_page=product_info&products_id=301$
RewriteRule ^index.php$ https://www.yoursite.com/shop/index.php?route=product/product&product_id=301? [R=301,L]
Here’s a discussion from Webmaster World talking about a similar issue you’re having, which might help you out.
https://www.webmasterworld.com/apache/4138119.htm
I hope some of this helps. I don’t have experience with this issue, so if you figure it out, I’d love to hear what you did.
Hi,
My Old Urls :
oyunambari.com/oyna.php?oyun_id=2442
oyunambari.com/oyna.php?oyun_id=2443
oyunambari.com/oyna.php?oyun_id=2444
oyunambari.com/oyna.php?oyun_id=3434
…………….
oyunambari.com/oyna.php?oyun_id=8991
oyunambari.com/oyna.php?oyun_id=8992
my new url there is not.
I want all oyna.php urls redirect oyunambari.com
My Code is
RewriteRule ^oyna.php?oyun_id=(.*)$ https://www.oyunambari.com [L,R=301]
But not working this code.
Help.
Thanks
Hello,
i want to redirect from:
https://www.baby-modern.de/gratisbutler/?p=798
to another site. But it dont work. Could somebody help me?
Something like that dont work:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^p=760$
RewriteRule ^(.*)$ https://www.example.com/blog/?p=221? [R=301,L]
Hy to all,
Here my question:
I have to rewrite some urls with path like:
/main/defautl.aspx?Action=hereavariable
to my new homepage
I used this:
RewriteCond %{QUERY_STRING} ^Action=tlc$
RewriteRule ^main/default.aspx$ https://mynewdomain.com [R=301,L]
the problem is that the final url become:
https://mynewdomain.com/?Action=tlc
but I need only:
https://mynewdomain.com
______________________________
Onother problem is: how I can get a simple rule for multiple page with same pattern “/main/defautl.aspx?Action=”
Thanks Bye!
oh thanks for your cooperation Mr. Alex.
Hi Jay,
For your first question, this should work:
RewriteCond %{QUERY_STRING} ^option=content&link_id={dynamic ID)$
RewriteRule ^index.php$ https://www.example.com/index.html/content/?id={dynamic ID)? [R=301,L]
For your second question, I’ve never done something like that. Maybe this page can help you; https://www.openjs.com/articles/ajax/target_url_hiding.php
You could always just set up redirect so that the clean URL redirects to the long URL instead too.
Its me again can you guide me how to get in hyperlink also that link. Like if i have < a href="index.php?option=content&link_id={dynamic ID}" rel="nofollow">Content
It should be seen in status bar as: index.html/content/?id={dynamic ID}.
Thank you hope you will guide me!!
Hello buddy!!
I am new in .htacess. I have tried so many times to redirect but i couldnot successed. Please can you help me to redirect this url https://www.example.com/index.php?option=content&link_id={dynamic ID)
to
https://www.example.com/index.html/content/?id={dynamic ID).
Please guide me!!
ALEX …. GOD BLESS YOU!!!!!!
Hi Itay,
I think it’s because you don’t have a space after the question mark, so instead it’s appending [R=301,L] to the end of the URL.
Hi Alex,
RewriteCond %{QUERY_STRING} ^id=14$
RewriteRule ^menu.php$ https://www.mynewdomain.com/our-guides/our-guides?%5BR=301,L%5D
I get redirect:
https://www.mynewdomain.com/our-guides/our-guides?%5BR=301,L%5D
But it should be:
https://www.mynewdomain.com/our-guides/our-guides
Any idea?
Hi Alex,
Thanks for your immediate response…Great one…I have one more doubt…i want to redirect to home page if a user tries to access a page which shows some ugly page…so i want to redirect to home if any user uses this kind of urls..i have as many as 5000 urls for my site…
Hi Samiullah,
You will need a different type of rule to create your redirects if you don’t want to input one rule for each one.
You will need to use regular expressions for this. This means that all of your URL’s will need to contain the same pattern. Or you can create a new rule for each pattern.
It would probably look something like this:
RedirectMatch 301 ^play.php?id=(.*).htm$ https://www.example.com/play/$1.html
The (.*) is a variable. The 1.html is what the rule will append to the redirect, so play.php?id=1753 will redirect to 1753.html. This one might work or you might have to play around with it a bit.
In your example you had asked that it redirect to a “Game_Name.” If you absolutely must have this, the .htaccess file probably isn’t the place you will be setting this stuff up because the regex above needs a pattern and “Game_Name” is random. Instead you will have to set up some php code and a lookup table for your database.
I’m not familiar with this so I can only lead you to some resources. Here’s some more info on htaccess code that could help:
https://www.askapache.com/htaccess/301-redirect-with-mod_rewrite-or-redirectmatch.html
If you still can’t figure it out, I would recommend asking the forums at https://www.webmasterworld.com/apache/.
And if you decide to do one redirect at a time, you should place the most important redirects at the top of the htaccess so that they are accessed first, reducing slow down from the server trying to find the correct redirect.
I believe your opinion is very sound advice!
One more question, should the redirection code you provided go before or after the WP mod rewrite code in the htaccess?
Thank you again for answering these questions.
Oliver
Hi Oliver, It can go after the WP mod rewrite code. I don’t believe it matters too much actually, as long as it comes after “RewriteEngine On”
Redirection is a great one but I like to use the .htaccess mainly because I worry about my site being bogged down by plugins. I also prefer to know what’s necessary to add to the htaccess in case I’m working on a site that isn’t running on Wordpress.
Alex,
Thanks for the reply. I found a WP plugin called – Redirection
It manages 301 redirects and monitors 404 errors. This worked for the /index.htm redirection.
Can I have your opinion on which method you believe is preferable?
htacces or WP plugin?
Oliver
Hello,
Site used to be a .htm and now it is a Wordpress site…….
Need to redirect an /index.htm to the root of the Wordpress site…… http://www.ptoutdoors.com.
When I add a… redirect 301 /index.htm https://www.ptoutdoors.com/
to the htaccess, a looping problem occurs and the site will not load. Any thoughts on how to do with htaccess?
Thank you,
OB
Hi Oliver,
Yes, redirecting index.htm and similar pages doesn’t work the same way. You will need to add this to your htaccess:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9} /.*index.htm HTTP/
RewriteRule ^(.*)index.htm$ https://www.yoursite.com/$1 [R=301,L]
Thanks so much. I moved my site from an old .cfm site to wordpress. There were/are hundreds of .cfm redirects.
Hi extramsg, I’m not sure why it’s not working, but you should try removing RewriteEngine On from the dynamic redirect part. That only needs to be in the htaccess file once and needs to be before the redirects.
Hmm, I’ve been trying but nothing seems to work. Attempting to redirect the first of these to the second:
https://www.extramsg.com/modules.php?name=News&file=article&sid=2
https://extramsg.com/?p=1
The code I used is:
RewriteEngine On
Options FollowSymLinks
RewriteCond %{QUERY_STRING} ^name=News&file=article&sid=2$
RewriteRule ^modules.php$ https://extramsg.com/?p=1 [R=301,L]
Not sure if this code that comes before for the page to do google-friendly rewrites is affecting it:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Very frustrating.
Sounds good, thank you!
Please help,
I’m trying to figure out how to 301 redirect from
https://www.domain.com/?rated
to
https://www.domain.com/top
and also redirect second type of url from
https://www.domain.com/?s=free files
to
https://www.domain.com/sh.php?q=free files
Thanks in advance.
Hi Greg, Without fooling around with the htaccess file myself, it’s hard for me to give advice on those two examples. These are much more advanced redirect questions, that’s for sure. I can’t answer them myself, but I would definitely recommend you post your question at https://www.webmasterworld.com/apache/ . I’m sure jdMorgan will be able to figure it out.
Hello Alex…
Useful post, but i cant around how to accomplish the following redirect:
From:
https://www.domain.co.uk/training-courses/?id=7
To:
https://www.domain.co.uk/electrical-training-courses/inspection-testing-electrical-installations-7
Can you help?
Thanks a lot
It´s not easy directing dynamic pages.
I´ve searched all over for the solution that worked for me!
You made it happen 🙂
Thank you!
I would appreciate if someone could help me. I’m getting so confused. I’m not the best coder around.
I want to redirect
https://www.guldenophthalmics.com/ccp51/cgi-bin/cp-app.cgi?usr= (any dynamic page)
To: https://www.guldenophthalmics.com/ccp7/ecom-prodidx/COREseo.html
Thank you
Ron
Hey Rony,
This is similar to Jim’s question above. This should work. I’m not sure on how to do this for all dynamic url’s in one .htaccess code without repeating the process.
RewriteCond %{QUERY_STRING} ^id=17641397$
RewriteRule ^/news/article$ https://www.caribbea.net/index.pl/article?id=17641397? [R=301,L]
I moved the directory structure of my blog, and now all the Google indexed links don’t work. So, what if I want to redirect:
http://www.whatever.com/?p=221
to
http://www.whatever.com/blog/?p=221
And also, what if I want every single instance of “www.whatever.com/?p=” redirected to “www.whatever.com/blog/?p=” to accommodate for all the dynamic posts?
Hey Jim
I think this should work:
RewriteCond %{QUERY_STRING} ^p=1$
RewriteRule ^(.*)$ https://www.example.com/blog/?p=221? [R=301,L]
I don’t know how to accomodate for all dynamic posts other than repeating this for each page in your .htaccess
Alex, could you help me with this. I am trying to redirect
https://www.buydominica.com/resource/linksdir/natural-cure-links.php?parent_id=43
to
https://www.buydominica.com/resource/Caribbean-43.html
How can i do that?
thanks
Hi Rony,
I believe this should work:
RewriteCond %{QUERY_STRING} ^parent_id=43$
RewriteRule ^resource/linksdir/natural-cure-links.php$ https://www.buydominica.com/resource/Caribbean-43.html [R=301,L]
Thank you man… I spent hours on this before finding you…!
Thank you, exactly what I needed, just 301 redirrected 200 urls with this method, worked like a charm..
Great post that got me most of the way.
But I need to redirect:
https://www.mydomain.com/index.asp?menuid=080 to
https://www.mydomain.com/?page_id=2
How would i do this?
Hey Douglas,
I believe it should look like this;
RewriteCond %{QUERY_STRING} ^menuid=080$
RewriteRule ^index.asp$ https://www.mydomain.com/?page_id=2 [R=301,L]
I’ve been trying to figure this out for a couple of hours today! I am sooooo glad i found your post and instructions. They saved my ass! Much appreciation from South Beach!
Awesome, glad it worked Mike in Miami!
HI there,
Great help here and I could help a friend out with his redirect thanks to you!
Now I have a problem:
Must redirect from a former framebusting script where blogs has noted dynamic urls like:
https://www.mysite.se/index.htm?freeinfo.htm
Above dynamic url shall then be redirected in .htaccess to new static url like below:
https://www.mysite.se/freeinfo.htm
Have tried a lot of different redirects but it wont work. Has the page at one.com.
Can someone please help me out here?
Think I can pay some for this help too, if it works fine!
Best Regards
Eric A.
Hi Eric,
The redirect examples above should work for what you’re trying to do. It should redirect a dynamic url to a static url.
Sorry I couldn’t be of more help. Please leave another comment if you figure it out.
Hi,
I´ve been trying to apply 301 redirect on my .htaccess, but It doesn´t seem to work.
I need to reedirect:
https://www.cursoscentromedico.com.ar/masajes-masajista-drenaje-linfatico-enfermeria-primeros-auxilios-tecnico-electrocardiograma-reflexologia.php?id=1
to
http://www.cursos-de-masajes.com.ar
Heres the code in my .htaccess:
RewriteCond %{QUERY_STRING} ^id=1$
RewriteRule ^masajes-masajista-drenaje-linfatico-enfermeria-primeros-auxilios-tecnico-electrocardiograma-reflexologia.php$ https://www.cursos-de-masajes.com.ar? [R=301,L]
what am I doing wrong?
Thanks in advance!
Karim
It looks like that should work, and clicking your link, it seems it’s redirecting fine. Did you change anything to make it work?
Any idea on how to redirect dynamic pages with multiple IDs? e.g. http://www.website.com/page.asp?id=4&mscsid=49
@SEOinHawaii thanks for the kind words! To answer your question, I think you’d just have to expand the expression.
For example, it would have to be written as;
RewriteCond %{QUERY_STRING} ^id=4&mscsid=49$
You’d just have to include everything after the question mark. I can’t think of any other way to do more than one ID.
Hope this helps!
Great post! I’ve been trying to figure out how to redirect these individual dynamic URLs for a while now!!! Thank God for your post…helped out a bunch. Keep up the good work.