The <If> directive in Apache allows for conditional execution of configuration directives based on server variables. The correct syntax requires careful attention to expression formatting:
<If "%{VARIABLE_NAME} =~ /pattern/">
# Configuration here
</If>
Here are several practical implementations that work in .htaccess files:
1. Checking Request Method
<If "%{REQUEST_METHOD} in ['GET','HEAD','OPTIONS']">
Header set X-Method-Valid "true"
</If>
2. Port-Based Configuration
The original question had an incorrect port check example. Here's the proper way:
<If "%{SERVER_PORT} == '80'">
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</If>
The error in the original question occurred because:
- SERVER_PORT was checked against HTTP methods (invalid comparison)
- Missing quotes around the comparison value
- Possible missing expression delimiters
For more complex scenarios:
<If "(%{HTTP_HOST} =~ /example\.com/) && (%{HTTPS} != 'on')">
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</If>
- Always wrap expressions in double quotes
- Use proper comparison operators: ==, !=, <, >, =~ (regex match)
- For string lists, use square brackets: ['value1','value2']
- Combine conditions with && (AND) or || (OR)
- Verify AllowOverride includes FileInfo (required for <If> directives)
- Check Apache error logs for specific syntax errors
- Test with simpler conditions first
- Ensure you're using Apache 2.4+ (earlier versions don't support this syntax)
The <If> directive in Apache's .htaccess allows for conditional execution of configuration directives based on various server variables. Unlike IfDefine or IfModule, it evaluates expressions at request time.
Your example contains a logical error - comparing SERVER_PORT (which is numeric) with HTTP methods. Here's the correct way to check request methods:
<If "%{REQUEST_METHOD} in ['GET','HEAD','OPTIONS']">
# Configuration for safe methods
Header set X-Safe-Method "true"
</If>
For port checking (which appears to be what you intended):
<If "%{SERVER_PORT} == 80">
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
</If>
The 500 error you encountered typically occurs when:
- Using incorrect expression syntax (missing quotes, wrong operators)
- Comparing incompatible variable types
- Having unclosed
<If>blocks
Combine multiple conditions:
<If "%{REQUEST_URI} =~ /\.php$/ && %{QUERY_STRING} =~ /debug=1/">
php_flag display_errors on
</If>
Check request headers:
<If "%{HTTP_USER_AGENT} =~ /Mobile/">
RewriteRule ^(.*)$ /mobile/$1 [L]
</If>
While powerful, overusing <If> can impact performance. For static conditions, consider:
IfModulefor module availability checksIfDefinefor build-time conditions- Environment variables for complex logic
Always test .htaccess changes gradually. Use:
apachectl configtest
Or check error logs for specific syntax errors when encountering 500 errors.