Apache mod_rewrite Compatibility Module for Nginx
This module provides Apache's mod_rewrite compatibility for Nginx, enabling .htaccess file support and standard rewrite rules.
Configuration Directives
The following directives are available in this module:
1. RewriteEngine
Purpose: Enable or disable the rewrite engine.
| Context | Available Levels |
|---|---|
main, server, location |
✓ All three levels supported |
Syntax:
RewriteEngine on|off
Possible Values:
on- Enable rewrite engineoff- Disable rewrite engine (default)
Example in nginx.conf:
http {
server {
RewriteEngine on;
location /blog/ {
# Rules apply here
}
location /static/ {
RewriteEngine off; # Disable for this location
}
}
}
2. RewriteRule
Purpose: Define a rewrite rule that matches a URL pattern and substitutes it with a new value.
| Context | Available Levels |
|---|---|
server, location |
✓ Server and Location level |
.htaccess |
✓ Supported in .htaccess files |
Syntax:
RewriteRule pattern substitution [flags]
Parameters:
-
pattern - Regular expression to match the URL (supports backreferences $1, $2, etc.)
- Pattern can be prefixed with
!for negation -as substitution means "no substitution" (only match for conditions)
- Pattern can be prefixed with
-
substitution - Target URL or file path to rewrite to
- Can be a relative path (
/new/path) or absolute redirect (http://example.com/new)
- Can be a relative path (
Flags: [flag1,flag2,...] (optional):
| Flag | Abbreviation | Description |
|---|---|---|
B |
- | Escape backreferences in output (prevent URL encoding issues) |
C |
Chain | Chain this rule with the next one (requires previous match) |
D |
DPI | Discard path info after substitution |
E |
Env=var:val | Set an environment variable for later use (FastCGI integration) |
F |
Forbidden | Return HTTP 403 Forbidden status |
G |
Gone | Return HTTP 410 Gone status |
L |
Last | Stop processing rules after this one |
N |
Next=limit | Loop (retry) up to N times for infinite rewriting prevention |
P |
Proxy | Proxy the request internally (Phase 2) |
Q |
QSA | Append original query string to substitution URL |
Q |
QSD | Discard original query string |
Q |
QSL | Set "query string last" marker |
R |
Redirect=code | Perform external redirect with status code (301, 302, 307) or: Permanent, Temp, SeeOther |
S |
Skip=N | Skip N subsequent rules after this one |
T |
Type=mime | Force specific MIME type for the response |
NC |
- | Case-insensitive matching |
NOESCAPE |
- | Do not escape special characters in output |
END |
- | Stop all rewriting and pass to content phase |
Example:
# Redirect /old-path/ to /new-path/ (permanent redirect)
RewriteRule ^old-path/(.*)$ /new-path/$1 [R=301,L]
# Condition-based rewrite (chain)
RewriteCond %REQUEST_URI !^/admin/
RewriteRule ^admin/(.*)$ /login.php?user=$1 [NC,E,END]
# In .htaccess:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
3. RewriteCond
Purpose: Define conditions that must be met before a RewriteRule is applied. Multiple conditions are ANDed together; OR flag can change this behavior.
| Context | Available Levels |
|---|---|
server, location |
✓ Server and Location level |
.htaccess |
✓ Supported in .htaccess files |
Syntax:
RewriteCond input_string pattern [flags]
Parameters:
-
input_string - Variable or string to test (e.g.,
%REQUEST_URI,%HTTP_HOST,%REQUEST_FILENAME)- Common variables:
REQUEST_URI,HTTP_HOST,REQUEST_METHOD,REQUEST_FILENAME
- Common variables:
-
pattern - Test pattern for the condition:
- File tests:
-f(file exists),-d(directory exists),-x(executable),-s(non-zero size) - Link tests:
-hor-l(hard/soft link),-L(link target exists) - Integer comparisons:
-lt,-le,-eq,-gt,-ge,-ne - String comparisons:
=,>,<,>=,<= - Regular expressions: Any regex pattern
- File tests:
-
flags (optional):
NC- Case-insensitive matchingOR/ornext- OR logic between conditions (instead of AND)
Examples:
# Condition: file exists
RewriteCond %REQUEST_FILENAME -f
# Condition: not a directory
RewriteCond %REQUEST_FILENAME !-d
# Condition: string comparison
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
# Integer comparison (file size > 1024 bytes)
RewriteCond %REQUEST_FILENAME -s
RewriteCond %{FILESIZE} -gt 1024
# Multiple conditions with OR logic
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{HTTPS} off
# Regular expression pattern
RewriteCond %{REQUEST_URI} ^/old/(.*)$
4. RewriteBase
Purpose: Set the base URL path for relative substitutions in rewrite rules.
| Context | Available Levels |
|---|---|
location |
✓ Location level only |
.htaccess |
✓ Supported in .htaccess files |
Syntax:
RewriteBase /path/
Parameters:
- Must start with
/and end with/(trailing slash required)
Example:
# Inside a specific location
location /blog/ {
RewriteBase /blog/
# Relative substitution resolves to: /blog/news.html
RewriteRule ^news\.html$ news.php [L]
}
# In .htaccess:
RewriteEngine on
RewriteBase /subdir/
RewriteRule ^index\.html$ home.php [L]
5. RewriteOptions
Purpose: Configure rewrite behavior options that affect rule inheritance and processing order.
| Context | Available Levels |
|---|---|
main, server, location |
✓ All three levels supported |
Syntax:
RewriteOptions option1 [option2 ...]
Possible Options:
| Option | Description |
|---|---|
Inherit |
Inherit rules from parent locations/servers (default behavior) |
InheritBefore |
Process parent rules before child rules |
Example:
http {
server {
RewriteOptions Inherit
location /parent/ {
RewriteRule ^parent/(.*)$ /new/$1 [L]
}
location /child/ {
# Inherits rules from parent by default with 'Inherit' option
RewriteBase /child/
}
}
}
6. RewriteMap
Purpose: Define name-value mappings for lookup tables in rewrite expressions.
| Context | Available Levels |
|---|---|
server |
✓ Server level only |
.htaccess |
✗ Not supported in .htaccess |
Syntax:
RewriteMap name type:source
Parameters:
- name - Map identifier (used as variable like
%MAPNAME:value) - type - Type of map:
int- Internal function (supported:tolower,toupper,escape,unescape)txt- Text file lookup (not supported yet)rnd- Random lookup (not supported yet)prg- Program lookup (not supported yet)
Example:
server {
# Map to lowercase version of hostname
RewriteMap lc int:tolower
server_name example.com;
location / {
# Use mapped value in rule
RewriteRule ^lc/([^/]+)$ /redirect/$1 [L]
}
}
# Usage in rules:
RewriteRule ^(.*)$ /%lc:$1 [L]
7. HtaccessEnable
Purpose: Enable or disable .htaccess file parsing for the server/location.
| Context | Available Levels |
|---|---|
main, server |
✓ Main and Server level only |
.htaccess |
✗ Not supported in .htaccess |
Syntax:
HtaccessEnable on|off
Parameters:
on- Enable.htaccessparsingoff- Disable.htaccessparsing (default)
Example:
http {
server {
HtaccessEnable on
# .htaccess files will be searched upward from the request path
location /subdir/ {
root /var/www/html;
}
}
}
# In nginx.conf, you can also enable at http level:
http {
HtaccessEnable on;
server {
# Inherits setting from http level
}
}
8. HtaccessName
Purpose: Specify an alternative filename for .htaccess files.
| Context | Available Levels |
|---|---|
main, server |
✓ Main and Server level only |
.htaccess |
✗ Not supported in .htaccess |
Syntax:
HtaccessName filename
Parameters:
- Any string (default is
.htaccess)
Example:
server {
HtaccessName .webconfig
# Will look for .webconfig files instead of .htaccess
location / {
root /var/www/html;
}
}
# In .htaccess:
HtaccessEnable on
HtaccessName .custom_htac
9. RewriteFallBack
Purpose: Specify an alternative fallback path when the rewritten file doesn't exist (instead of default /index.php). This directive can only be used in .htaccess files and is read by ngx_htaccess_parse_file_from_ha(). The fallback path is cached per request and retrieved in ngx_http_apache_rewrite_url_register_hook_with_fallback().
| Context | Available Levels |
|---|---|
.htaccess |
✓ Supported only in .htaccess files |
Syntax:
RewriteFallBack /path/to/fallback.php
Parameters:
- Path must start with
/(required) - Default fallback is
/index.phpif not specified
Example in .htaccess:
# Use custom fallback when file not found
RewriteFallBack /custom/app.php
# Fallback will redirect to /custom/app.php?query_string instead of /index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
Example with query string:
RewriteFallBack /handler.php?lang=ru
# When file doesn't exist, request is redirected to the fallback path
# preserving the original query string if present
Configuration Levels Summary
| Directive | http/main | server | location | .htaccess |
|---|---|---|---|---|
| RewriteEngine | ✓ | ✓ | ✓ | ✓ |
| RewriteRule | - | ✓ | ✓ | ✓ |
| RewriteCond | - | ✓ | ✓ | ✓ |
| RewriteBase | - | - | ✓ | ✓ |
| RewriteOptions | ✓ | ✓ | ✓ | - |
| RewriteMap | - | ✓ | - | - |
| HtaccessEnable | ✓ | ✓ | - | - |
| HtaccessName | ✓ | ✓ | - | - |
| RewriteFallBack | ✗ | ✗ | - | ✓ |
.htaccess File Format
.htaccess files follow the Apache format:
# Comments start with #
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/old/(.*)$
RewriteRule ^old/(.*)$ /new/$1 [R=301,L]
# Multiple conditions (AND logic by default)
RewriteCond %{HTTP_HOST} www\.example\.com$
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
RewriteBase /subdir/
RewriteFallBack /custom/fallback.php
RewriteCond !-f
RewriteCond !-d
RewriteRule ^(.*)$ index.php?route=$1 [QSA,L]
When a file doesn't exist after URL rewriting, the module falls back to:
RewriteFallBackpath if specified in.htaccess, or/index.phpas default fallback
Module Features
FastCGI Integration
The module automatically passes environment variables (set via [E=VAR:VAL] flags) to FastCGI applications without manual configuration.
Environment Variables
Environment variables persist across request phases and are available for downstream modules.
.htaccess Caching
.htaccess files are cached by modification time in the request pool to improve performance on repeated requests. The RewriteFallBack directive is also stored in the cache entry and retrieved when needed.
RewriteFallBack Directive
The RewriteFallBack directive allows customizing the fallback path used when a rewritten file doesn't exist:
- Caching: The fallback path from
.htaccessis cached per request to avoid repeated parsing - Fallback Logic: When
try_filesfails, the module redirects to the configured fallback instead of/index.php - Query String Preservation: Original query string is preserved and appended to fallback path
Notes
- Rewrite rules are processed in order as defined in configuration or
.htaccessfiles - The
[L]flag stops processing at the current rule - The
[N]flag enables looping for infinite redirects prevention (max 10,000 rounds) - Location-level rules override server-level rules unless
Inheritoption is set