Search code examples
laravelapache.htaccessmod-rewrite

Laravel reverts to /public/ in URLs when trailing slashes are added


This is my .htaccess in the root directory that's supposed to get rid of "public" from URLs:

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

This is my .htaccess in the public directory that's supposed to get rid of trailing slashes:

<IfModule mod_rewrite.c>
    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]
</IfModule>

This is all well and good, except that when I enter a URL with a trailing slash, it redirect back to a URL with no trailing slash, but also with /public added.

For example, we have this route:

Route::get('/de', 'HomeController@index')->name('home');

Normally, the URL looks like domain.com/de.

But, if I type in domain.com/de/ into the browser, it redirects to domain.com/public/de instead of to domain.com/de - and the page loads as normal.

How do I fix this?


Solution

  • Your site root .htaccess should be like this:

    RewriteEngine On
    
    # remove trailing slash
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301,NE]
    
    # route all requests to public/
    RewriteRule ^(.*)$ public/$1 [L]
    

    Then inside public/.htaccess have this code:

    RewriteEngine On
    
    # if /public/ is part of original URL then remove it
    RewriteCond %{THE_REQUEST} /public/(\S*) [NC]
    RewriteRule ^ /%1 [L,NE,R=301]
    
    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    

    Make sure to completely clear your browser cache before testing this change.