Teymur
Teymur

Reputation: 121

Laravel 5, Sub-Domain routing, with optional parameter

I’ve just started learning Laravel 5 and trying to create multilanguage web site and want to use different domains for the language so en.example.app points to English version, es.example.app to Spanish and so on. I use route groups and below is my code.

Route::group(['domain' => '{domain}.example.app'], function() {
    Route::get('/', function () {
        return view('index');
    });
    Route::get('test', function(){
        return view('index');
    });
});

It works fine for all domains except example.app. Unfortunately optional parameters {domain?} doesn’t work for subdomains, and I don’t want to duplicate routes like this.

Route::get('/', function () {
    return view('index');
});
Route::get('test', function(){
    return view('index');
});

Route::group(['domain' => '{domain}.example.app'], function() {
    Route::get('/', function () {
        return view('index');
    });
    Route::get('test', function(){
        return view('index');
    });
});

Could somebody please advise how to avoid this duplication?

Upvotes: 12

Views: 4772

Answers (5)

tapos ghosh
tapos ghosh

Reputation: 2202

Route::group(['domain' => '{domain}.example.app'], function() {

}); 

Route::group(['domain' => 'example.app'], function() {

}); 

this pattern is good but if you want to use different language add localization file

Upvotes: 1

J. Davis
J. Davis

Reputation: 49

You could create a file named app-routes.php which contains all your routes and then in your actual routes.php file

Route::group(['domain' => '{domain}.example.app'], function() {
    include('app-routes.php');
}); 

Route::group(['domain' => 'example.app'], function() {
    include('app-routes.php');
}); 

Upvotes: 4

Sougata Bose
Sougata Bose

Reputation: 31749

A MiddleWare helped me.

Route::group(array('middleware' => 'resolve_domain'), function () {
    Route::get('/', 'WhitePapersController@getHomepage');
});

And in MiddleWare -

public function handle($request, Closure $next)
{
    $params = explode('.', $request->getHost());
    $sub_domains = config('admin_configs.editions'); // Predefined sub-domain
    $edition = false;
    if(!empty($params[0]) && in_array($params[0], $sub_domains, true))  {
        $edition = $params[0];
    }
    define('DOMAIN_EDITION', $edition); // Set constant to be used.

    return $next($request);
}

Upvotes: 3

Qevo
Qevo

Reputation: 2371

Your options are either the route duplication or a server level redirect for HTTP requests without a subdomain.

The simple option is to just forward example.app to www.example.app.

Upvotes: 2

Kapil Garg
Kapil Garg

Reputation: 477

Thats becuase the {domain}.example.app requires a . before example.app.

You can remove the . and add contraint for domain parameter for it to have atmost 1 .

So the code will look like

Route::group(['domain' => '{domain}example.app'], function($group) {
    Route::get('/', function ($domain) {
        //code
    }) ;
    // more routes

    foreach($group->getRoutes() as $route){
        $route->where('domain', '[a-z]+\.{0,1}');
    }

});

P.S. : I don't know whether my regex is correct or not.

Upvotes: 5

Related Questions