平行路由

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.tsxerror.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 里匹配到的那一块,@analyticschildren 还留在上一页的活跃状态,看起来正常。

硬刷新 /setting 时,框架会同时给每个槽匹配 URL。@teamsetting@analytics 和默认槽没有,整页就会 404。

补一个 default.tsx 做兜底:

  • app/@analytics/default.tsx
  • app/default.tsx(给 children 槽)

硬刷新时没匹配到的槽渲染 default,不再炸 404。内容可以是 null,也可以是「请选择一项」之类的占位。


什么时候用

  • 仪表盘:多块面板共享一个 URL
  • 弹层、抽屉:用独立槽,返回时主列表还在
  • 需要各槽自己的 loading / error

只是普通嵌套页面(/blog/blog/a),用文件夹 + layout 就够,不必上平行路由。

下一篇:路由组,用括号文件夹组织代码但不改 URL。


参考文档