Laravel 11 中应直接使用 Route::domain() 链式调用 middleware、prefix、namespace、name 等方法,避免在其内部嵌套 Route::group();通配符子域名需用 {sub} + where() 限定,并将主域名路由置于最后以确保正确匹配。

在 Laravel 11 中,`Route::domain()` 和 `Route::group()` 可以配合使用,但要注意:`Route::domain()` 本身就是一个**顶层路由分组机制**,它内部已隐含一个闭包作用域,因此通常**不需要、也不建议再套一层 `Route::group()`** —— 否则容易导致配置冗余、语义混乱或意外覆盖(比如 `prefix` 或 `middleware` 被重复应用)。
直接用 domain() 包裹路由定义(推荐)
这是最清晰、最符合 Laravel 11 惯例的写法。`Route::domain()` 已支持链式调用中间件、前缀、命名空间等,和 `Route::group()` 功能一致:
- 为子域名统一加中间件:
Route::domain('shop.example.com')->middleware(['web', 'verified'])->group(...) - 添加路径前缀:
->prefix('products') - 指定控制器命名空间:
->namespace('Shop') - 设置路由名前缀:
->name('shop.')
示例:
routes/web.phpRoute::domain('shop.example.com')
->middleware(['web', 'verified'])
->namespace('Shop')
->name('shop.')
->group(function () {
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('/items/{id}', [ItemController::class, 'show'])->name('item.show');
});
<p>Route::domain('blog.example.com')
->middleware(['web'])
->name('blog.')
->group(function () {
Route::get('/', [BlogController::class, 'index'])->name('home');
Route::get('/post/{slug}', [PostController::class, 'show'])->name('post.show');
});
</p>
不推荐:在 domain() 内部再嵌套 group()
以下写法语法上可行,但无实际增益,反而增加理解成本和出错风险:
Route::domain('api.example.com')->group(function () {
Route::group(['middleware' => 'api'], function () { // ❌ 多余嵌套
Route::get('/users', [UserController::class, 'index']);
});
});
应简化为:
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
Route::domain('api.example.com')
->middleware('api') // ✅ 直接链式调用
->group(function () {
Route::get('/users', [UserController::class, 'index']);
});
需要通配符子域名时,用 {sub} + where 约束
若要支持动态子域名(如 us.shop.example.com、eu.shop.example.com),用参数化 domain 并配合 `where()` 限定合法值:
Route::domain('{sub}.example.com')
->where('sub', 'shop|blog|admin')
->middleware('web')
->group(function () {
Route::get('/', function (Request $request) {
return "Subdomain: " . $request->route('sub');
});
});
注意:通配符路由必须放在**明确域名路由之后、主域名 fallback 之前**,否则会提前匹配,导致其他子域名被拦截。
主域名作为 fallback,必须放最后
Laravel 按定义顺序匹配路由。所有 `Route::domain()` 必须排在无域名约束的路由之前,否则主域名路由会“兜底”捕获所有请求,使子域名失效:
// ✅ 正确顺序
Route::domain('shop.example.com')->group(...);
Route::domain('blog.example.com')->group(...);
<p>// 主域名(无 domain 约束)放最后
Route::middleware('web')->group(function () {
Route::get('/', function () { return view('welcome'); });
});
</p>










