Installing Laravel in a domain subfolder can be useful in certain situations, although it is not officially supported by Laravel creators. In this instruction, I will describe how to configure Laravel 10 in a subfolder and additional tools such as Livewire v3.
Create a .htaccess
file in the main installation folder. In this file, rewrite all requests to the public
folder:
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
Update the .env
file by adding your folder name to the links. Additionally, create APP_DIR
with the folder name:
APP_DIR=subdir
APP_URL="http://localhost/${APP_DIR}"
ASSET_URL="${APP_URL}"
Add your subdirectory env variable to config/app.php
:
return [
//...
'dir' => env('APP_DIR'),
//...
];
It's a good idea to create a helper that will add a prefix to the paths. I did it in app/Helpers/RouteHelper.php
:
use Illuminate\Support\Str;
class RouteHelper
{
public static function getDirPathPrefix(?string $path = ''): string
{
$appDir = config('app.dir');
if (! $appDir) {
return $path;
}
if (Str::length($path) === 0) {
return $appDir;
}
if (Str::startsWith($path, '/')) {
$appDir = Str::start($appDir, '/');
}
return $appDir.Str::start($path, '/');
}
}
In the app/providers/RouteServiceProvider.php
file, modify the paths by adding prefixes:
$this->routes(function () {
Route::middleware('api')
+ ->prefix(RouteHelper::getDirPathPrefix('api'))
->group(base_path('routes/api.php'));
Route::middleware('web')
+ ->prefix(RouteHelper::getDirPathPrefix())
->group(base_path('routes/web.php'));
});
If you use the HOME
constant from RouteServiceProvider
in the code, change it to a static variable, and then update all occurrences of RouteServiceProvider::HOME
to RouteServiceProvider::$HOME
:
public static string $HOME = '/dashboard';
public function __construct($app)
{
self::$HOME = RouteHelper::getDirPathPrefix('dashboard');
parent::__construct($app);
}
Create a new file named web_custom.php
in the routes
folder:
use Illuminate\Support\Facades\Route;
use Livewire\Features\SupportFileUploads\FilePreviewController;
use Livewire\Features\SupportFileUploads\FileUploadController;
use Livewire\Livewire;
Livewire::setScriptRoute(fn ($handle) => Route::get('/livewire/livewire.js', $handle));
Livewire::setUpdateRoute(fn ($handle) => Route::post('/livewire/update', $handle));
Route::post('/livewire/upload-file', [FileUploadController::class, 'handle'])
->name('livewire.upload-file');
Route::get('/livewire/preview-file/{filename}', [FilePreviewController::class, 'handle'])
->name('livewire.preview-file');
In the routes/web.php
file, include the web_custom.php
file at the end of the file:
require __DIR__.'/web_custom.php';
In this section, the routes are re-declared, which allows Laravel to automatically prepend the subdirectory prefix set earlier in the RouteServiceProvider. This way, there's no need to use RouteHelper::getDirPathPrefix
in this section.
After configuration according to the documentation, the admin panel will return a 404. In the app/Providers/AdminPanelProvider.php
file, you need to change the path:
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path(RouteHelper::getDirPathPrefix('admin'))
//...
}
}
Hi, great work. Could you help me how to do it Laravel 11+. I followed the instructions in Laravel 11 to configure route: added the following in bootstrap/app.php
My web_livewire.php file:
This adds the routes in the
php artisan route:list
with the prefix that I have specified. But my routes are being duplicated for these livewire routes without the prefix. They seem to have the same name.Also, as you see filament exports route is also not being getting the prefix ``` bsds `` (my chosen prefix). My file uploads are failing in filament forms, this may be the cause, though it is not causing stack trace in log file. Any help would be great. Thanks in advance.