Welcome to WebmasterWorld Guest from 22.214.171.124
[edited by: not2easy at 3:44 pm (utc) on Dec 31, 2016]
[edit reason] Please use example.com for readability [/edit]
However it is creating a double 301 - because of course there are two redirects going on.
[edited by: phranque at 4:53 am (utc) on Jan 2, 2017]
[edit reason] unlinked url pattern for clarity [/edit]
Cleaning up an htaccess file
Step 1: Organize. Collect all the directives for each module in one place. The server doesn't care, but you-- and anyone who comes along after you-- will appreciate it.
Tip: Use a text editor with a "Find All" window to pull up all lines beginning with the element "Rewrite..." That takes care of mod_rewrite; dump them all at the end for now.
Step 2: Get rid of all <IfModule> envelopes. Not their contents, just the envelopes themselves. These envelopes are hallmarks of mass-produced htaccess files that have to work anywhere, on any server. You are now on your own site. Any given mod is either available to you or it isn't.
Exception: If you use a standard CMS such as WordPress, your htaccess file will contain a group of lines beginning and ending with #comments saying something like "begin WordPress" and "end WordPress". Leave everything in this package unchanged unless you know what you are doing.
Step 3: Sort by module. The server doesn't care what order the directives are listed in, or even if rules from different modules are all garbled together. Each module works separately, seeing only its own directives. But humans need to be able to find things.
For most people it will be most practical to group one-liners at the beginning:
is a good start. If your htaccess file contains only one line, that's probably it. Other quick directives are ones starting with words like AddCharset or Expires. Then list your error documents.
If you have any very short Files or FilesMatch envelopes, put them near the top too. For example:
Allow from all
Header set X-Robots-Tag "noindex"
Be sure to have an "Allow from all" envelope for your custom 403 page. If you are on shared hosting and they provide default error-document names such as "forbidden.html", this has probably already been done in the config file. But it does no harm to repeat it.
Step 4: Consolidate redirects.
Step 4a: Get rid of mod_alias. If your htaccess file contains any mod_rewrite directives, it can't use mod_alias (Redirect... by that name), or things may happen in the wrong order. For large-scale updating, use these Regular Expressions, changing \1 to $1 if that's what your text editor uses. Each of these can safely be run as an unsupervised global replace.
# change . to \. in pattern
^(Redirect \d\d\d \S+?[^\\])\.
# now change Redirect to Rewrite
^Redirect(?:Match)? 301 /(.+)
RewriteRule \1 [R=301,L]
# and if needed
^Redirect(?:Match)? 410 /(.+)
RewriteRule \1 - [G]
^Redirect(?:Match)? 403 /(.+)
RewriteRule \1 - [F]
Step 4b: Sort your RewriteRules. At the beginning is the single line
A RewriteBase is almost never needed; get rid of any lines that mention it. Instead, make sure every target begins with either protocol-plus-domain or a slash / for the root.
Sort RewriteRules twice.
First group them by severity. Access-control rules (flag [F]) go first. Then any 410s (flag [G]). Not all sites will have these. Then external redirects (flag [R=301,L] unless there is a specific reason to say something different). Then simple rewrite (flag [L] alone). Finally, there may be a few rules without [L] flag, such as cookies or environmental variables.
Function overrides flag. If your redirects are so complicated that they've been exiled to a separate .php file, the RewriteRule will have only an [L] flag. But group it with the external redirects. If certain users are forcibly redirected to an "I don't like your face" page, the RewriteRule will have an R flag. But group it with the access-control [F] rules.
Then, within each functional group, list rules from most specific to most general. In most htaccess files, the second-to-last external redirect will take care of "index.html" requests. The very last one will fix the domain name, such as with/without www.
Leave a blank line after each RewriteRule, and put a
before each ruleset (Rule plus any preceding Conditions). A group of closely related rulesets can share an explanation.
Step 5: Notes on error documents.
Reminder: ErrorDocument directives must not include a domain name, or else everything will turn into a 302 redirect. Start each one with a / representing the root.
Caution: Since each module is an island, any module that can issue a 403 must have its own error-document override. "Allow from all" in a <Files> envelope covers mod_authzzzz. If you have RewriteRules that end in [F], make sure your 403 documents can bypass these rules:
RewriteRule ^forbidden\.html - [L]
This rule must go before any rules with the [F] flag.
when there are Redirect and RewriteRule directives in the same scope, the RewriteRule directives will run first, regardless of the order of appearance in the configuration file.
Redirect and RewriteRule directives in the same scope
Some configuration directives are only available in the server configuration file. So if you are in a hosting situation where you only have .htaccess files to work with, you may need to resort to mod_rewrite.
Redirect permanent /about-xyz-word.html "https://www.example.com/c/1335/About-Us.html"
and it should be rewritten like this:
Rewrite rule ^/about-xyz-word.html /c/1335/About-Us.html [R=301,L]
Scroll up to the "htaccess cleanup" boilerplate and you'll find the section on converting mod_alias syntax to mod_rewrite syntax.
RewriteRule ^about-xyz-word\.html http://www.example.com/c/1335/About-Us.html [R=301,L]
In mod_rewrite, unlike mod_alias, patterns do not begin with a slash.
What this pattern is compared against varies depending on where the RewriteRule directive is defined.
The directory path where the rule is defined is stripped from the currently mapped filesystem path before comparison (up to and including a trailing slash). The net result of this per-directory prefix stripping is that rules in this context only match against the portion of the currently mapped filesystem path "below" where the rule is defined.
where the RewriteRule directive is defined