Web Development

RewriteCond: Apache Conditional URL Rewriting Guide

Configure RewriteCond to filter Apache rewrite rules. Manage redirects using server variables, back-references, and regex patterns for SEO redirects.

1.3k
rewritecond
Monthly Search Volume
Keyword Research

RewriteCond is an Apache server directive that tells the software to only perform a URL redirect or rewrite if specific conditions are met. You place these conditions immediately before a RewriteRule to control when that rule triggers. Marketers use it to manage SEO redirects based on user devices, hostnames, or specific server environments.

What is [RewriteCond]?

The RewriteCond directive acts as a filter for the RewriteRule that follows it. It evaluates a specific "TestString" (such as a browser type or an IP address) against a "CondPattern" (usually a regular expression). If the test matches the pattern, the server moves to the next condition or executes the rewrite rule.

You can use an unlimited number of conditions for a single rule. By default, the server evaluates multiple RewriteCond directives using a logical AND sequence. This means every condition must be true for the rewrite to occur unless you specify otherwise with flags.

Why [RewriteCond] matters

Using conditions prevents blanket redirects that might hurt your site's SEO or user experience.

  • Device-Specific Targeting: Deliver mobile-specific pages only to users on mobile browsers by checking the HTTP_USER_AGENT variable.
  • Preventing Hotlinking: Protect your server bandwidth by blocking other sites from embedding your images.
  • Canonical Hostnames: Ensure all traffic goes to the "www" or "non-www" version of your site by checking the HTTP_HOST.
  • Maintenance Windows: Redirect users to a "down for maintenance" page based on the server's time variables.
  • Security and Access Control: Block specific IP addresses or referrers that show suspicious patterns.

[Using a high trace log level for mod_rewrite will slow down the Apache HTTP Server dramatically] (Apache HTTP Server Documentation). Always use levels higher than trace2 only for temporary debugging.

How [RewriteCond] works

The rewriting engine follows a specific sequence to process your conditions:

  1. Rule Evaluation: The server actually looks at the RewriteRule first to see if the URL pattern matches.
  2. Condition Testing: If the rule matches, the server then evaluates any RewriteCond directives placed above that rule.
  3. Variable Expansion: The server expands variables in the TestString, such as %{HTTP_HOST} or %{QUERY_STRING}.
  4. Pattern Matching: The server compares the expanded string against the CondPattern using Perl Compatible Regular Expressions (PCRE).
  5. Execution: If the conditions are met, the server performs the substitution defined in the RewriteRule.

Back-references

RewriteCond creates back-references that you can reuse later. While RewriteRule uses $N (like $1, $2) to reference parts of its matched pattern, RewriteCond uses %N (like %1, %2) to reference grouped parts of its own patterns.

Best practices

Use the NC flag for case-insensitivity. When matching strings like User-Agents or hostnames, use the [NC] (no case) flag to ensure the condition catches variations in capitalization.

Limit use of internal subrequests. The -F (file via subrequest) and -U (URL via subrequest) tests check if a file or URL exists via a secondary internal request. [These checks can impact your server's performance and should be used with care] (Apache HTTP Server Documentation).

Clean up your logs. In modern Apache versions, [the functionality of RewriteLog and RewriteLogLevel has been completely replaced by the per-module LogLevel configuration] (Apache HTTP Server Documentation). Use LogLevel alert rewrite:trace3 to see detailed processing for debugging.

Use the OR flag for multiple alternatives. If you want a rule to trigger if any of several conditions are true, append the [OR] flag to each RewriteCond except the last one.

Common mistakes

  • *Mistake:* Putting a leading slash in .htaccess conditions. In a per-directory context (like .htaccess), the directory path is stripped before matching. Fix: Patterns in .htaccess should not start with a slash because they match against a string that never has one.

  • *Mistake:* Negating patterns and using back-references. If you use ! to negate a pattern, you cannot use %N in your substitution string. Fix: Only use back-references when the condition is set to match a pattern, not when it is set to "not match."

  • *Mistake:* Forgetting that Virtual Hosts do not inherit rules. [Rewrite configurations are not inherited by virtual hosts by default] (Apache HTTP Server Documentation). Fix: Place a RewriteEngine on directive inside every virtual host where you want to use conditions.

  • *Mistake:* Confusing $1 with %1. Using the wrong symbol for back-references causes the server to insert empty strings or incorrect data. Fix: Use $ for groups found in the RewriteRule and % for groups found in the RewriteCond.

Examples

Redirect mobile users to a subfolder

This scenario checks the User-Agent string to see if the visitor is using a mobile platform.

RewriteCond "%{HTTP_USER_AGENT}" "(iPhone|Blackberry|Android)"
RewriteRule "^/$" "/homepage.mobile.html" [L]

Block image hotlinking

This scenario checks the HTTP_REFERER to ensure it matches your own site's hostname. If it does not match, the request for any image file in the /images folder is forbidden.

RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule "^/images" "-" [F]

Redirect specific IP address range

This scenario uses a regular expression to match an internal IP range and sends those users to a specific intranet server.

RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
RewriteRule "(.*)" "http://intranet.example.com$1"

FAQ

What variables can I test with RewriteCond? You can test HTTP headers (like HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE), server internals (SERVER_ADDR, DOCUMENT_ROOT), and date/time variables (TIME_YEAR, TIME_DAY). You can also check the QUERY_STRING to find specific parameters in a URL.

Does RewriteCond support numeric comparisons? Yes. You can use operators like -eq (equal), -gt (greater than), and -lt (less than). These treat the values as integers rather than strings, which is useful for checking timestamps or port numbers.

How do I test if a file exists on the server? You can use the -f flag to check if the TestString is a regular file on the disk. For example, RewriteCond %{REQUEST_FILENAME} !-f is a common way to say "only run this rule if the requested file does not exist."

What is the difference between [L] and [END] flags? The [L] flag stops the current rewriting process but may trigger again in certain contexts like .htaccess. [The END flag stops the rewriting process immediately and prevents further execution of rewrite rules in per-directory and .htaccess contexts] (Apache HTTP Server Documentation).

Can I use multiple conditions for one rule? Yes. You can list several RewriteCond lines before a single RewriteRule. All must be true (AND logic) unless you add the [OR] flag to the end of the condition lines.

Start Your SEO Research in Seconds

5 free searches/day • No credit card needed • Access all features