Reputation: 585
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteRule ^$ /subdir/ [L,NC]
I want to rewrite the root domain to subfolder without changing the URL in the browser. The above code works just for the root domain but not any folders and files.
For example, I have https://example.com/
and https://example.com/subdir/
.
With the above code in .htaccess
file, when I go to https://example.com/
I see the contents of https://example.com/subdir/
which is good.
But when I go to https://example.com/test.txt
I should see https://example.com/subdir/test.txt
but I get The requested URL was not found on this server.
Same happens when I go to https://example.com/abc
expecting to see contents of https://example.com/subdir/abc
Any idea?
Upvotes: 1
Views: 1314
Reputation: 45829
RewriteRule ^$ /subdir/ [L,NC]
Change this to read:
RewriteRule !^subdir/ subdir%{REQUEST_URI} [L]
Any request that does not start /subdir/
is internally rewritten to /subdir/<url>
. The REQUEST_URI
server variable contains the full URL-path (including the slash prefix).
I removed the slash prefix from the substitution string since you have defined a RewriteBase /
. (Although neither are strictly necessary here.)
UPDATE:
...when I go to
example.com/s
I am being redirected toexample.com/subdir/s/
s
is a subfolder withinsubdir
, does that make any difference?
Ah yes, if /s
is a subdirectory then mod_dir will append the trailing slash (to "fix" the URL) with an external 301 redirect. This redirect occurs after the URL has been rewritten to /subdir/s
- thus exposing the /subdir
subdirectory.
To handle this situation we can add another rule (a redirect) before the existing rewrite that first checks whether the request would map to a directory within the /subdir
subdirectory and append a slash if it is omitted (before mod_dir would append the slash to the rewritten URL).
For example:
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/subdir%{REQUEST_URI} -d
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}/ [R=301,L]
This states... for any request that:
!\.\w{2,4}$
- does not contain (what looks like) a file extension of between 2 and 4 characters (assuming your directories aren't named this way)!/$
- and does not currently end in a slash.-d
- and exists as a physical directory in the /subdir
subdirectory.Whilst this probably should be a 301 (permanent) redirect, you should first test with a 302 (temporary) redirect to avoid potential caching issues.
You will need to clear your browser cache before testing, since the erroneous 301 redirect from /s
to /subdir/s/
will have been cached by the browser.
A potential optimisation is to remove the filesystem check and simply assume that any request that does not contain a file extension should map to a directory. (But this depends on whether you are handling these URLs in any other way.)
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
# If the requested URL exists as a directory in "/subdir" then append a slash
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/subdir%{REQUEST_URI} -d
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}/ [R=301,L]
# Rewrite everything to "/subdir"
RewriteRule !^subdir/ subdir%{REQUEST_URI} [L]
Upvotes: 1