Inside this Article
What is mod_rewrite?
The mod_rewrite module is an Apache tool that lets you change URLs using a set of rules. It works at the server level and modifies incoming requests before they reach your website. With mod_rewrite, you can:- Turn long, complex URLs into clean, search engine-friendly ones
- Redirect requests based on certain conditions, like the visitor’s device or location
- Create shorter or custom URLs
- Enforce a single, preferred version of a URL to improve SEO
- Restrict access to certain parts of your site based on different criteria
.htaccess
or httpd.conf
. The former is a directory-level configuration file that controls how your web server responds to different requests, while the latter manages the main configuration for the Apache server.
Although mod_rewrite is a powerful tool for managing URLs and improving SEO, using too many rules or complex conditions can slow down your server. You should always double-check your rules to avoid unintentionally exposing sensitive parts of your website, such as admin panels or database files.
Enabling mod_rewrite
Before you use mod_rewrite, make sure it’s enabled on your Apache server. Here’s how to do that:- Verify mod_rewrite installation: Check if mod_rewrite is installed on your server. Run the following command in your terminal or command line interface:
apachectl -M | grep rewrite
.This command will list all the modules currently enabled on your Apache server. If rewrite_module appears in the list, mod_rewrite is installed and enabled. If not, you’ll have to install it. - Install mod_rewrite (if necessary): You must install mod_rewrite if it isn’t listed. It’s usually included with Apache on macOS, but ensure it’s enabled in the configuration file. The installation method depends on your operating system:
-
- •
-
- Run the code
sudo apt-get install libapache2-mod-rewrite
-
- to install. Once installed, enable the module with
sudo a2enmod rewrite
-
- •
-
- Run the code
sudo yum install mod_rewrite
-
- to install mod_rewrite
-
- •
-
- Run the code
brew install apache2
- to install the mod_rewrite module
-
- Enable mod_rewrite in Apache configuration: Once mod_rewrite is installed, open your Apache configuration files like
httpd.conf
,apache2.conf
, or the virtual host configuration file. Locate the line that loads the mod_rewrite module, which should look like this:LoadModule rewrite_module modules/mod_rewrite.so
.Note: If this line is commented out with a ‘#’ at the beginning, remove the hash sign to uncomment it. Save the configuration file after making the changes. - Restart Apache server: After editing the configuration file, restart the Apache server for the changes to take effect. Use one of the following commands based on your operating system:• Debian/Ubuntu-based systems:
sudo service apache2 restart
• Red Hat/CentOS-based systems:sudo systemctl restart httpd
• macOS:sudo apachectl restart
- Test mod_rewrite: After enabling it, test if mod_rewrite is working properly. Create a simple
.htaccess
file in your web root directory with the following content:RewriteEngine On
This rule redirects requests from
Rewrite Rule ^test\.html$ index.html [L]test.html
toindex.html
. Place atest.html
file in your web directory, then try accessing “test.html” in your browser. If it redirects toindex.html
, mod_rewrite will function properly.
Basic Syntax and Directives
The mod_rewrite module uses a specific syntax and set of directives to define rewrite rules. At its core, mod_rewrite maps a URL to a filesystem path on the server. When you request a URL, mod_rewrite can transform that URL into a path that corresponds to a specific file or directory on your server. Here’s an overview of the basic syntax and some commonly used directives:RewriteRule Directive
TheRewriteRule
directive is the core of mod_rewrite. It defines a rule that matches a specific URL pattern and specifies how to rewrite or redirect the URL. The basic syntax of a RewriteRule
is: RewriteRule pattern substitution [flags]
- Pattern: A regular expression that matches the requested URL. Regular expressions are sequences of characters that define search patterns for matching complex URL structures.
- Substitution: The new URL or transformation to apply to the matched URL.
- Flags (optional): Flags are additional options that control how Apache processes the rule. They can determine if the rule should stop further processing, apply to case-insensitive matches, perform a redirect, or append query strings to the new URL.
/old-page.html
to /new-page.html
. In this example:
^old-page\.html$
is the pattern that matches the exact URL/old-page.html
. The caret (^) indicates the start of the string and the dollar sign ($) indicates the end, ensuring an exact match./new-page.html
is the substitution, which rewrites the matched URL to/new-page.html
.[L]
is a flag that tells Apache to stop processing further rules if this pattern matches. This prevents any other rules from interfering with this one.
RewriteCond Directive
TheRewriteCond
directive lets you set specific conditions that must be true before Apache applies a RewriteRule
. This gives you greater control over when to trigger a rewrite rule. The basic syntax of a RewriteCond
is: RewriteCond TestString CondPattern [flags]
- TestString: This is the string or server variable that Apache tests against the condition pattern. Commonly used server variables include
%{REQUEST_FILENAME}
, which represents the file path of the requested URL, and%{HTTP_HOST}
, which refers to the domain name. You can also use environment variables or static text here. - CondPattern: This is the condition that Apache uses to test the
TestString.
It can be a regular expression or a special pattern, such as:
Common Flags | Optional Flags | ||
-f | Checks if the file exists | [NC] | Makes the condition case-insensitive |
-d | Checks if the directory exists | [OR] | Lets you combine this condition with others using a logical OR, so Apache applies the rule if any one condition is true |
-s | Checks if the file exists and is not empty | [L] | Stops processing conditions if this one is met |
-l | Checks if the file is a symbolic link | ! | Negates the condition, meaning “does not exist” or “is not true” |
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [L]
In this example, the RewriteCond
checks if the requested file doesn’t exist on the server. %{REQUEST_FILENAME}
is the path to the requested file, and !-f
means the file doesn’t exist. If the condition is true and the file doesn’t exist, Apache applies the RewriteRule
. It rewrites the URL to /index.php?url=$1
, where $1
represents the original requested URL.
Common Flags
Flags are used to modify the behavior of rewrite rules and conditions. In addition to the flags mentioned above, here are a few others:- [R=301] (Redirect): Performs a 301 permanent redirect instead of rewriting the URL. You can also use other status codes, such as
[R=302]
for a temporary redirect. - [F] (Forbidden): Forbids access to the matched URL and returns a 403 Forbidden status to the client. This is useful for blocking access to certain parts of your site.
- [QSA] (Query String Append): Appends any existing query string from the original URL to the substituted URL, preserving parameters across rewrites.
- [P] (Proxy): Forwards the request to another server as a proxy, without redirecting the client’s browser. This is useful when integrating with backend services or external servers.
- [S=num] (Skip): Skips the next num rules if the current rule matches. This is useful for creating conditional logic in your rewrite rules.
- [B] (Escape Backreferences): Escapes special characters in backreferences, such as query strings, to prevent issues when rewriting URLs that contain special characters.
- [NE] (No Escape): Prevents Apache from escaping special characters in the output URL, allowing you to include characters like &, #, or % in the final URL.
Practical Examples of mod_rewrite
Now that you understand the basic syntax and directives, let’s explore some practical examples of using mod_rewrite.Example 1: Rewriting Dynamic URLs
Suppose you have dynamic URLs like/product.php?id=123
, and you want to rewrite them to clean, search engine-friendly URLs like /product/123
. You can do this using mod_rewrite:
RewriteEngine On
RewriteRule ^product/(\d+)$ /product.php?id=$1 [L]
In this example, you can use the RewriteEngine On
” directive to enable mod_rewrite so it can start processing the rules. The “RewriteRule
” directive matches URLs that start with “/product/
” followed by one or more digits. The “(\d+)
is a capturing group that captures these digits.
The $1
in the substitution part refers to the captured digits. If the URL matches /product/123,
it rewrites to /product.php?id=123
. The [L]
flag tells Apache to stop processing any further rules once this rule matches.
Example 2: Implementing Redirects
You should redirect users and search engines from an old URL to a new one. Here’s how you can do it with a permanent (301) redirect using the Redirect directive:Redirect 301 /old-page.html http://www.example.com/new-page.html
Any request to /old-page.html
redirects to http://www.example.com/new-page.html
Note: The Redirect directive comes from Apache’s “mod_alias” module, which is useful for basic redirects. However, if you need more control or want to use mod_rewrite, you can perform the same redirect like this:
RewriteEngine On
RewriteRule ^old-page\.html$ http://www.example.com/new-page.html [R=301,L]
Example 3: Enforcing Canonical URLs
Canonical URLs help you avoid duplicate content issues by making sure that only one version of a URL is used Here’s how you can enforce canonical URLs, using mod_rewrite:RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
In the above example, the RewriteCond
directive checks if the URL includes the “www” subdomain. If it does, RewriteRule
redirects you to the same URL without the “www” subdomain. The [R=301]
flag indicates a permanent redirect and the [L]
flag stops further processing of rules.
Best Practices and Tips
When working with mod_rewrite, follow these best practices and tips to ensure your rewrite rules are effective and efficient:- Understand your URL structure: Start with a clear understanding of your URL structure and the transformations you want to achieve. This helps you create rewrite rules that align with your goals.
- Thoroughly test your Rewrite Rules: Test your rules in a development environment before deploying them live so that you can catch any errors or unintended consequences that could disrupt your site’s functionality.
- Use the “[L]” flag: This flag stops processing additional rules once a match is found. As a result, you can prevent unnecessary processing and potential conflicts with other rules.
- Mind the order of your rules: Place your rewrite rules in the correct order, as Apache processes them sequentially. The order in which you place rules can affect how URLs get rewritten.
- Leverage server variables: Use server variables like
%{HTTP_HOST}
and%{REQUEST_URI}
to create dynamic conditions and substitutions. This makes your rewrite rules more flexible and powerful. - Enable logging and debugging: For Apache 2.4 and later, use the
LogLevel
directive with the “rewrite” option, likeLogLevel warn rewrite:trace3
to enable detailed logging for debugging purposes. - Review your work: Regularly review and optimize your rewrite rules to ensure they remain efficient and relevant as your site evolves. Remove or update rules that are no longer necessary.
- Use the [QSA] flag: When appending query strings, include the
[QSA]
(Query String Append) flag to preserve any existing query string in the rewritten URL. This prevents accidental loss of query parameters. - Consider security: Be cautious with user input in URLs. Not handling it properly can lead to security vulnerabilities, such as open redirects.
- Enforce HTTPS: Use mod_rewrite to enforce HTTPS across your site if you haven’t already. This enhances security and meets modern expectations for secure web browsing.