When migrating websites or restructuring URLs, Apache's Redirect
directive can sometimes behave unexpectedly with trailing slashes. The core issue occurs when:
- Source URL has a trailing slash
- Destination is a PHP file
- The redirect incorrectly appends a slash to the destination
The standard approach:
Redirect 301 /example/ /example.php
Results in the undesired redirect to example.php/
. This happens because Apache's Redirect
directive treats the trailing slash as part of the path to be preserved.
For precise control over URL redirects, mod_rewrite
is more flexible:
RewriteEngine On
RewriteRule ^example/?$ /example.php [L,R=301]
Key advantages:
/?
makes the trailing slash optional- No slash gets appended to the destination
- Works for both
/example
and/example/
Here's a robust implementation that handles multiple cases:
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect /example/ and /example to /example.php
RewriteRule ^example/?$ /example.php [L,R=301]
# Alternative version that preserves query strings
RewriteCond %{REQUEST_URI} ^/example/?$
RewriteRule .* /example.php [L,R=301,QSA]
</IfModule>
Always verify redirects using:
- Browser's network inspector
- cURL command:
curl -I https://yoursite.com/example/
- Online redirect checkers
- Forgetting to enable
RewriteEngine On
- Not clearing browser cache when testing
- Mixing
Redirect
andRewriteRule
directives for the same paths - Omitting the
[L]
flag which can cause rule interference
When migrating a website or changing URL structures, we often need to set up 301 redirects in the .htaccess file. A common issue arises when dealing with URLs that may or may not have trailing slashes.
Consider this standard redirect:
Redirect 301 /example /example.php
This works perfectly for requests to /example
, but fails when users access /example/
(with trailing slash). The natural solution might seem to be:
Redirect 301 /example/ /example.php
However, this creates a new problem - the redirect adds a trailing slash to the destination, resulting in example.php/
, which breaks the URL.
The Redirect
directive in Apache's mod_alias has this behavior by design. When the source path ends with a slash, it preserves that slash in the destination URL. This is intentional for directory redirects but problematic for file redirects.
The more robust approach is to use mod_rewrite instead of mod_alias for these redirects. Here's how:
RewriteEngine On
RewriteRule ^example/?$ /example.php [L,R=301]
This solution:
- Matches both
/example
and/example/
(the/?
makes the slash optional) - Redirects to the exact destination URL without adding a trailing slash
- Uses a 301 (permanent) redirect status
For multiple similar redirects, you can create a more generic rule:
RewriteEngine On
RewriteRule ^([a-z0-9-]+)/?$ /$1.php [L,R=301]
This will redirect any alphanumeric path (with optional trailing slash) to its corresponding .php file.
If you need to preserve query parameters during the redirect:
RewriteEngine On
RewriteRule ^example/?$ /example.php [QSA,L,R=301]
The QSA
flag (Query String Append) ensures any original query parameters are passed through to the destination URL.
Always test redirects thoroughly. You can use:
curl -I http://yoursite.com/example
curl -I http://yoursite.com/example/
Check that both return:
HTTP/1.1 301 Moved Permanently
Location: http://yoursite.com/example.php