.htaccess Redirect 301 with trailing slash adds trailing slash to destination
Just had my website re-done and am trying to set up redirects in the .htaccess file for links that have changed
This works fine, except it doesn't work for /example/
(with trailing slash on source path)
Redirect 301 /example /example.php
So I added this to account for the trailing slash:
Redirect 301 /example/ /example.php
But that redirects to example.php/
(adds a trailing slash to the destination, which does not work)
Clearly I'm doing this wrong. What is a better way?
But that redirects to
example.php/
That is caused by the first (original) rule. Note that the earlier (erroneous) 301 will likely have been cached by the browser. Test with 302 (temporary) redirects to avoid potential caching issues.
The Redirect
directive is prefix-matching (whole path segments), and everything after the match is appended to the end of the target URL. So, the first directive redirects:
-
/example
to/example.php
-
/example/
to/example.php/
and -
/example/abc
to/example.php/abc
If the directives are ordered like this then they should "work" for the two example URLs posted:
Redirect 301 /example/ /example.php
Redirect 301 /example /example.php
However, the Redirect
directive is not really the correct directive to use here, since you need two directives to handle this. (Generally, with the Redirect
directive, you need to either include or exclude the trailing slash on both the source and target URLs.)
You could use the RedirectMatch
directive instead, which matches using a regex. For example, to handle both with and without a trailing slash:
RedirectMatch 301 ^/example/?$ /example.php
This matches only /example
or /example/
and redirects to /example.php
.
Redirect
and RedirectMatch
are both part of mod_alias.
However, if you are already using mod_rewrite then consider using mod_rewrite RewriteRule
instead to avoid potential conflicts, since mod_rewrite always runs before mod_alias, despite the apparent order of the directives in .htaccess
. For example:
RewriteEngine On
RewriteRule ^example/?$ /example.php [R=301,L]
Note that there is no slash prefix on the RewriteRule
pattern when used in .htaccess
since the URL-path that the pattern matches against has had the directory-prefix (which always ends with a slash) removed.
Note also that the order of the directives within each module can be important.
Aside: If you've had your website "re-done", why are the "new" URLs of the form /example.php
? This would seem to be backward?
UPDATE: I had someone convert the original wordpress website to an (almost) equivalent site that used only HTML and a little javascript and php
You could potentially keep the original WordPress URLs (eg. /example
) and internally rewrite the request to the underlying file that handles the request (ie. example.php
) instead of externally redirecting. For this you would need to use mod_rewrite. You also need to be linking to the "old" WordPress URLs in your HTML source. eg. /example
(and consider canonicalising the trailing slash - redirect to one or the other).
To internally rewrite /example
(or /example/
) to /example.php
you simply need to remove the R
flag from the above RewriteRule
directive. For example:
RewriteRule ^example/?$ example.php [L]
(I've also removed the slash prefix on the RewriteRule
substitution, which is now not required since we are rewriting to a filesystem path.)
Providing you link to /example
in your HTML source then the user is unaware that the request is really mapped to example.php
.