Oficially Laravel can not be served from a subdirectory. In practice it’s just a matter of proper setup.
I was browsing the issues on Laravel repo and came across one complaining about issues that arise from serving Laravel out of a subdirectory. Turns out there are multiple such reports and the official answer is just that it’s not supported. Even the documentation states:
Laravel should always be served out of the root of the “web directory” configured for your web server.
In fact there are no problems with serving it from a subdirectory as long as you take some care to set up the server and Laravel properly.
The key idea is that you should not hide your setup from Laravel. Don’t put Laravel in an actual subfolder, serve from example.com/subdirectory/public
and expect Laravel to treat that as a base. You should instead redirect example.com/subdirectory
to your Laravel app, provide Laravel with the full URI (including /subdirectory
) and configure it to handle requests that start with that prefix.
At that point it’s no different for Laravel than serving it from root but only receiving and handling requests with prefixed routes. But the difference for you is that you can serve something else without the prefix. Here are some examples for common setups.
Admin panel in a subdirectory
Let us consider the following setup. You have a Linux server with Nginx. You are willing to serve a SPA frontend from/srv/frontend
onexample.com
and a Laravel administration panel from/srv/admin
on example.com/admin
.
Server configuration
You should instruct Nginx to serve any requests to example.com/admin
to the Laravel app:
server {
listen 443 ssl http2;
# do your tls setup, gzip, logging etc server_name example.com; index index.html;
root /srv/frontend; location /admin {
alias /srv/admin/public;
index index.php; try_files $uri /index.php?$query_string;
} location ~ \.php$ {
# do your PHP setup
}
}
Important detail to note is the alias
directive. It means that Nginx will serve example.com/admin
from /srv/admin/public
. If we used root
instead, Nginx would append the URI to it and try to serve from /srv/admin/public/admin
.
Note: you should not have any directory starting with the string public…
(apart from public
dir itself) like public_enemy
in your Laravel directory, otherwise it will be served on example.com/admin_enemy
. If you do have something like that, see this answer on SF.
Laravel configuration
In your routes/web.php
wrap everything in a prefix group so Laravel handles the /admin
routes:
Route::prefix('admin')->group(function () {
// Your routes here
});
SPA with an API in subdirectory
You have a Linux server with Nginx. You are willing to serve a SPA frontend from/srv/frontend
onexample.com
and a Laravel API from/srv/api
on example.com/api
.
Nginx configuration
server {
listen 443 ssl http2;
# do your tls setup, gzip, logging etc server_name example.com; index index.html;
root /srv/frontend; location /api {
alias /srv/api/public;
index index.php; try_files $uri /index.php?$query_string;
} location ~ \.php$ {
# do your PHP setup
}
}
And you are done. No need for any Laravel setup because the routes in routes/api.php
have an api
prefix by default. If you still need assets, replace that root
with an alias
.
Still here?
Check out some of my silly projects on Laravel and Nginx: