Serving Laravel from a subdirectory

An image so medium doesn’t show some stock photo on previews.
An image so medium doesn’t show some stock photo on previews.

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:

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store