40

Let's say I have the following:

Route::group(array('domain' => array('admin.example.com')), function()
{
    ...
});

Route::group(array('domain' => array('app.example.com')), function()
{
    ...
});

Route::group(array('domain' => array('dev.app.example.com')), function()
{
    ...
});

Is there any way to have multiple domains share a routing group? Something like:

Route::group(array('domain' => array('dev.app.example.com','app.example.com')), function()
{
    ...
});
Andy Fleming
  • 7,655
  • 6
  • 33
  • 53

9 Answers9

67

Laravel does not seem to support this.

I'm not sure why I didn't think of this sooner, but I guess one solution would be to just declare the routes in a separate function as pass it to both route groups.

Route::group(array('domain' => 'admin.example.com'), function()
{
    ...
});

$appRoutes = function() {
    Route::get('/',function(){
        ...
    }); 
};

Route::group(array('domain' => 'app.example.com'), $appRoutes);
Route::group(array('domain' => 'dev.app.example.com'), $appRoutes);

I'm not sure if there is any significant performance impact to this solution.

Andy Fleming
  • 7,655
  • 6
  • 33
  • 53
  • Thanks for this. I think there's no performance impact to this because you're just storing it in a array variable and just padding it to the 2 declaration. Cheers! – marknt15 Feb 22 '17 at 01:47
  • 1
    Would this really work with `php artisan route:cache`? https://laravel.com/docs/5.8/controllers#route-caching *"Closure based routes cannot be cached. To use route caching, you must convert any Closure routes to controller classes."* – Fredrik Apr 16 '19 at 21:51
  • 2
    I'm not sure @Fredrik, but that quote may be speaking to the actual route implementation and not the construction of the routes. In my example above, if `Route::get` referenced a controller method, it might be cacheable. – Andy Fleming Apr 17 '19 at 00:27
18

Laravel 5.1

 

Route::pattern('subdomain', '(dev.app|app)');
Route::group(['domain' => '{subdomain}.example.com'], function () {
  ...
});

 

Route::pattern('subdomain', '(dev.app|app)');
Route::pattern('domain', '(example.com|example.dev)');
Route::group(['domain' => '{subdomain}.{domain}'], function () {
  ...
});

Johnathan Douglas
  • 8,807
  • 2
  • 14
  • 7
  • 11
    This is a great tip. Be aware, though, that the domain parameter will be passed as the first parameter of any child routes: `Route::get('users/{id}', 'UsersController@show'); // id = "example.com";` To avoid this you can always use environment variables instead: `$domain = env('BASE_DOMAIN', 'example.com'); Route::group(['domain' => 'subdomain.'.$domain], function() { ... });` – Ed B Feb 27 '16 at 10:41
8

You can pass on the domain name as well:

Route::pattern('domain', '(domain1.develop|domain2.develop|domain.com)');
Route::group(['domain' => '{domain}'], function() {
    Route::get('/', function($domain) {
        return 'This is the page for ' . $domain . '!';
    });
});

Just in case you need to know with which domain name the controller is called. Tested it with Laravel 5.6.

Marty Staas
  • 401
  • 4
  • 8
4

Interested in this also! I'm trying to register a local development + production subdomain route, for the one controller action.

i.e.

# Local Dev
Route::group(array('domain' => "{subdomain}.app.dev"), function() {
    Route::get('/{id}', 'SomeController@getShow');
});

# Production Server
Route::group(array('domain' => "{subdomain}.app.com"), function() {
    Route::get('/{id}', 'SomeController@getShow');
});

I tried:

# Failed
Route::group(array('domain' => "{account}.app.{top_level_domain}"), function() {
    Route::get('/{id}', 'SomeController@getShow');
});

But it failed.

Not a huge issue, as DesignerGuy mentioned I can just pass in a function to both routes - but it would just be more elegant if they could be grouped :)

  • I am attempting to solve a similar problem. Namely, to have a "ui.domain.com" and an "api.domain.com" in production, yet allow my development team to have "ui.domain.local" and "api.domain.local" for their local development environments. Support for a wild card after the sub-domain would do the trick. The basic problem is that I am aiming to solve is to resolve conflicting routes. For example ui.domain.com/messages should return HTML and api.domain.com/messages should return JSON. So two groups with 'domain' => 'api.(:any)' and 'domain' => 'ui.(:any)' would be ideal – Adam Lenda Apr 22 '14 at 19:24
4

check in laravel docs, if you main domain is myapp, in production is myapp.com and in local environment is myapp.dev try using a *

Route::group(array('domain' => '{subdomain}.myapp.*'), 
function()
{
    ...
});
Marwelln
  • 28,492
  • 21
  • 93
  • 117
Bradley
  • 455
  • 5
  • 11
3

according to laravel document in laravel 5.4+ you can use this way:

Route::domain('{account}.myapp.com')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});
Winner1
  • 1,261
  • 2
  • 12
  • 17
2

A better answer found on Laravel discussion on the same topic is with macros. It works great for me. https://github.com/laravel/framework/issues/4017#issuecomment-267820459

Route::macro("domain", function(array $domains, \Closure $definition) {
    foreach ($domains as $domain) {
        Route::group(['domain' => $domain], $definition);
    }
});

Route::domain(['foo.bar.dev', 'foo.bar'], function($route) {
    // Do stuff
});
Dipu Raj
  • 1,784
  • 4
  • 29
  • 37
  • 2
    I added a comment to this link you provided with an improvement for named routes: https://github.com/laravel/framework/issues/4017#issuecomment-897936526 – sgtcoder Aug 12 '21 at 20:56
1

Currently you cannot. I had the same 'problem'; my fix is to cycle through your subdomains with a foreach and register the routes.

Rob Gordijn
  • 6,381
  • 1
  • 22
  • 29
0

see this link. http://laravel.com/docs/routing#sub-domain-routing

Route::group(array('domain' => '{subdomain}.example.com'), function()
{
    ...
});

or Use this package.

https://github.com/jasonlewis/enhanced-router

It help you can set where on group routing like this.

Route::group(array('domain' => '{maindomain}'), function()
{
    ...
})->where('maindomain', '.+\.example\.com$');
EThaiZone
  • 311
  • 1
  • 8
  • this not work Route::group(array('domain' => '{maindomain}'), function() { ... })->where('maindomain', '.+\.example\.com$'); – Ivan Dec 04 '16 at 16:17