When the same URI exists on both a 'global' domain and a subdomain, the 'global' one is used.
For example:
When I create an application with web routes: http://www.example.com and http://subdomain.example.com and only explicitly define the subdomain in the routes I get these routes: (php artisan route:list)
| Domain | URI | Action |
+-----------------------+-------+------------------------------------------------+
| | /home | App\Http\Controllers\HomeController@index |
| subdomain.example.com | /home | App\Http\Controllers\SubdomainController@index |
+-----------------------+-------+------------------------------------------------+
Then if I visit subdomain.example.com I will get the result of the HomeController index method and NOT the SubdomainController index method.
When I register the 'global' domain also, I do get the result of the SubdomainController index method:
| Domain | URI | Action |
+-----------------------+-------+------------------------------------------------+
| www.example.com | /home | App\Http\Controllers\HomeController@index |
| subdomain.example.com | /home | App\Http\Controllers\SubdomainController@index |
+-----------------------+-------+------------------------------------------------+
So the issue here is that when I visit the subdomain route, it should have a higher priority than the 'global' (empty) domain.
Hey @hansvn,
If you wish to give it higher priority without explicitly defining the www domain, all you need to do is place the sub domain above the "global" routes. Personally I find it more organized to explicitly define all domains, makes a lot more sense when digging through a potentially big file like that.
Ex.
Route::group([
'domain' => 'www.'.env('SESSION_DOMAIN'),
], function () {
Route::get('/', 'HomeController@index');
});
Route::group([
'domain' => 'subdomain.'.env('SESSION_DOMAIN'),
], function () {
Route::get('/', 'SubdomainController@index');
});
@hansvn yes the order of routes definition makes a difference.
I like how @craigpaul solves the problem, it makes your routes file looks very organised as well.
@craigpaul What if you have multipe domains serving the same application?
Example:
www.example.com, example.com, www.example2.com and example2.com serve one set of the same routes and sudomain.example.com serves an other
| Domain | URI | Action |
+-----------------------------------------------------------+-------+------------------------------------------------+
| www.example.com || www.example2.com || example.com || ... | /home | App\Http\Controllers\HomeController@index |
| subdomain.example.com | /home | App\Http\Controllers\SubdomainController@index |
+-----------------------------------------------------------+-------+------------------------------------------------+
@hansvn So one thing you could do is use the dynamic domain routing. It is essentially the same as route parameters.
Route::group([
'domain' => '{domain}.com',
], function () {
Route::get('/', 'HomeController@index');
});
So that would allow you to group all those routes together. In your controller you would have the following passed in on every route now.
public function index(string $domain)
{
dd($domain); // Domain would be equal to exactly what your domain is above in {domain}.
}
Using the above domain grouping, you would probably want to utilize pattern matching to restrict it to your exact domains though. You have to provide the name of your pattern, then any regex you would like to match against.
Route::pattern('domain', '[a-z0-9]+');
@craigpaul
I tried your suggestion for the dynamic domains and though it works for the subdomain routes, on the non-subdomain routes I get a 404 on every page.
1/1 NotFoundHttpException in compiled.php line 8882:
in compiled.php line 8882
at RouteCollection->match(object(Request)) in compiled.php line 8206
at Router->findRoute(object(Request)) in compiled.php line 8134
at Router->dispatchToRoute(object(Request)) in compiled.php line 8130
at Router->dispatch(object(Request)) in compiled.php line 2472
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request)) in Pipeline.php line 53
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in compiled.php line 3213
at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in compiled.php line 9870
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in compiled.php line 9855
at Pipeline->then(object(Closure)) in compiled.php line 2416
at Kernel->sendRequestThroughRouter(object(Request)) in compiled.php line 2400
at Kernel->handle(object(Request)) in index.php line 53
@hansvn could you post your routes file and your server block / virtual host configs for the domains your trying to point to this code base.
@craigpaul
The subdomain serves as an api in this specific config:
The route service provider:
//RouteServiceProvider.php
protected function mapWebRoutes()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
'domain' => '{domain}.com'
], function ($router) {
require base_path('routes/web.php');
});
}
protected function mapApiRoutes()
{
Route::group([
'middleware' => 'api',
'namespace' => 'API_NAMESPACE',
'domain' => 'subdomain.example.com',
'as' => 'api.'
], function ($router) {
require base_path('routes/api.php');
});
}
There routes:
//web.php
Route::auth();
Route::group(['middleware' => ['auth', 'auth.admin']], function() {
Route::resource('user', 'UserController');
Route::get('dashboard', ['uses' => 'DashboardController@showDashboard']);
...
});
//api.php
Route::resource('user', 'User\UserController', ['only' => ['index', 'store']]);
...
and the nginx server config:
server {
server_name example.com example2.com;
root /home/forge/example.com/public;
...
}
server {
server_name subdomain.example.com;
root /home/forge/example.com/public;
...
}
@hansvn can you share how you solved it?
@pplanel I didn't solve it using laravel, there is no fix that I know of yet.
I solved it using nginx redirects first, so the example2.com domain redirects back to example.com.
Not what wI intended to achieve, but it provides a fallback...
Most helpful comment
Hey @hansvn,
If you wish to give it higher priority without explicitly defining the
wwwdomain, all you need to do is place the sub domain above the "global" routes. Personally I find it more organized to explicitly define all domains, makes a lot more sense when digging through a potentially big file like that.Ex.