平行路由
2026年9月6日
平行路由让同一份 layout.tsx 同时挂多块独立页面,有点像多个出口。后台里左边团队、右边分析、中间主内容,就是典型场景。文件夹名以 @ 开头,不会出现在 URL 里。
基本用法
app/
├── layout.tsx
├── page.tsx
├── @team/page.tsx
└── @analytics/page.tsx
text
layout 会多出和文件夹同名的 props:
export default function Layout({
children,
team,
analytics,
}: {
children: React.ReactNode;
team: React.ReactNode;
analytics: React.ReactNode;
}) {
return (
<div>
{team}
{children}
{analytics}
</div>
);
}
tsx
@team 对应 team,名字必须对上。children 仍然是「没有 @ 的那条默认槽」。
独立的 loading / error
每个槽可以有自己的 loading.tsx、error.tsx。分析面板慢、团队列表报错,不会把整页一起拖死。这是平行路由比「一个 page 里塞三个 fetch」更值当的地方。
子导航和 default.tsx
槽下面还能继续挂路由:
app/
├── layout.tsx
├── page.tsx
├── default.tsx
├── @team/
│ ├── page.tsx
│ └── setting/page.tsx
└── @analytics/
├── page.tsx
└── default.tsx
text
从 / 点 Link 去 /setting:客户端软导航时,Next 只替换 @team 里匹配到的那一块,@analytics 和 children 还留在上一页的活跃状态,看起来正常。
硬刷新 /setting 时,框架会同时给每个槽匹配 URL。@team 有 setting,@analytics 和默认槽没有,整页就会 404。
补一个 default.tsx 做兜底:
app/@analytics/default.tsxapp/default.tsx(给children槽)
硬刷新时没匹配到的槽渲染 default,不再炸 404。内容可以是 null,也可以是「请选择一项」之类的占位。
什么时候用
- 仪表盘:多块面板共享一个 URL
- 弹层、抽屉:用独立槽,返回时主列表还在
- 需要各槽自己的 loading / error
只是普通嵌套页面(/blog → /blog/a),用文件夹 + layout 就够,不必上平行路由。
下一篇:路由组,用括号文件夹组织代码但不改 URL。