So you decided your domain doesn’t fit you as well as you’d like. And you are also afraid you’ll be losing all the old links and search
engine ranking if you move to a new one. Maybe you also want to use the current domain for a different project that suits it best.
Or maybe you just want to change the structure of your URLs or you want a different URI structure in the new domain.
Let’s see how to write some htaccess rules so Apache can do the magic for you.
Redirect the whole domain
Redirecting a whole domain with .htaccess rules is easy. All you have to do is to put the rules below in an file named .htaccess
in the root directory for your old domain.
RewriteEngine on
RewriteRule ^(.∗)$ http://www.newdomain.com/$1 [R=301,L]
Let’s see how the magic happens.
The first line is merely to turn on the Rewrite engine on apache and enable the rewrite rules to be interpreted.
The second line is composed of 4 parts.
- The RewriteRule keyword
- A regular expression (regex) to match the original URI
- The URI to be redirected to and
- Parameters
The regular expression in this case is ^(.*)$. The dot, in a regular expression matches a character, any character except the newline.
That means that any letter, number or symbol container in a URL will be matched. The asterisk (∗) means that you want to repeat the regex it affects
zero or more times.
Simply put, (.∗) matches any amount of non-newline characters, including zero.
Additionally, the carat (^) represents the start of a line and the dollar sign ($) represents the end, so the whole expression
matches a line of zero or more non-newline characters, i.e., the whole path of your URI inside your domain.
The third part is the URI to redirect to. As you see, is pretty straightforward, the only tricky bit is the $1.
The reason for it is that you don’t want to redirect any URI in the old domain to the root of your new domain. What you want is to redirect
each page for the equivalent in the new one. For instance this URI
http://www.oldomain.com/path/to/page
Should redirect to
http://www.newomain.com/path/to/page
Now, for every regular expression inside parenthesis the text it matches is stored for use in the third part as a variable. The variables are called
$1, $2, $3 and so on. We have only one Regex matching the whole path (remember the domain name is not included)
so we have the whole path stored in $1.
Altering the URI structure
It may be the case that you don’t like the current structure of your URI’s. If your blog has URIs like this
www.olddomain.com/blog/category/2009-12-20-post-title
Say we decide dates are not that important, we only want to keep the year, and we want it separated by a slash, rather than a dash. Additionally,
we want to get rid of the ‘blog’ keyword, since the whole domain is for the blog. The following rule will do the trick.
RewriteEngine on
RewriteRule ^blog/(.∗)/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])-(.∗)$ http://www.newdomain.com/$1/$2/$5 [R=301,L]
Here we have 5 matches being put into variables, one for each pair of parenthesis.
- The category ($1)
- Matches the first set of non-newline characteres after ‘blog/’ and the before the following slash.
- The Year ($2)
- Matches 4 consecutive digits after the second slash and before the first dash after that
- The Month ($3)
- Matches 2 consecutive digits between the first and second dashes after the second slash
- The day ($4)
- Matches 2 consecutive digits between the second and third dashes after the second slash
- The Post Slug ($5)
- Matches all the rest of the line
Before we proceed, notice a peculiarity here. Because the rule starts with the carat (^) and ends with the dollar sign ($) you are
matching the whole line in this format. If the URI doesn’t start exactly with “blog/” and has the exact amount of slashes and dashes
we specified it won’t be a match and will be ignored. Also, the category may be empty, as long as the two slashes are there, but the digits
must be present in exact amounts. That, of course, is to be expected of any previously valid URL on the domain.
Now that we have the five variables with the orginal information parsed, we can use them as we want. We decided to get rid of the blog part (which we
are matching literally, instead of via regex, because it’s too simple), month and day and reorganize category, year and post slug. We will use the
first, second and fifth variables and simply ignore the rest.
http://www.newdomain.com/$1/$2/$5/
If you don’t want to redirect to a new domain but just rearrange the URIs within it, you may simply omit the domain on the redirection and use these rules
RewriteEngine on
RewriteRule ^blog/(.∗)/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])-(.∗)$ /$1/$2/$5 [R=301,L]
Reusing the domain for a different project
More often than not, after a domain redirect, the old domain will remain merely as an entry point for redirection. People do that for several reasons,
one of them is that readers can be confused to find the old URLs being redirected to a new site and the domain being used for a new site.
But deciding whether or not to reuse your domain is outside the scope of this post. You may be splitting your site in two and you’ll leave part of it in
the old domain or after a few years, links to your old domain may be minimal or, simply, you may have a better strategy that I can thing while writing this.
In any case, if you want to reuse your domain at some point, you must be aware of a few things.
All the URI’s redirected are taken and can’t be reused without disabling the redirection. You guessed that, of course, but you have to keep in mind that
when you are using regexes for your redirects you are matching a whole class of URIs, even some that have not being used but match the pattern.
If you hurried up and used the first rule (repeated below) you are matching every single URI within the old domain and it means that any content there
will be unreachable because the redirection rules will take precedence.
RewriteEngine on
RewriteRule ^(.∗)$ http://www.newdomain.com/$1 [R=301,L]
If you used the second rule (repeated below) you are targetting a much more specific set of URIs. Anything that doesn’t have the exact format described
(/blog/[characters]/[4digits]-[2digits]-[2digits]-[characters]) will be reachable.
RewriteEngine on
RewriteRule ^blog/(.∗)/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])-(.∗)$ http://www.newdomain.com/$1/$2/$5 [R=301,L]
You’ll be able to even run a blog under http://www.olddomain.com/blog/ as long as you don’t use the exact same URI structure. Again
whether or not this is a good idea is up to you to decide.
301 or 302 redirects
Finally, you may have noticed that one of the parameters on the last part of the rules is the number 301. This is the type of redirection you are
performing. You can use either 301 or 302 as redirection codes, 301 stands for a permanent redirection, whereas 302 stands for a temporary redirection.
Redirection codes are informed to user agents (browsers), search bots and anyone else who may want to know. While both redirection codes will take you
to the new URI, there are important consequences of choosing either.
Because user agents and bots are informed of the redirection code, they can take actions based on them.
A temporary redirection is equivalent to an “Out For Lunch” sign. For some reason, the page is being redirected, but you are confirming the user is on
the permanent URI for the resource. Bear in mind that “temporary” doesn’t imply in any length of time, you are only saying “Yes, this is the URI. We
are operating there right now, but come back here the next time”.
Reasons for that could be:
one day you want to use a different service, all your subscribers use your URI, so they will be automatically redirected.
A permanent redirection is stronger, it is equivalent to say “We moved, we are now operating there and we are not coming back. Next time
you may prefer to go there straight away”. The consequence of that
is that search bots, intelligent user agents, social bookmarking sites and whoever else may care, can update their links to the new location.
This is what is going to make possible for Search Engines to transfer the status of your site to the new structure.






















23 Comments
Nice; .htaccess redirects haven’t been one of my strong points. This is
one ofthe best tutorials I’ve seen. Thanks!Thanks for the tutorial, Gui. You make it sound so simple and easy. Now, a question…
I’m wanting to eliminate my dates in the permalink structure. This will redirect visitors also, not just search engines, right?
And if a site is linking to a post, will the link give someone clicking on it a 404, or will the redirect work then, also?
@Adam Kayce – No, thank you for the kind words.
@Sue –
It’s really not that complicated when the Automata Theory is omitted, right? ;)
No 404 for already valid links. What the 301 does is to inform whoever (user, SE bot, whoever) that the URI has changed to the new destination. For all practical effects it would be exactly as if it has always been like that… unless you want to get down to the level of HTTP requests and things like that.
The 301 redirect will just create a black hole that will teleport requests to the old address to the new one and that includes link clicks as well because when you click a link you are generating an HTTP request on your user agent (browser) pretty much as if you had put the URL on your browser and pressed enter (There are a few differences but are minor in this context).
Right on with this tutorial, Gui….I can personally testify that Gui knows what he is doing in this department because he actually did this on my entire website a while back. Everything went smoothly and I have no problems since then. Also, all of the link juice transferred to the new URLs so that was awesome too.
Thanks again for all the work you did for me, hoping to send a few customers your way when I get inquiries down the road…..
Hi Gui!
This is excellent! I tried to get my son to explain them to me, but he just says, “Do this and it will work.” LOL
I have a PDF on Regex, but it is way too boring. Your examples are more fun. Plus, I finally understand parameters. They’re just like the “good old days” of DOS batch files.
Hope your year is permanently redirected to a successful page!
Cheers,
Mitch
@Patrick – Hi Patrick, thanks. Regarding clients, I’m currently off-market, working only for Yahoo! but thanks for that too.
@Mitchell Allen –
I’m not a great believer that this kind of faith makes Regexes work, LOL. I’m glad you liked my examples. You too have a great year.
@Patrick – BTW, congratulations on the high number of subscribers on your blog, well deserved.
Great post! Got here from Chris Garrett’s Re-Tweet for “Domain redirect wizardry with .htaccess rules” — you’ve posted some very good tips, Guilherme.
For those of us that are less .htaccess-editing-capable…
I wrote a post on my blog last night, that is very much related to what you are talking about here, regarding setting up the “Best Wordpress Permalink Structure” and how to use a simple, straightfoward WP Plugin to help Wordpress blog owners setup redirection for old permalink structures. Please take a look and let me know if I should add anything to make it even easier for Wordpress users to understand:
http://www.michaelbubbo.com/blog/2009/best-wordpress-permalink-structure
I’m going to add a link to this blog post to mine, for those who really want to learn the details of what goes into actually editing .htaccess to achieve these all-important 301 domain redirects, as your explanation serves as an excellent tutorial.
Happy New Year 2009!
http://www.michaelbubbo.com
@Michael – Hi Michael, nice tutorial. I’ll play with it myself.
Great, thanks Guilherme.
Just noticed you are on Twitter, I’m following you now. Looking foward to more posts! Again, excellent job, this one is going into my permanent cheat-sheet file for easy future reference.
http://www.michaelbubbo.com
P.S. You can follow me, too, I’m at http://twitter.com/bubbo
You have make such a difficult concept easy to understand. I have been using .htaccess code without really understand what it means, but now I do with your made-easy tutorial.
Thanks
As someone who’s thinking about changing permalinks,this has come inhandy,Guioconner makes it seem so easy
Hi, Great post.
What if you are moving to a new site with a different site structure? For instance:
from
http://www.oldomain.com/path/page
to
http://www.newdomain.com/path/to/page
What redirect command is needed to take into account the new subdirectory?
@Michael, @Damien – Thanks, I’m glad it’s useful.
@DJPumpkin –
If your directory is going to be static across the site, then it’s as easy as doing
RewriteRule ^path/(.*)$ http://www.newdomain.com/path/to/$1 [R=301,L]
Now, if “path” and “to” are to change according to context (e.g., dates or categories) then it may become much more complex.
Most of the time people change name of a category, remove dates from their URL or simply use a ‘pretty URL’ instead of an ugly URL with lots of parameters.
Something like this is very popular:
RewriteRule ^path.php?par1=(.)&par2=(.)$ http://www.domain.tld/path/pretty-url-$1-and-$2 [R=301,L]
I have seen this in a lot of websites where ‘one’ php file is used to show details of many resources identified by an id or a slug.
Hi Guilherme,
I want to redirect Domain A to Domain B but I want the url to stay Domain A. So after the redirect users should still see http://www.DomainA/page.php and any link they click on they still see http://www.DomainA/contactus.php instead of reverting back to the old domain.
Does that make sense?
@Rizwan – Well, you can do that combining different techniques. Redirects will take you to another page, period. But you can, for instance, use a frame to include the page form the other domain, which is known as cloaking.
Now, why would you want to do that?
Is cloaking the same as Frame Forwarding?
The reason I want to do that is because we have a listing directory installed on one server with Domain A but we prefer Domain B and want to use that instead.
In this context, yes, but actually there is some terminology mistake on my side, there are different techniques with similar names, cloaking is most commonly used for a technique to fool search engines.
Anyway, terminology mistakes apart, I think you can do just well by simple make a redirect from domain A to B and let the domain change. If you do it properly, in a few days or weeks at most all your search engine traffic will be linking directly to the new domain.
Dear Guilherme
Like everyone else, I think you’ve very successfully broken down a mystical whole into its understandable parts and deftly strung the parts together to form a coherent and engaging narrative, just like a string of beads, well done!
Now onto a problem. I would like http://www.new-domain.com to point to http://www.old-domain.com/new-domain/, the only problem is though that http://www.new-domain.com and http://www.old-domain.com share the same IP address and the same host (naturally). Any ideas?
Many thanks in advance.
@Andrew Brown – Andy, the IP is no problem at all. That will be taken care of by DNS. As long as you have both domains set up correctly (which is assumed for this tutorial) all the rest will work.
Straing to your question, I understand you want requests to http://www.new-domain.com to be redirected to http://www.old-domain.com/new-domain, you do that by placing this rule into newdomain.com.
RewriteEngine on
RewriteRule ^(.∗)$ http://www.old-domain.com/new-domain/$1 [R=301,L]
A request to http://www.new-domain.com/foobar will now be redirected to http://www.old-domain.com/new-domain/foobar
Dear Guilherme
I am terribly sorry to pester you further but I have been trying and trying all day and things just don’t go.
Currently the domains browns.co.uk, brownsbox.com and mainsdata.com all point to 217.46.224.255.
What I would like to happen is that when the client enters either or that they get /index.php but when they put in , I would like them either to get /mainsdata.php or /mainsdata/index.php. Finally, I am constrained to using just one server of either a physical variety or a virtual variety.
Many thanks for your help.
Trackbacks