Next.js App Router中Link组件as属性的使用困惑
as 属性的问题及解决方法 首先明确:Next.js App Router 已完全废弃 Link 组件的 as 属性,这是 Pages Router 时期的遗留用法,在 App Router 中使用会直接导致路由解析异常,也就是你遇到的参数获取错误的根源。
问题原因
在 Pages Router 里,as 属性的作用是做 URL 重写——让浏览器显示友好的自定义 URL,但实际请求的是 href 指定的真实路由。但 App Router 重构了整个路由系统,不再支持这种写法。现在你设置 as 后,App Router 会直接把 as 的路径当作实际路由解析,所以页面中拿到的参数是标题(project.title),而非 href 里的 ID,自然找不到对应页面。
实现友好 URL 同时保留 ID 参数的正确方式
要实现「浏览器显示标题友好 URL,同时能获取 ID 参数」的需求,推荐两种方案:
方案一:调整动态路由结构,同时包含 ID 和 Slug(标题)
修改路由文件结构为:
app/ └── projects/ └── [id]/ └── [slug]/ └── page.js
渲染 Link 时直接拼接包含 ID 和标题的路径:
{datas.map((project) => { return ( <div key={project.id}> <Link href={`/projects/${project.id}/${project.title}`}> {project.description} </Link> </div> ) })}
在 app/projects/[id]/[slug]/page.js 中,通过 params 获取 ID 和标题:
export default function ProjectPage({ params }) { // params.id 为项目ID,params.slug 为标题 console.log(params.id, params.slug) return <div>项目详情页面</div> }
这种方式简单直接,浏览器 URL 显示为 /projects/123/我的项目标题,既友好又能正常获取 ID 参数。
方案二:使用 Next.js 重写规则(next.config.js)
如果不想调整路由结构,可通过 next.config.js 的重写功能,将标题路径映射到带 ID 的真实路由(需后端支持根据标题反向查询 ID):
/** @type {import('next').NextConfig} */ const nextConfig = { async rewrites() { return [ { source: '/projects/:slug', // 替换为实际根据slug获取项目的接口或路由 destination: '/api/projects/get-by-slug?slug=:slug', }, ] }, } module.exports = nextConfig
后续需要在 app/api/projects/get-by-slug/route.js 中处理请求,根据 slug 查询到对应项目后,跳转到带 ID 的页面或直接返回数据。不过这种方式相对复杂,不如方案一直观。
总结
你之前的问题核心是误用了 Pages Router 的 as 属性,App Router 已不再支持该属性。改用「动态路由包含 ID 和 Slug」的方式,就能同时实现友好 URL 和正确获取 ID 参数的需求。
内容的提问来源于stack exchange,提问作者ShueiYang

