dcdeiv dcdeiv - 27 days ago 9x
Apache Configuration Question

Redirect subfolder to root and hide it in the url

I have managed to "rebase" the root from a directory in order to keep public files separated from configs, helpers, and controllers, thanks to this answer and this answer.

However I realized that if a user type

it will not redirect to
this is harmful for SEO because robots will treat them as two urls thus duplicate.

I need to 301 redirect
to root but as long as I am trying. It doesn't work.

My htaccess looks like the following:

# Options
Options +FollowSymLinks +MultiViews -Indexes
DirectorySlash off

# Enable Rewrite Engine
RewriteEngine on
RewriteBase /

# Exceptions
RewriteCond %{REQUEST_URI} ^/(images|javascripts|stylesheets)/ [NC]
RewriteRule ^ - [L]

# www to non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301]

# Make /public like it was root
RewriteCond %{THE_REQUEST} /public/([^\s]+) [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_URI} !^/public
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]

# Error pages
ErrorDocument 403 /errors/403.php
ErrorDocument 404 /errors/404.php
ErrorDocument 500 /errors/500.php

<files .htaccess="">
order allow,deny
deny from all

In this way it will redirect to

How can I fix this issue?


My website directory structure is:


In root there won't be any index.php pages. So I need to make the
dir as it was my root, in order to keep configs and other directories that users don't have to see separate.


Replace your 2 public/ related rules to this:

# add a trailing slash if public/$1 is a directory
RewriteCond %{DOCUMENT_ROOT}/public/$1 -d
RewriteRule ^(.*?[^/])$ %{REQUEST_URI}/ [L,R=301,NE]

# Make /public like it was root
RewriteCond %{THE_REQUEST} \s/+public/(\S*)\s [NC]
RewriteRule ^ /%1 [L,R=301,NE]

# internally add public/ to URIs
RewriteRule ^(?!public/).*$ public/$0 [L,NC]

Without first trailing slash add rule if you use a URL for sub-directory e.g. http://domain.com/subfolder then after 3rd rule adding public/ in the URI it internally becomes http://domain.com/public/subfolder which is a valid directory and Apache's mod_dir module adds a trailing slash in the end doing a 301 redirect to http://domain.com/public/subfolder/ and this will expose public/ part to your clients.

When first trailing slash is there we check if destination is directory and add a trailing slash in original non-/puclic/ URL itself.