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?
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:
However, the
Redirect
directive is not really the correct directive to use here, since you need two directives to handle this. (Generally, with theRedirect
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:This matches only
/example
or/example/
and redirects to/example.php
.Redirect
andRedirectMatch
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: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?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 theR
flag from the aboveRewriteRule
directive. For example:(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 toexample.php
.