Next.js 13中Link组件无法跳转至页面锚点区块问题求助
问题
在Next.js 13项目中,使用原生<a>标签可以正常滚动到页面内的锚点区块(比如/#testimonials),但使用Next.js的<Link>组件时,仅URL地址栏发生变化,页面却不会滚动到目标区块。
相关代码及环境信息如下:
Testimonials组件代码
export function Testimonials() { return ( <section id="testimonials" aria-label="What our customers are saying" className="bg-slate-50 py-20 sm:py-32" > ... </section> ) }
Link组件使用代码
<div className="hidden md:flex md:gap-x-6"> <Link href="/#features">Features</Link> <Link href="/#testimonials">Testimonials</Link> <Link href="#pricing">Pricing</Link> </div>
环境信息
Operating System: Platform: linux Arch: x64 Version: #36-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 3 18:36:56 UTC 2023 Binaries: Node: 16.19.1 npm: 8.19.3 Yarn: N/A pnpm: N/A Relevant packages: next: 13.2.4 eslint-config-next: 13.2.4 react: 18.2.0 react-dom: 18.2.0
原因分析
Next.js 13的<Link>组件默认启用客户端路由(SPA模式),当跳转目标为当前页面的锚点时,它仅更新URL的hash部分,不会触发页面滚动——这是因为客户端路由在处理同页面hash变化时,没有内置自动滚动到对应锚点的逻辑。而原生<a>标签是浏览器原生行为,会自动处理锚点滚动。
解决方案
方法1:给Link组件添加scroll={true}属性
Next.js 13的<Link>组件提供了scroll属性,设置为true可强制触发滚动到锚点:
<div className="hidden md:flex md:gap-x-6"> <Link href="/#features" scroll={true}>Features</Link> <Link href="/#testimonials" scroll={true}>Testimonials</Link> <Link href="#pricing" scroll={true}>Pricing</Link> </div>
方法2:手动处理滚动逻辑
如果方法1不生效,可通过useRouter钩子手动监听hash变化并执行滚动:
'use client'; import { useRouter, usePathname } from 'next/navigation'; import { useEffect } from 'react'; export default function Layout() { const router = useRouter(); const pathname = usePathname(); useEffect(() => { const hash = window.location.hash; if (hash) { const element = document.getElementById(hash.slice(1)); if (element) { element.scrollIntoView({ behavior: 'smooth' }); } } }, [pathname, router]); return ( <div className="hidden md:flex md:gap-x-6"> <Link href="/#features">Features</Link> <Link href="/#testimonials">Testimonials</Link> <Link href="#pricing">Pricing</Link> </div> ); }
注意:需添加'use client'指令,因为使用了客户端钩子。
方法3:使用原生<a>标签(适合简单场景)
如果不需要客户端路由的优势,直接使用原生<a>标签即可保留浏览器原生的锚点滚动行为:
<div className="hidden md:flex md:gap-x-6"> <a href="/#features">Features</a> <a href="/#testimonials">Testimonials</a> <a href="#pricing">Pricing</a> </div>
内容的提问来源于stack exchange,提问作者Rafael Zasas
相关产品推荐
相关产品推荐

