← [ BACK_TO_NOTES ]

Next.js 动态路由段

Next.js App Router 用 [id]、[...slug]、[[...slug]] 表达动态、Catch-all 与 Optional Catch-all URL segment,并通过 params 取得路径参数。

#concept #growing #frame #react

[!info] related notes

Next.js 动态路由段

一句话定义

Next.js 动态路由段允许目录名中使用方括号,把 URL 中某一段或多段路径作为运行时参数交给页面。

最常见形式:

[id]         → 一个动态 segment
[...slug]    → 一个或多个 segment
[[...slug]]  → 零个或多个 segment

单个动态 Segment:[id]

app/
└── assessment/
    └── [assessmentId]/
        └── page.tsx

可以匹配:

/assessment/123
/assessment/a8f2...

页面通过 params 取得:

export default async function Page({
  params,
}: {
  params: Promise<{ assessmentId: string }>
}) {
  const { assessmentId } = await params
  // ...
}

所以:

/assessment/123
        ↓
assessmentId = "123"

[id]、[slug]、[assessmentId] 的区别

方括号内部名称只是参数名,本质机制相同。

常见语义:

  • [id]:数据库或领域实体标识。
  • [slug]:更适合人类阅读的 URL 标识,例如 react-server-components。
  • [assessmentId]:在多层动态路由中更明确,避免多个 id 混淆。

Catch-all:[...slug]

app/docs/[...slug]/page.tsx

可以匹配:

/docs/react
/docs/react/hooks
/docs/react/hooks/use-effect

得到的参数通常是数组:

["react"]
["react", "hooks"]
["react", "hooks", "use-effect"]

适合文档、Wiki、CMS、知识库等深度不固定的内容路径。

Optional Catch-all:[[...slug]]

app/shop/[[...slug]]/page.tsx

除了:

/shop/clothing
/shop/clothing/shirts

还可以覆盖没有后续 segment 的:

/shop

因此:

[...slug]   → 至少一个 segment
[[...slug]] → 可以没有 segment

多层动态路由

/goals/123/tasks/456

可表示为:

app/
└── goals/
    └── [goalId]/
        └── tasks/
            └── [taskId]/
                └── page.tsx

得到:

goalId = "123"
taskId = "456"

URL 层级不是授权证明

一个非常重要的安全边界:

/goals/123/tasks/456

只表示客户端请求了这组标识,不证明 Task 456 一定属于 Goal 123,也不证明当前用户有访问权限。

服务端仍必须验证:

身份认证
   ↓
资源存在性
   ↓
Goal / Task 关系
   ↓
当前用户是否拥有访问权限

否则很容易形成 IDOR / BOLA。

URL 层级和数据库关系不是同一回事

路由可以表达产品的信息架构,但不能让目录结构替代领域约束。

URL nesting
≠
DB foreign-key relation
≠
authorization rule

这三个层面可以相互映射,但必须分别验证。

最短记忆方式

[id]         = 一个变量路径段
[...slug]    = 一个或多个变量路径段
[[...slug]]  = 零个或多个变量路径段
params       = 页面取得这些路径值的入口

普通目录如何组成 URL,见 Next.js 文件系统路由。

创建于 2026/9/15 更新于 2026/9/15
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本