Next.js 13实验性App Dir路由哈希无法定位指定ID求助
Next.js 13 App Dir 哈希锚点滚动失效的解决方案
问题根源
Next.js 13 实验性 App Router 的客户端导航逻辑和旧版 Pages Router 不同,目前内置的哈希锚点滚动存在兼容性问题,就算设置了scroll={false}或者用router.push("/#faqs")也没法触发浏览器的自动滚动行为。
解决办法
1. 手动监听路由变化实现滚动
在客户端组件里,用useRouter监听路由完成事件,手动定位到目标元素:
'use client'; import { useRouter } from 'next/navigation'; import { useEffect } from 'react'; export default function Home() { const router = useRouter(); useEffect(() => { const scrollToHash = () => { const hash = window.location.hash; if (!hash) return; const targetEl = document.getElementById(hash.slice(1)); targetEl?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }; // 页面加载时先检查哈希 scrollToHash(); // 监听路由切换完成事件 router.addEventListener('routeChangeComplete', scrollToHash); return () => router.removeEventListener('routeChangeComplete', scrollToHash); }, [router]); return ( <div> {/* 页面内容 */} <div id="faqs">FAQ 区域</div> </div> ); }
2. 强制使用原生浏览器跳转
如果不需要客户端导航的特性,直接让链接走浏览器原生跳转,哈希滚动就会正常工作:
import Link from 'next/link'; // 方法一:添加target="_self" <Link href="/#faqs" target="_self">跳转到FAQ</Link> // 方法二:用legacyBehavior回退到旧版Link逻辑 <Link href="/#faqs" legacyBehavior> <a>跳转到FAQ</a> </Link>
3. 升级Next.js版本
早期的Next.js 13实验性版本存在不少哈希滚动的bug,试试升级到最新的稳定版13.x,很多这类问题已经被修复。
4. 跨页面跳转时延迟滚动
从其他页面跳转到首页带哈希的URL时,可能因为页面还没渲染完导致找不到元素,加个小延迟再执行滚动:
'use client'; import { useEffect } from 'react'; export default function Home() { useEffect(() => { const hash = window.location.hash; if (!hash) return; const targetEl = document.getElementById(hash.substring(1)); if (targetEl) { // 延迟100ms确保DOM渲染完成 setTimeout(() => { targetEl.scrollIntoView({ behavior: 'smooth' }); }, 100); } }, []); // 页面内容... }
注意:所有操作window或document的代码必须放在客户端组件里,也就是顶部要加'use client'指令,服务器组件没法访问浏览器API。
内容的提问来源于stack exchange,提问作者Erik James Robles
相关产品推荐
相关产品推荐

