跳至正文
来两杯美式
返回

Next.js 并行路由完全指南

By 来两杯美式
发布于更新于

所有规则均为 13.4+ 正式版标准,无冗余内容,完全覆盖工业级 T3 项目开发需求。


一、基础认知

1. 是什么

并行路由是让同一个 URL 下可以同时渲染多个完全独立的路由模块的能力,每个模块有自己的路由匹配、加载、错误边界,互不影响。

典型 T3 项目使用场景:后台的侧边栏、主内容、全局模态框、通知栏四个模块完全解耦,各自走自己的路由逻辑。

2. 前置要求

// app/layout.tsx
export default function RootLayout({
  children,
  sidebar, // 对应@sidebar槽
  modal, // 对应@modal槽
  toast, // 对应@toast槽
}: {
  children: React.ReactNode;
  sidebar: React.ReactNode;
  modal: React.ReactNode;
  toast: React.ReactNode;
}) {
  return (
    <html>
      <body>
        {toast}
        {modal}
        <div className="flex">
          {sidebar}
          <main>{children}</main>
        </div>
      </body>
    </html>
  );
}

二、核心匹配规则

每个 @xxx 槽位完全独立匹配当前访问的 URL 路径,和主路由 children、其他槽位的匹配逻辑完全无关,匹配规则和普通主路由完全一致。

1. 最高优先级:匹配槽位下对应路径的 page.tsx

比如访问 /post/123

2. 次优先级:逐层向上找 default.tsx 兜底

如果匹配不到对应路径的 page.tsx,就从当前路径段开始逐层向上找父级的 default.tsx

还是访问 /post/123@sidebar 槽找不到 @sidebar/post/[id]/page.tsx

  1. 先找 @sidebar/post/default.tsx → 没有
  2. 再找 @sidebar/default.tsx → 有就渲染

3. 最低优先级:无兜底则直接 404

如果从当前路径到 @xxx 根目录都找不到 page.tsxdefault.tsx,哪怕主路由 children 存在,整个页面直接返回 404。


特殊文件作用(每个槽位独立生效)

文件作用范围
@xxx/page.tsx仅服务于根路径 / 的专属内容,不是全局默认
@xxx/default.tsx全局兜底内容,所有匹配不到专属 page.tsx 的路径都渲染它
@xxx/loading.tsx当前槽位独有的加载 UI,不影响其他槽位和主内容
@xxx/error.tsx当前槽位独有的错误边界,槽位报错不会导致整个页面崩溃
@xxx/layout.tsx当前槽位下所有子路径的公共布局

三、组合规则(T3 项目必备)

并行路由 90% 的生产级用法都是和拦截路由配合,实现「模态框随 URL 变化、刷新保留状态、关闭回退」的标准交互。

拦截路由的路径前缀规则

前缀匹配逻辑典型用法
(.)匹配同级路径@modal/(.)user/[id]/page.tsx:从同级页面点进 /user/123 时弹模态框
(..)匹配上一级路径@modal/(..)post/[id]/page.tsx:从子页面点进 /post/123 时弹模态框
(..)(..)匹配上两级路径同理

四、导航行为规则

  1. 客户端软导航(Link 点击、router.push):所有槽位都会重新匹配新路径,已匹配的内容如果没有变化不会重新渲染(比如通用侧边栏在 /dashboard/dashboard/settings 都匹配 default.tsx,跳转时不会重渲)

  2. 硬刷新/服务端导航:拦截路由的前缀((.)/(..))失效,槽位会按普通路径匹配,找不到就走 default.tsx 兜底

举个例子:从 /dashboard 点击 /user/123 触发软导航,@modal 槽匹配 (.)user/[id]/page.tsx 弹框;刷新 /user/123 时,@modal 找不到 @modal/user/[id]/page.tsx,走 default.tsx 返回空,主路由渲染 app/user/[id]/page.tsx 的独立页面,符合用户预期。


五、避坑指南(Top5 新手必踩)

  1. 忘加 default.tsx:路径不匹配直接 404,哪怕主路由存在

  2. @xxx/page.tsx 当成全局默认:它仅服务于根路径 /,其他路径找不到专属 page.tsx 只会用 default.tsx

  3. 槽位文件夹没加 @ 前缀:会被当成普通路由,生成 /sidebar 这类可访问路径,不是槽位

  4. 根 Layout 的 props 名和槽位名不一致:比如槽位叫 @userModal,props 传 usermodal,大小写敏感,渲染不出来

  5. 槽位里写 layout.tsx 忘传 children:槽位的布局和普通布局一样,必须接收 children 渲染子内容


六、T3 项目最佳实践

标准后台结构

app/
├── layout.tsx // 接收children、sidebar、modal、toast四个prop
├── @sidebar/
│   ├── default.tsx // 全局通用侧边栏(放菜单、用户信息)
│   ├── page.tsx // 根路径/专属侧边栏(放欢迎引导)
│   └── settings/
│       └── page.tsx // /settings路径专属侧边栏(放设置分类)
├── @modal/
│   ├── default.tsx // 兜底返回null,默认不显示
│   └── (.)user/[id]/page.tsx // 拦截同级的/user/[id],弹用户详情模态框
├── @toast/
│   └── default.tsx // 全局通知组件,永远渲染,不用其他配置
├── dashboard/
│   └── page.tsx
├── settings/
│   └── page.tsx
├── user/
│   └── [id]/page.tsx // 直接访问/user/[id]时的独立页面
└── page.tsx

对应渲染结果

访问路径渲染内容
/侧边栏用根路径专属,主内容用根 page,模态框隐藏
/dashboard侧边栏用全局 default,主内容用 dashboard/page,模态框隐藏
/settings侧边栏用 settings 专属,主内容用 settings/page,模态框隐藏
从/dashboard 点进 /user/123侧边栏不变,主内容还是 dashboard/page,模态框弹用户详情,URL 变成 /user/123
刷新 /user/123模态框隐藏,主内容用 user/[id]/page 的独立页面

分享这篇文章:
通过邮件分享这篇文章✓ 链接已复制
查看系列全部文章
  1. 01.T3 Stack 开发规范
  2. 02.Next.js 并行路由完全指南
  3. 03.Web 会话与身份验证完整指南
  4. 04.Auth Guard 与 tRPC 中间件
  5. 05.T3 Stack 会话认证指南
  6. 06.Next.js 子域名、反向代理与分享链路最佳实践
  7. 07.CORS 与 Web 安全实战白皮书
  8. 08.Web 多主题架构最佳实践
  9. 09.Vercel AI SDK 自定义 OpenAI 模型接入
  10. 10.AI 驱动动态看板架构指南
  11. 11.VitePress 动态渲染全栈落地方案

上一篇
Web 会话与身份验证完整指南
下一篇
T3 Stack 开发规范