Routes
This package has a concept of central routes and tenant routes. Central routes are only available on central domains, and tenant routes are only available on tenant domains. If you don't use domain identification, then all routes are always available and you may skip the details about preventing access from other domains.
Central routes
You may register central routes in routes/web.php
or routes/api.php
like you're used to. However, you need to make one small change to your RouteServiceProvider.
Note: Since Laravel 11, there isn't a
RouteServiceProvider
, so you can instead wrap your central routes in aRoute::domain(...)->group(...)
call. See the quickstart guide for an example.
You don't want central routes — think landing pages and sign up forms — to be accessible on tenant domains. For that reason, register them in such a way that they're only accessible on your central domains:
// RouteServiceProvider
protected function mapWebRoutes()
{
foreach ($this->centralDomains() as $domain) {
Route::middleware('web')
->domain($domain)
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
}
protected function mapApiRoutes()
{
foreach ($this->centralDomains() as $domain) {
Route::prefix('api')
->domain($domain)
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
protected function centralDomains(): array
{
return config('tenancy.central_domains', []);
}
Note: If you're using multiple central domains, you can't use route names, because different routes (= different combinations of domains & paths) can't share the same name. If you need to use a different central domain for testing, use config()->set()
in your TestCase setUp()
.
Tenant routes
You may register tenant routes in routes/tenant.php
. These routes have no middleware applied on them, and their controller namespace is specified in app/Providers/TenancyServiceProvider
.
By default, you will see the following setup:
Route::middleware([
'web',
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class,
])->group(function () {
Route::get('/', function () {
return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id');
});
});
Routes within this group will have the web
middleware group, an initialization middleware, and finally, a middleware related to the section below applied on them.
You may do the same for the api
route group, for instance.
Also, you may use different initialization middleware than the domain one. For a full list, see the Tenant identification page.
Conflicting paths
Due to the order in which the service providers (and as such, their routes) are registered, tenant routes will take precedence over central routes. So if you have a /
route in your routes/web.php
file but also routes/tenant.php
, the tenant route will be used on tenant domains.
However, tenant routes that don't have their central counterpart will still be accessible on central domains and will result in a "Tenant could not be identified on domain ..." error. To avoid this, use the Stancl\Tenancy\Middleware\PreventAccessFromCentralDomains
middleware on all of your tenant routes. This middleware will abort with a 404 if the user is trying to visit a tenant route on a central domain.
Universal routes
See the Universal Routes feature.