# /.htaccess
RewriteEngine on
RewriteBase /
RewriteRule "^([^/]+)/root/(.*)" "$1/index.php?root=$2"
# /folder/.htaccess
RewriteRule "^sub/(.*)" "index.php?sub=$1"
Each folder’s RewriteRule
works in isolation:
/folder/root/hi => /folder/index.php?root=hi
/folder/sub/hello => /folder/index.php?sub=hello
Q: Why does adding any RewriteRule
in the subfolder (/folder/.htacces
) break the one in the web root (causes 404)? What do I need to do to create rules on different levels?
I’ve tried adding RewriteOptions Inherit(Down)
, but that didn’t have any effect.
3
Answers
Assuming you have
RewriteEngine On
in the/folder/.htaccess
then the mod_rewrite directives in the parent config will be completely overridden, since mod_rewrite directives don’t inherit by default.However, even if you enable mod_rewrite inheritance, the directives still won’t work, because mod_rewrite inheritance “virtually copies” the directives “in-place”, as if the directives are in the same config file – in the same scope (with the same directory-prefix).
So, with
RewriteOptions Inherit
in the/folder/.htaccess
file, the directives are effectively processed like this:The pattern
"^([^/]+)/root/(.*)"
simply won’t match if used in the scope of the/folder/.htaccess
file – which is what’s happening when using mod_rewrite inheritance.IF the
/.htaccess
(root) directives are always inherited then you could modify the root directive to read something like the following (removing the parent directory from the rule):(Yes, it matches the directive already in the
/folder/.htaccess
file.)However, the “problem” now is that directive probably won’t work if not inherited as in your example. IF you specifically need it to work in both scenarios: when inherited from a subdirectory
.htaccess
file and directly from the document-root, then modify the directive to make the parent folder optional. For example:You may still need to fix the
RewriteBase
directive, or remove it altogether.mod_rewrite inheritance is not as useful as it at first appears. Directives – that are expected to be inherited – generally need to be specifically written to allow for this.
You need to change your root .htaccess rule to this:
This is to make initial part
[^/]+/
an optional match in order to make same rule work from root .htaccess as well as from a/folder/.htaccess
.Then have this in your
folder/.htaccess
:RewriteOptions Inherit
will inherit all rules and directives from parent .htaccess and will apply them in child’s context after applying all the rules defined in child .htaccess.With Apache 2.4, I’ve success by adding
RewriteOptions InheritDownBefore
in the parent.htaccess
.