I have seen this in a few .htaccess
examples
RewriteBase /
It appears to be somewhat similar in functionality to the <base href="">
of HTML.
I believe it may automatically prepend its value to the beginning of RewriteRule
statements (possibly ones without a leading slash)?
I could not get it to work properly. I think it's use could come in very handy for site portability, as I often have a development server which is different to a production one. My current method leaves me deleting portions out of my RewriteRule
statements.
Can anyone explain to me briefly how to implement it?
Thanks
The clearest explanation I found was not in the current 2.4 apache docs, but in version 2.0.
How does it work? For you apache hackers, this 2.0 doc goes on to give "detailed information about the internal processing steps."
Lesson learned: While we need to be familiar with "current," gems can be found in the annals.
AFAIK, RewriteBase is only used to fix cases where mod_rewrite is running in a
.htaccess
file not at the root of a site and it guesses the wrong web path (as opposed to filesystem path) for the folder it is running in. So if you have a RewriteRule in a .htaccess in a folder that maps tohttp://example.com/myfolder
you can use:If mod_rewrite isn't working correctly.
Trying to use it to achieve something unusual, rather than to fix this problem sounds like a recipe to getting very confused.
When I develop, it's on a different domain within a folder. When I take a site live, that folder doesn't exist anymore. Using RewriteBase allows me to use the same .htaccess file in both environments.
When live:
When developing:
I believe this excerpt from the Apache documentation, complements well the previous answers :
This command can explicitly set the base URL for your rewrites. If you wish to start in the root of your domain, you would include the following line before your RewriteRule:
RewriteBase
is only applied to the target of a relative rewrite rule.Using RewriteBase like this...
is essentially the same as...
But when the .htaccess file is inside
/folder/
then this also points to the same target:Although the docs imply always using a
RewriteBase
, Apache usually detects it correctly for paths under the DocumentRoot unless:You are using
Alias
directivesYou are using .htaccess rewrite rules to perform HTTP redirects (rather than just silent rewriting) to relative URLs
In these cases, you may find that you need to specify the RewriteBase.
However, since it's a confusing directive, it's generally better to simply specify absolute (aka 'root relative') URIs in your rewrite targets. Other developers reading your rules will grasp these more easily.
Quoting from Jon Lin's excellent in-depth answer here:
In an htaccess file, mod_rewrite works similar to a
<Directory>
or<Location>
container. and theRewriteBase
is used to provide a relative path base.For example, say you have this folder structure:
So you can access:
http://example.com/
(root)http://example.com/subdir1
(subdir1)http://example.com/subdir2
(subdir2)http://example.com/subdir2/subsubdir
(subsubdir)The URI that gets sent through a
RewriteRule
is relative to the directory containing the htaccess file. So if you have:/a/b/c/d
, then the captured URI ($1
) isa/b/c/d
.subdir2
and the request is/subdir2/e/f/g
then the captured URI ise/f/g
.subsubdir
, and the request is/subdir2/subsubdir/x/y/z
, then the captured URI isx/y/z
.The directory that the rule is in has that part stripped off of the URI. The rewrite base has no affect on this, this is simply how per-directory works.
What the rewrite base does do, is provide a URL-path base (not a file-path base) for any relative paths in the rule's target. So say you have this rule:
The
bar.php
is a relative path, as opposed to:where the
/bar.php
is an absolute path. The absolute path will always be the "root" (in the directory structure above). That means that regardless of whether the rule is in the "root", "subdir1", "subsubdir", etc. the/bar.php
path always maps tohttp://example.com/bar.php
.But the other rule, with the relative path, it's based on the directory that the rule is in. So if
is in the "root" and you go to
http://example.com/foo
, you get servedhttp://example.com/bar.php
. But if that rule is in the "subdir1" directory, and you go tohttp://example.com/subdir1/foo
, you get servedhttp://example.com/subdir1/bar.php
. etc. This sometimes works and sometimes doesn't, as the documentation says, it's supposed to be required for relative paths, but most of the time it seems to work. Except when you are redirecting (using theR
flag, or implicitly because you havehttp://host
in your rule's target). That means this rule:if it's in the "subdir2" directory, and you go to
http://example.com/subdir2/foo
, mod_rewrite will mistake the relative path as a file-path instead of a URL-path and because of theR
flag, you'll end up getting redirected to something like:http://example.com/var/www/localhost/htdocs/subdir1
. Which is obviously not what you want.This is where
RewriteBase
comes in. The directive tells mod_rewrite what to append to the beginning of every relative path. So if I have:in "subsubdir", going to
http://example.com/subdir2/subsubdir/foo
will actually serve mehttp://example.com/blah/bar.php
. The "bar.php" is added to the end of the base. In practice, this example is usually not what you want, because you can't have multiple bases in the same directory container or htaccess file.In most cases, it's used like this:
where those rules would be in the "subdir1" directory and
would be in the "subsubdir" directory.
This partly allows you to make your rules portable, so you can drop them in any directory and only need to change the base instead of a bunch of rules. For example if you had:
such that going to
http://example.com/subdir1/foo
will servehttp://example.com/subdir1/bar.php
etc. And say you decided to move all of those files and rules to the "subsubdir" directory. Instead of changing every instance of/subdir1/
to/subdir2/subsubdir/
, you could have just had a base:And then when you needed to move those files and the rules to another directory, just change the base:
and that's it.