I'm using the micro framework Silex on my website hosted on a VPS.
So, the site files are in the /site_name/public_html/ folder but, with Silex, the site must point to the /site_name/public_html/web/ folder.
In the public_html directory, I have the following .htaccess file :
Options -Indexes -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Redirect to https & www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,NE]
# Redirect incoming URLs to web folder
RewriteCond %{REQUEST_URI} !web/
RewriteRule (.*) /web/$1 [L]
</IfModule>
And, in the /public_html/web/ folder, the following .htaccess :
<IfModule mod_rewrite.c>
# Redirect incoming URLs to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
Now, everything works fine but my pages are accessible with three different patterns :
example.com/page/(the one I want to keep)example.com/web/page/example.com/web/index.php/page/
I have used the meta canonical to avoid duplicate content but I still want these last two options to not exist.
I guess I have something to change in both .htaccess files but I can't find what it is.
I would actually remove the
.htaccessfile in the/websubdirectory altogether and rewrite directly to/web/index.phpin the root.htaccessfile. By having two.htaccessfiles you are seemingly creating extra work. The mod_rewrite directives in the subdirectory will completely override the parent directives (by default), so your canonical HTTPS and www redirects are also being overridden.(Presumably you had a
RewriteEngine Ondirective in the/web/.htaccessfile?)Having removed the
/web/.htaccessfile, try something like the following in your root.htaccessfile:The check against the
REDIRECT_STATUSenvironment variable ensures we only test initial requests and not requests that have been later rewritten.The
<IfModule>wrapper is not required, unless your site is intended to work without mod_rewrite.Note that a request like
/web/index.php/page/would result in two redirects. First to/index.php/pagethen to/page. Since this is an edge case I would consider a double redirect to be acceptable.UPDATE: I've removed the "directory" check in the above as this would have prevented the document root (
example.com/) from being rewritten to the/websubdirectory. This would have consequently resulted in a 403 if you didn't have a directory index document (eg.index.php) in the document root of your site. (However, requests forexample.com/page/should have still worked OK.)Test with 302 (temporary) redirects and only change to 301 (permanent) when you are sure it's working OK - to avoid any caching issues in the browser. Be sure to clear the browser cache before testing.