Next.js中通过URL直接访问落地页时滚动到指定区域的实现问题
Next.js中通过URL直接访问落地页时滚动到指定区域的实现问题
看起来你遇到的问题是,想让用户访问localhost:3000/faqs时直接跳转到首页的FAQ区域,但现在直接访问会触发404——这很正常,因为Next.js默认会把/faqs当成一个独立的页面路由去寻找对应的页面文件,但你的FAQ组件是放在首页(根路径)里的对吧?下面给你一步步解决这个问题:
第一步:给目标组件添加唯一ID
首先,你需要给<LandingFaqs />组件加上一个可识别的ID,这样我们才能定位到它进行滚动:
<LandingFaqs id="faqs" />
第二步:配置路由重写,避免404
因为直接访问/faqs时,Next.js会找不到对应的页面文件,所以我们需要在next.config.js里添加重写规则,把/faqs的请求转发到首页:
// next.config.js module.exports = { async rewrites() { return [ { source: '/faqs', destination: '/', }, ]; }, };
这样用户访问/faqs时,就会加载首页内容,而不是跳404了。
第三步:在首页添加滚动逻辑
接下来回到你的LandingPage组件,我们需要监听路由路径,当用户是通过/faqs访问时,自动滚动到FAQ区域。利用你已经引入的useRouter和useEffect来实现:
// 在LandingPage组件内部 import { useEffect } from 'react'; import { useRouter } from 'next/router'; const LandingPage: NextPage<Props> = () => { const router = useRouter(); const { locale, asPath } = router; const { t } = useTranslation("common"); const completeURL = getFullURL(asPath, locale); useEffect(() => { // 检测当前访问路径是否是/faqs if (asPath === '/faqs') { // 找到FAQ组件对应的DOM元素 const faqsSection = document.getElementById('faqs'); if (faqsSection) { // 平滑滚动到目标区域 faqsSection.scrollIntoView({ behavior: 'smooth' }); } // 可选:把URL更新为带锚点的形式(比如/#faqs),用户刷新页面也能保持定位 router.push('/#faqs', undefined, { shallow: true }); } }, [asPath, router]); return ( <DefaultLayout showFooter showLandingNav fullWidth > <LandingBanner /> <OnlinePresence /> <MixMatch /> <JoinCommunity /> <LandingFaqs id="faqs" /> {/* 这里加上ID */} </DefaultLayout> ); };
额外说明
- 如果你的项目开启了国际化路由,记得在rewrite规则里考虑locale的情况,比如
/en/faqs要重写到/en/,可以把source改成/:locale/faqs(根据你的实际路由配置调整)。 scrollIntoView的behavior: 'smooth'是可选的,如果你不需要平滑滚动,去掉这个参数即可。
备注:内容来源于stack exchange,提问作者Ahmed fouad
相关产品推荐
相关产品推荐

