The Science of Web Art, Design and Development

Domain redirect wizardry with .htaccess rules

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.

  1. The RewriteRule keyword
  2. A regular expression (regex) to match the original URI
  3. The URI to be redirected to and
  4. 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:

Maintenance page
You may want to redirect the whole traffic of your page for a few minutes or hours while you are performing an upgrade
Feedburner redirect
If you use feedbuner, you may want people to subscribe to an URI within your domain, but redirect to feedburner. If
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.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Netvouz
  • DZone
  • ThisNext
  • MisterWong
  • Wists
  • Technorati
  • BlogMemes
  • Ma.gnolia
  • YahooMyWeb
  • Netscape
  • Slashdot
  • StumbleUpon
Trackback URI

23 Comments

  • 1

    Nice; .htaccess redirects haven’t been one of my strong points. This is one of the best tutorials I’ve seen. Thanks!

    Friday, 2 January 2009, 20:03
  • 2
    Sue says:

    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?

    Friday, 2 January 2009, 20:29
  • 3

    @Adam Kayce – No, thank you for the kind words.

    @Sue –

    Thanks for the tutorial, Gui. You make it sound so simple and easy.

    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).

    Friday, 2 January 2009, 22:13
  • 4
    Patrick says:

    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…..

    Friday, 2 January 2009, 22:24
  • 5

    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

    Friday, 2 January 2009, 22:28
  • 6

    @Patrick – Hi Patrick, thanks. Regarding clients, I’m currently off-market, working only for Yahoo! but thanks for that too.

    @Mitchell Allen –

    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’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.

    Friday, 2 January 2009, 22:44
  • 7

    @Patrick – BTW, congratulations on the high number of subscribers on your blog, well deserved.

    Friday, 2 January 2009, 22:52
  • 8
    Michael says:

    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!

    Friday, 2 January 2009, 23:10
  • 9

    @Michael – Hi Michael, nice tutorial. I’ll play with it myself.

    Friday, 2 January 2009, 23:33
  • Michael says:

    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.

    P.S. You can follow me, too, I’m at http://twitter.com/bubbo

    Friday, 2 January 2009, 23:41
  • Damien says:

    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

    Saturday, 3 January 2009, 1:48
  • Marbl Host says:

    As someone who’s thinking about changing permalinks,this has come inhandy,Guioconner makes it seem so easy

    Wednesday, 11 February 2009, 10:47
  • DJPumpkin says:

    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?

    Tuesday, 17 February 2009, 13:51
  • @Michael, @Damien – Thanks, I’m glad it’s useful.

    @DJPumpkin –

    from
    http://www.oldomain.com/path/page
    to
    http://www.newdomain.com/path/to/page

    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.

    Thursday, 19 February 2009, 17:56
  • Jeet says:

    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.

    Saturday, 21 March 2009, 7:42
  • Rizwan says:

    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?

    Tuesday, 9 June 2009, 13:51
  • @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?

    Tuesday, 9 June 2009, 16:34
  • Rizwan says:

    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.

    Tuesday, 9 June 2009, 16:52
  • 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.

    Wednesday, 10 June 2009, 8:36
  • Andrew Brown says:

    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.

    Tuesday, 15 September 2009, 19:30
  • @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

    Wednesday, 16 September 2009, 8:27
  • Andrew Brown says:

    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.

    Wednesday, 16 September 2009, 19:24

Trackbacks

  1. Michael Bubbo » Blog Archive » Best Wordpress Permalink Structure