next路由规则
分类: 编码创建于: 5/31/2025
Next.js 是一个基于 React 的全栈框架,其路由规则主要基于文件系统(File System Based Routing),即通过项目中 pages
或 app
目录下的文件和文件夹结构来定义路由。Next.js 的路由规则非常直观,开发者无需手动配置复杂的路由表,只需按照约定组织文件即可。以下是 Next.js 路由规则的详细说明,涵盖了 pages
目录(传统路由)和 app
目录(App Router,Next.js 13 及以上版本引入)两种模式。
1. 传统路由:基于 pages
目录
在 Next.js 12 及之前的版本(以及未启用 App Router 的项目)中,路由基于 pages
目录下的文件结构。规则如下:
基本路由规则
- 文件映射到路由:
pages
目录下的每个.js
,.jsx
,.ts
, 或.tsx
文件都会映射到一个路由。- 例如:
pages/index.js
映射到根路径/
。 - 例如:
pages/about.js
映射到路径/about
。
- 例如:
- 嵌套路由:通过文件夹创建嵌套路由。
- 例如:
pages/blog/post.js
映射到路径/blog/post
。
- 例如:
- 动态路由:通过在文件名或文件夹名中使用方括号
[param]
定义动态参数。- 例如:
pages/post/[id].js
映射到/post/1
,/post/abc
等路径,id
可以通过useRouter
获取。 - 例如:
pages/shop/[category]/[product].js
映射到/shop/electronics/phone
,其中category
和product
是动态参数。
- 例如:
- 可选的 Catch-All 路由:使用
[...param]
定义可选的动态路由,捕获多个路径段。- 例如:
pages/docs/[...slug].js
可以匹配/docs/a
,/docs/a/b
,/docs/a/b/c
等,slug
是一个数组。
- 例如:
- 强制 Catch-All 路由:使用
[[...param]]
定义可选的动态路由,包含根路径。- 例如:
pages/docs/[[...slug]].js
可以匹配/docs
,/docs/a
,/docs/a/b
等。
- 例如:
特殊文件
- _app.js:自定义 App 组件,用于全局布局或状态管理,不映射到具体路由。
- _document.js:自定义 HTML 文档结构,仅在服务器端渲染时生效,不映射到路由。
- _error.js:自定义错误页面,用于处理 404 或 500 错误。
- 404.js:自定义 404 页面。
- 500.js:自定义 500 页面。
API 路由
- 在
pages/api
目录下定义后端接口,文件结构映射到/api/*
路径。- 例如:
pages/api/hello.js
映射到/api/hello
。 - 支持动态参数,例如:
pages/api/post/[id].js
映射到/api/post/1
。
- 例如:
中间件和重写规则
- 使用
next.config.js
或中间件(Next.js 12 引入)可以重写路由规则、实现重定向或国际化支持。
2. 新路由:基于 app
目录(App Router,Next.js 13 及以上)
从 Next.js 13 开始,引入了基于 app
目录的新路由模式(App Router),旨在支持 React Server Components、更好的性能优化和更灵活的布局。规则如下:
基本路由规则
- 文件夹映射到路由:
app
目录下的每个文件夹对应一个路由段,文件page.js
或page.tsx
定义该路由的内容。- 例如:
app/page.js
映射到根路径/
。 - 例如:
app/about/page.js
映射到路径/about
。
- 例如:
- 嵌套路由:通过嵌套文件夹定义嵌套路由。
- 例如:
app/blog/post/page.js
映射到/blog/post
。
- 例如:
- 动态路由:使用
[param]
文件夹定义动态参数。- 例如:
app/post/[id]/page.js
映射到/post/1
,/post/abc
,id
可通过params
获取。
- 例如:
- 可选的 Catch-All 路由:使用
[...param]
文件夹捕获多个路径段。- 例如:
app/docs/[...slug]/page.js
匹配/docs/a
,/docs/a/b
等。
- 例如:
- 强制 Catch-All 路由:使用
[[...param]]
文件夹,包含根路径。- 例如:
app/docs/[[...slug]]/page.js
匹配/docs
,/docs/a
等。
- 例如:
布局系统
- layout.js:定义布局文件,可以为特定路由或路由组提供共享布局。
- 例如:
app/layout.js
是根布局,包裹所有页面。 - 例如:
app/dashboard/layout.js
为/dashboard
及其子路由定义布局。
- 例如:
- 布局可以嵌套,子路由会继承父路由的布局。
其他特殊文件
- error.js:定义错误边界,处理特定路由的错误。
- loading.js:定义加载状态 UI,与 Suspense 结合使用。
- not-found.js:自定义 404 页面。
- route.js:定义 API 路由,类似
pages/api
,但支持更多 HTTP 方法。
路由组(Route Groups)
- 使用
(group-name)
形式的文件夹定义路由组,用于组织代码或应用不同布局,不影响 URL 路径。- 例如:
app/(marketing)/about/page.js
和app/(marketing)/contact/page.js
共享一个布局,但 URL 仍然是/about
和/contact
。
- 例如:
并行路由(Parallel Routes)
- 使用
@folder
语法定义并行路由,用于在同一页面渲染多个独立的内容。- 例如:
app/dashboard/@analytics/page.js
和app/dashboard/@overview/page.js
可以在/dashboard
页面同时渲染。
- 例如:
中间件和配置
- App Router 支持更强大的中间件,可以用于重定向、URL 重写、身份验证等。
- 通过
next.config.js
或middleware.js
配置。
Server Components 和 Client Components
- 默认情况下,App Router 中的组件是 Server Components(在服务器端渲染)。
- 使用
"use client"
指令将组件标记为 Client Components(在客户端渲染),支持交互性。
3. 路由优先级
在 pages
和 app
目录中,Next.js 按照以下优先级解析路由:
- 静态路由优先于动态路由。
- 例如:
/about
会优先匹配pages/about.js
,而不是pages/[slug].js
。
- 例如:
- 具体路径优先于 Catch-All 路由。
- 例如:
/docs/a
会优先匹配pages/docs/a.js
,而不是pages/docs/[...slug].js
。
- 例如:
4. 获取路由参数和查询参数
- 在
pages
目录中:- 使用
useRouter
Hook(来自next/router
)获取动态参数和查询参数。1import { useRouter } from 'next/router'; 2 3export default function Post() { 4 const router = useRouter(); 5 const { id } = router.query; // 获取动态参数 6 return <div>Post ID: {id}</div>; 7}
- 使用
- 在
app
目录中:- 动态参数通过
params
传递给页面组件,查询参数通过searchParams
获取。1export default function Post({ params, searchParams }) { 2 const { id } = params; // 获取动态参数 3 const query = searchParams.q; // 获取查询参数 ?q=xxx 4 return <div>Post ID: {id}, Query: {query}</div>; 5}
- 动态参数通过
5. 路由跳转
- 客户端导航:使用
next/link
组件或useRouter
的push
方法。1import Link from 'next/link'; 2 3<Link href="/about">About Us</Link>;
1import { useRouter } from 'next/router'; // 或 next/navigation(App Router) 2 3const router = useRouter(); 4router.push('/about');
- 服务器端重定向:使用
getServerSideProps
或getStaticProps
返回redirect
。1export async function getServerSideProps(context) { 2 return { 3 redirect: { 4 destination: '/about', 5 permanent: false, 6 }, 7 }; 8}
6. 国际化路由
Next.js 支持国际化路由,通过 next.config.js
配置 i18n
实现多语言支持。
1module.exports = { 2 i18n: { 3 locales: ['en', 'zh'], 4 defaultLocale: 'en', 5 }, 6};
- 路由会自动添加语言前缀,例如
/en/about
和/zh/about
。
总结
- Pages Router(
pages
目录):传统路由,基于文件系统,简单易用,适合小型项目或需要快速开发的场景。 - App Router(
app
目录):Next.js 13+ 引入,支持 Server Components、布局系统和更复杂的功能,适合现代大型应用。 - 路由规则的核心是文件系统约定,开发者通过文件和文件夹的命名来定义静态、动态和嵌套路由。
如果你有具体的路由问题或需要某个功能的代码示例,请告诉我,我会进一步帮助你!