Next.js如何配置动态路由实现/[分类]/[文章]及分类页可访问路径
Next.js 无前缀分类+文章URL路由配置解决方案
你需要的路由结构对应配置如下
你要实现的/分类名/文章slug和/分类名两级路由,只需要按照层级嵌套动态路由段即可,分两种常用路由模式给出配置:
方案1:App Router(Next.js 13及以上版本,默认路由模式)
正确文件结构
app/ └── [category]/ ├── page.tsx // 对应分类页:https://www.example.com/category1 └── [postSlug]/ └── page.tsx // 对应文章页:https://www.example.com/category1/post-1
页面参数获取示例
- 分类页
app/[category]/page.tsx:
// 拿到当前分类参数 export default function CategoryPage({ params }: { params: { category: string } }) { const category = params.category // 后续根据分类获取对应内容即可 return <div>当前分类:{category}</div> } // 静态生成时需要预生成所有分类路径,SSG/静态导出场景必填 export async function generateStaticParams() { // 这里替换为你实际的分类列表查询逻辑 const categories = [{ slug: 'category1' }, { slug: 'category2' }] return categories.map((cat) => ({ category: cat.slug, })) }
- 文章页
app/[category]/[postSlug]/page.tsx:
export default function PostPage({ params }: { params: { category: string; postSlug: string } }) { const { category, postSlug } = params // 后续根据分类和文章slug获取对应文章内容即可 return <div>当前分类:{category},当前文章:{postSlug}</div> } // 静态生成预生成路径,SSG/静态导出场景必填 export async function generateStaticParams() { // 这里替换为你实际的文章列表查询逻辑 const posts = [ { category: 'category1', slug: 'post-1' }, { category: 'category1', slug: 'post-2' }, { category: 'category2', slug: 'post-4' }, ] return posts.map((post) => ({ category: post.category, postSlug: post.slug, })) }
方案2:Pages Router(Next.js 12及更早版本)
正确文件结构
pages/ └── [category]/ ├── index.tsx // 对应分类页:https://www.example.com/category1 └── [postSlug].tsx // 对应文章页:https://www.example.com/category1/post-1
页面参数获取示例
- 分类页
pages/[category]/index.tsx:
import { useRouter } from 'next/router' export default function CategoryPage() { const router = useRouter() const category = router.query.category as string return <div>当前分类:{category}</div> } // SSG场景预生成路径 export async function getStaticPaths() { const categories = [{ slug: 'category1' }, { slug: 'category2' }] return { paths: categories.map(cat => ({ params: { category: cat.slug } })), fallback: false // 按需调整为true/blocking } } export async function getStaticProps({ params }) { // 根据params.category查询分类内容 return { props: { category: params.category } } }
- 文章页
pages/[category]/[postSlug].tsx:
import { useRouter } from 'next/router' export default function PostPage() { const router = useRouter() const { category, postSlug } = router.query return <div>当前分类:{category},当前文章:{postSlug}</div> } // SSG场景预生成路径 export async function getStaticPaths() { const posts = [ { category: 'category1', slug: 'post-1' }, { category: 'category1', slug: 'post-2' }, { category: 'category2', slug: 'post-4' }, ] return { paths: posts.map(post => ({ params: { category: post.category, postSlug: post.slug } })), fallback: false } } export async function getStaticProps({ params }) { // 根据params查询对应文章内容 return { props: { post: {} } } }
常见404原因排查
- 动态路由段的命名错误,必须用
[]包裹参数名,不能有拼写错误 - 静态导出/SSG场景下没有配置
generateStaticParams(App Router)或getStaticPaths(Pages Router),导致路径没有预生成 - 服务端渲染场景下
fallback配置错误,没有匹配到未预生成的路径
内容的提问来源于stack exchange,提问作者RebootGG
相关产品推荐
相关产品推荐

