You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中如何将[id]动态路由转换为slug格式自定义URL

Next.js 动态路由slug格式URL实现方案

你当前跳转异常的核心原因有两个:

  1. 路由文件结构和目标URL路径不匹配
  2. 动态路由参数名与query传参的字段名不一致,Next.js无法识别动态路径参数,最终把参数拼到了URL查询串上

具体实现步骤

1. 调整文件系统路由结构

Next.js的路由路径和本地文件结构一一对应,你的目标URL格式为/slug/posttitle,因此需要按如下结构创建路由文件:

  • 使用Pages Router:创建文件 pages/slug/[slug].js 作为博客详情页
  • 使用App Router:创建文件 app/slug/[slug]/page.js 作为博客详情页

2. 修正Link组件代码

动态路径的参数名必须和query中传递的字段名完全一致,之前代码里动态参数写的是[slug],但query传的是title字段,Next.js无法匹配到动态参数就会出现你遇到的URL异常问题,正确代码如下:

<Link
  href={{
    pathname: "/slug/[slug]",
    query: { slug: post.slug || post.title },
  }}
>
  {post.title}
</Link>

注意:不建议直接用原始文章title作为URL参数,最好提前将title处理为符合URL规范的slug格式:转全小写、空格替换为短横线、移除特殊字符,例如标题My First Post处理为my-first-post,避免中文、特殊符号导致URL解析异常。

3. 调整详情页参数获取逻辑

路由改完后,详情页获取参数的逻辑也要对应调整:

  • Pages Router 示例:
// pages/slug/[slug].js
export async function getServerSideProps(context) {
  // 从query中获取slug参数查询对应文章
  const postSlug = context.query.slug
  const post = await fetchPostBySlug(postSlug)
  return {
    props: { post }
  }
}

export default function PostDetail({ post }) {
  return <div>{post.title}</div>
}
  • App Router 示例:
// app/slug/[slug]/page.js
async function fetchPostBySlug(slug) {
  // 文章查询逻辑
  return {}
}

export default async function PostDetail({ params }) {
  const post = await fetchPostBySlug(params.slug)
  return <div>{post.title}</div>
}

无/slug前缀的实现补充

如果你不需要/slug前缀,想要最终URL为http://localhost:3001/posttitle格式,只需要做两个调整:

  • 将路由文件放在根路径,命名为pages/[slug].js(Pages Router)或app/[slug]/page.js(App Router)
  • 将Link组件的pathname改为/[slug]即可,query字段依然保持slug和动态参数名一致

内容的提问来源于stack exchange,提问作者amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:18:20