Creating Apache redirects
Apache HTTP Server provides multiple methods to redirect URLs. This article covers some approaches and examples for Apache 2.4
What is a redirect?
Apache can create a redirect that points from one vhost to another vhost on the server or to another external site. Common reasons for using this feature are to force HTTP traffic to https and to move domain names.
Although complex rewrite configurations are not officially supported by the Global Linux Rackspace team, we are providing this information as a reference for customers who may choose to implement it at their discretion.
When to use redirects
Moving your website to a new domain.Enforcing HTTPS connections.Redirecting www to non-www (or vice versa).Restructuring your website URLs.Handling old URLs after site migration.Consolidating multiple domains into one.
Verify Apache version and module are enabled
$ sudo apache2 -v
# or on CentOS/RHEL
$ sudo httpd -v
# Check if modules are enabled (Ubuntu/Debian)
apache2ctl -M | grep -E 'alias|rewrite'
# Check on CentOS/RHEL
httpd -M | grep -E 'alias|rewrite'Enable Module if needed
# Ubuntu/Debian
sudo a2enmod alias
sudo a2enmod rewrite
# CentOS/RHEL (usually enabled by default)
# Edit /etc/httpd/conf.modules.d/00-base.conf
# Ensure these lines are present and uncommented:
# LoadModule alias_module modules/mod_alias.so
# LoadModule rewrite_module modules/mod_rewrite.soUnderstanding Redirect Types
| Code | Type | Use Case | SEO Impact
| **301** | Permanent Redirect | Domain changes, permanent URL moves | Passes ~90-99% of link equity
| **302** | Temporary Redirect | Temporary maintenance, A/B testing | Does not pass link equity
| **303** | See Other | POST to GET redirect | Specialized use
| **307** | Temporary Redirect | Maintains request method | Modern alternative to 302
| **308** | Permanent Redirect | Maintains request method | Modern alternative to 301Key Decision: Use 301 for permanent changes, 302/307 for temporary redirects.
Simple Redirect
The Redirect directive is the fastest and simplest method for straightforward redirects.
For understanding the basics of Regular Expression, please visit the Regular Expression Building Blocks Apache and Nginx article.
- Locate your virtual host file or .htaccess
- Add a simple Redirect.
Syntax:
Redirect [status] [URL-path] [destination-URL]
Example
# Redirect old page to new page
Redirect 301 /old-page.html https://example.com/new-page.html
# Redirect all pages under /old-directory/ to new location
Redirect 301 /old-directory/ https://example.com/new-directory/
# Redirect everything to new domain
Redirect 301 / https://new-domain.com/
Test Configuration
`<VirtualHost *:80>
DocumentRoot /var/www/example.com/httpdocs
ServerName example.com
Redirect 301 / https://example.com/ <-----
ServerAlias www.example.com
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /var/www/example.com/httpdocs
ServerName example.com
ServerAlias www.example.com
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/2017-example.com.crt
SSLCACertificateFile /etc/pki/tls/certs/CABundle.crt
SSLCertificateKeyFile /etc/pki/tls/private/2017-example.com.key
</VirtualHost>`# Test configuration syntax
$ sudo apache2ctl configtest
# or #
$ sudo httpd -t
# If OK, reload Apache
$ sudo systemctl reload apache2
# or #
$ sudo systemctl reload httpd
# Test with curl
$ curl -I http://example.com/old-page.htmlPattern-Based Redirects
Use RedirectMatch for pattern matching with regular expressions.
Syntax:
RedirectMatch [status] [regex-pattern] [destination-URL]
Example
# Redirect all .php files to .html equivalents
RedirectMatch 301 ^/(.*)\.php$ https://example.com/$1.html
# Redirect /blog/ or /news/ to /articles/
RedirectMatch 301 ^/(blog|news)/(.*)$ https://example.com/articles/$2
# Redirect all .htm files to .html
RedirectMatch 301 ^/(.*)\.htm$ https://example.com/$1.html
Apply and Test
# Test configuration syntax
$ sudo apache2ctl configtest
# or #
$ sudo httpd -t
# If OK, reload Apache
$ sudo systemctl reload apache2
# or #
$ sudo systemctl reload httpd
# Test with curl
$ curl -I http://example.com/page.phpUsing mod_rewrite
When to Use mod_rewrite:
Multiple conditions requiredQuery string manipulation neededComplex URL transformationsConditional redirects based on user agent, referrer, etc.
Syntax: RewriteRule [pattern] [substitution] [flags]
Common Flags:
R=301 - Redirect with 301 status
R=302 - Redirect with 302 status
L - Last rule (stop processing)
NC - Case-insensitive
QSA - Query String Append
Example: Force WWW Prefix
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>Remove WWW Prefix
<VirtualHost *:80>
ServerName www.example.com
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
</VirtualHost>Force HTTPS
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>Redirect Based on Query String
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
# If URL contains ?id=123, redirect to new URL
RewriteCond %{QUERY_STRING} ^id=123$
RewriteRule ^/product\.php$ /new-product-page.html? [R=301,L]
</VirtualHost>Redirect Multiple Old URLs
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
# Redirect multiple old pages
RewriteRule ^/about-us$ /about [R=301,L]
RewriteRule ^/contact-us$ /contact [R=301,L]
RewriteRule ^/services/web-design$ /services/design [R=301,L]
</VirtualHost>Multiple Conditions
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
# Don't redirect if already HTTPS and www
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ - [L]
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# Force WWW (after HTTPS is set)
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>Conditional Redirects with If Directive
# Force WWW with If
<VirtualHost *:80>
ServerName example.com
<If "%{HTTP_HOST} != 'www.example.com'">
Redirect 301 "/" "https://www.example.com/"
</If>
</VirtualHost>
# Redirect Based on User Agent
<VirtualHost *:80>
ServerName example.com
<If "%{HTTP_USER_AGENT} =~ /mobile|android/i">
Redirect 302 "/" "https://m.example.com/"
</If>
</VirtualHost>
# Block and Redirect Specific IPs
<VirtualHost *:80>
ServerName example.com
<If "%{REMOTE_ADDR} == '192.168.1.100'">
Redirect 403 "/" "https://example.com/blocked.html"
</If>
</VirtualHost>Maintenance Mode Redirect
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
# Exclude maintenance page itself
RewriteCond %{REQUEST_URI} !^/maintenance\.html$
# Exclude images and CSS for maintenance page
RewriteCond %{REQUEST_URI} !^/assets/
# Redirect all other requests
RewriteRule ^(.*)$ /maintenance.html [R=302,L]
</VirtualHost>Redirect All Except Specific Pages
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
# Don't redirect these pages
RewriteCond %{REQUEST_URI} !^/allowed-page\.html$
RewriteCond %{REQUEST_URI} !^/another-allowed-page\.html$
# Redirect everything else
RewriteRule ^(.*)$ https://new-site.com/$1 [R=301,L]
</VirtualHost>Note - You can use a third-party module as well to test your Redirect.
Updated 3 days ago
