I created the ultimate .htaccess for Laravel.
The greatest ever written. A dazzling masterpiece of server configuration.
All right, perhaps that is a slight exaggeration.
What it actually does is solve a couple of common Laravel hosting problems in a simple and practical way, which is still fairly impressive for such a small file.
Let’s take a look.
The URL Problem
In a standard Laravel installation, the application is served through the public/ directory.
Depending on how your hosting environment is configured, you may end up with a URL like this:
Instead of the cleaner version:
The first one works, of course, but the extra public/ is not exactly helping the URL win any beauty contests.
The Security Problem
There is also a more important concern.
If you upload the entire Laravel project directly into a publicly accessible directory without configuring the web server correctly, files outside public/ may become accessible through the web.
That is something you definitely want to avoid.
Ideally, the server’s document root should point directly to Laravel’s public/ directory. This keeps configuration files, application code, dependencies and other sensitive project files outside the publicly accessible area.
However, some shared-hosting environments do not allow you to change the document root.
That is where our heroic little .htaccess enters the story.
Laravel also uses another public directory:
storage/app/public/
Here is the difference between the two:
| Directory | Usage |
|---|---|
public/ |
Contains static public files, including assets added during development. |
storage/app/public/ |
Contains dynamic public files created or uploaded through the application. |
The Ultimate .htaccess Solution
The following configuration routes public requests through the appropriate Laravel directories while keeping the rest of the project out of sight.
In other words, visitors see the files they need, not your entire application structure.
Everybody wins.
Is it truly the ultimate .htaccess?
That is for history to decide.
For now, it does the job rather nicely.
1. Place this .htaccess file in the project’s root directory /:
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -d
RewriteRule ^ %{REQUEST_URI}/ [R=301, L]
RewriteCond %{REQUEST_URI} !^/storage/app/public/
RewriteCond %{DOCUMENT_ROOT}/storage/app/public%{REQUEST_URI} -f
RewriteRule ^ /storage/app/public%{REQUEST_URI} [QSA, L]
RewriteCond %{REQUEST_URI} !^/(public|storage/app/public)/
RewriteRule ^ /public%{REQUEST_URI} [QSA, L]
2. Place this .htaccess file inside the storage/app/public/ directory:
storage/app/public/.htaccess
allow from all
That’s It
The publicly accessible directories are now:
public/storage/app/public/
Their files can be accessed as though they were located directly in the root /, while the rest of the Laravel project remains hidden.
As a bonus, the slightly awkward public/ disappears from the URL.
Much cleaner.
The ultimate .htaccess has completed its mission.
One Last Note
When testing the configuration, clear any relevant browser, proxy, CDN or server caches. Otherwise, older cached responses may make it seem as though the new .htaccess rules have not been applied.
You should also verify that sensitive files cannot be accessed directly after enabling the configuration.
Trust is good. Testing is better.