I have the following directory structure:
/html
.git
project-folder
build
index.html
.htaccess
The apache server see the directory /html
as a root folder for the domain https://example.com
.
What should I put to .htaccess
to be able to see index.html
as a root index for the domain https://example.com
?
Could DirectoryIndex help? If so, how to write the RewriteRule
and RewriteCond
then?
Could DirectoryIndex help?
Not really, that would only help with requests to the root directory itself and not /<something>
. This should be left as the default, in order to serve index.html
from the requested directory (including /html/project-folder/build
). For example:
DirectoryIndex index.html
I'm assuming you don't need to access anything outside of the /build
subdirectory publicly. I'm also assuming you are on Apache 2.4 (as opposed to Apache 2.2).
Here are two methods, depending on whether you will have one or two .htaccess
files. The second being in the /build
subdirectory.
.htaccess
file in the document rootIn the root .htaccess
file (at /html/.htaccess
) you can internally rewrite any internal requests that are not already for the /project-folder/build
subdirectory to that subdirectory.
Any external requests for /project-folder/build
need to be externally redirected back to the root (or blocked altogether).
For example:
# Single .htaccess file in document root at /html/.htaccess
DirectoryIndex index.html
RewriteEngine On
# Redirect any direct requests to the subdirectory back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^project-folder/build/(.*) /$1 [R=301,L]
# Internally rewrite all requests to the subdirectory
RewriteRule (.*) project-folder/build/$1 [END]
The use of the REDIRECT_STATUS
environment variable in the RewriteCond
directive ensures we are only checking direct (external) requests and not internal rewrites (by other rules). Although, in this limited example, the use of the END
flag on the second rule makes this check redundant.
.htaccess
files (one in document root and one in project subdirectory)This is required if the project (directory) has its own .htaccess
file that also contains mod_rewrite directives.
In this scenario, the external redirect back to root would need to be in the project folder's .htaccess
file (not in the root .htaccess
file), this is because mod_rewrite directives are not inherited (by default).
For example:
# /html/.htaccess (in the document root)
DirectoryIndex index.html
RewriteEngine On
# Internally rewrite all requests to the subdirectory
RewriteRule (.*) project-folder/build/$1 [L]
In this case, it doesn't matter whether L
or END
is used on the above rule.
# /html/project-folder/build/.htaccess
RewriteEngine On
# Redirect any direct requests to this subdirectory back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L]
At a casual glance, the above redirect might look like it's redirecting back to itself, but note that the captured URL-path (from the RewriteRule
pattern) is relative to the directory that contains the .htaccess
file. So, a request for /project-folder/build/<something>
is redirected back to /<something>
in the "root".
Always test first with 302 (temporary) redirects first to avoid potential caching issues.