Dev Notes

Software Development Resources by David Egan.

Moving a Site to a New Domain - Apache Redirects/Rewrites


Apache, Server, Sysadmin, WordPress
David Egan

When moving a site to a new domain, it’s important to redirect visitors to the new domain. This provides a courtesy to your users, helps retain search engine ranking, and prevents broken links to your site.

Apache provides several methods for redirecting requests and this article documents several approaches.

The rules should be tested properly before applying them. In our case, we set up a virtual machine with cloned versions of both new and old sites (with an appropriately modified hosts file) to allow full testing of all redirects.

Context

This article refers to a site that is being moved to a new domain as part of a re-branding exercise.

The site structure will remain broadly the same, but for two quite important differences. The old site permalink structure for the ‘projects’ and ‘people’ index pages is:

  • http://olddomain/category/people/
  • http://olddomain/category/projects/

On the new site, these index pages will be located at the following URLs:

  • http://newdomain/people/
  • http://newdomain/projects/

In addition, project categories (a custom taxonomy) are to be rationalised as part of the move/rebuild. The old URL structure involved having ‘projects’ as a category, with projects further grouped into sub-categories. For the new site, these sub-categories have been mapped into a more logical ‘project-category’ structure.

The resource found on the old domain at http://olddomain/category/projects/term/ should be available at http://newdomain/project-category/term/ on the new domain.

Approach

The redirects can be achieved with a combination of Redirect and Rewrite rules, or Rewrite rules only. Rules can be added on a Directory basis (either .htaccess or in a <Directory> block in the vHost config).

A better approach would probably be to include all necessary rewrite rules outside a <Directory> block within the vHost configuration. This allows the redirect to happen without even the presence of a directory corresponding to the old domain - so when the move is complete, the old site can be collapsed completely.

Per-Directory Rules: .htaccess

These rules are added to a .htaccess file in the root directory of the old site.

Redirect 301 /category/people/ http://newdomain.com/people/
Redirect 301 /category/projects/ http://newdomain.com/projects/

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !newdomain.com$ [NC]
RewriteCond %{REQUEST_URI} !^/category/people/$ [NC]
RewriteCond %{REQUEST_URI} !^/category/projects/$ [NC]
RewriteRule ^(category/projects/)(.*)$ http://newdomain.com/project-category/$2
RewriteRule ^(.*)$ http://newdomain.com/$1 [L,R=301]

Alternatively, the rewrite engine only could be used:

RewriteEngine On
Options FollowSymLinks
RewriteBase /
RewriteCond %{HTTP_HOST} !newdomain.com$ [NC]
RewriteRule ^(category/people/)$ http://newdomain.com/people/ [L,R=301]
RewriteRule ^(category/projects/)$ http://newdomain.com/projects/ [L,R=301]
RewriteRule ^(category/projects/)(.*)$ http://newdomain.com/project-category/$2 [L,R=301]
RewriteRule ^(.*)$ http://newdomain.com/$1 [L,R=301]

Note that the first string to be matched should not have a leading slash. This is because in the directory context (within either a <Directory> block or a per-directory .htaccess file) the removed prefix always ends with a slash - so a Pattern with ^/ never matches in the per-directory context.

Bracketed sections of the source string are available as indexed variables in the destination string:

...
# Rewrite http://olddomain.com/first-string/second-string/...
# ...to http://newdomain/second-string:
RewriteRule ^(first-string/)(second-string)$ http://newdomain/$2`

NOTE for testing purposes, you should designate these rules as “302” - a temporary redirect. These should be amended to “301” to denote a permanent redirect when you deploy the rules to the production server.

These rules could be placed in either a .htaccess file in the olddomain.com document root or a <Directory> block in the site virtual host configuration file for the old site (e.g. /etc/apache2/sites-available/olddomain.com.conf). If adding the rules to an Apache config file, you’ll need to restart Apache for the rules to take effect.

Simple vHost Redirect

This block added to the virtual host configuration of the old site provides a one-to-one mapping of the old domain to the new. If the site retains the exact same permalinks (apart from the domain of course), this might be an adequate solution. Note that a <Directory> block is not necessary:

<VirtualHost *:80>
        ServerName oldsite.com
        ServerAlias www.oldsite.com
        ServerAdmin info@olddomain.com

        Redirect 301 / http://newdomain.com

        ErrorLog ${APACHE_LOG_DIR}/oldsite.com.error.log
        CustomLog ${APACHE_LOG_DIR}/oldsite.com.access.log combined
</VirtualHost>

This kind of simple redirect isn’t going to work in our case, because the structure of some of our URLs will be altered.

Complete vHost Redirect

Here’s the final virtual host config file solution:

<VirtualHost *:80>
        ServerName olddomain.com
        ServerAlias www.olddomain.com
        ServerAdmin info@olddomain.com
        RewriteEngine On
        RewriteCond %{HTTP_HOST} !newdomain.com$ [NC]
        RewriteRule ^(/category/people/)$ http://newdomain.com/people/ [L,R=301]
        RewriteRule ^(/category/projects/)$ http://newdomain.com/projects/ [L,R=301]
        RewriteRule ^(/category/projects/)(.*)$ http://newdomain.com/project-category/$2 [L,R=301]
        RewriteRule ^(.*)$ http://newdomain.com/$1 [L,R=301]
</VirtualHost>

Don’t forget to restart Apache for the rewrite rules to take effect.

References


comments powered by Disqus