Next.js站点:点击浏览器返回按钮时保留页面滚动位置
Next.js 返回页面保留滚动位置的解决方案
问题原因
Next.js 默认会在前进导航时滚动到页面顶部,但返回浏览器历史记录时应该保留原页面滚动位置。如果出现返回时回到顶部的情况,大概率是项目中存在自定义强制滚动到顶部的代码,覆盖了默认的滚动恢复行为。
分路由方案解决
1. App Router(Next.js 13+)
App Router 默认启用滚动恢复,但自定义滚动逻辑会干扰这一行为:
第一步:排查并修改强制滚动代码
检查根layout.js、页面组件(如博客列表页)中的useEffect,如果存在以下代码:useEffect(() => { window.scrollTo(0, 0); }, []);这段代码会在组件每次挂载时(包括返回页面时)强制滚动到顶部,需要修改为仅在前进导航时执行:
'use client'; import { useEffect, useState } from 'react'; import { usePathname } from 'next/navigation'; export default function RootLayout({ children }) { const pathname = usePathname(); const [isBackNav, setIsBackNav] = useState(false); useEffect(() => { // 监听浏览器返回事件 const handlePopState = () => setIsBackNav(true); window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); }, []); useEffect(() => { // 仅非返回导航时滚动到顶部 if (!isBackNav) window.scrollTo(0, 0); // 重置状态,确保下次前进导航生效 setIsBackNav(false); }, [pathname]); return ( <html lang="zh-CN"> <body>{children}</body> </html> ); }第二步:确认滚动恢复配置
检查next.config.js,确保没有禁用默认滚动恢复:// next.config.js module.exports = { // 不要设置 scrollRestoration: false };
2. Pages Router(Next.js 12及以下)
Pages Router 默认支持返回时保留滚动位置,问题同样来自自定义滚动逻辑:
- 修改
_app.js中的滚动处理逻辑,仅在前进导航时滚动到顶部:import { useEffect } from 'react'; import { useRouter } from 'next/router'; function MyApp({ Component, pageProps }) { const router = useRouter(); useEffect(() => { const handleRouteComplete = (url, { shallow }) => { // 非浅路由、非返回导航时,滚动到顶部 if (!shallow && window.performance.navigation.type !== 2) { window.scrollTo(0, 0); } }; router.events.on('routeChangeComplete', handleRouteComplete); return () => router.events.off('routeChangeComplete', handleRouteComplete); }, [router]); return <Component {...pageProps} />; } export default MyApp;
针对你的博客项目的排查建议
从你的项目结构来看,使用的是 App Router,重点检查:
app/layout.js或app/blog/page.js中是否存在强制滚动到顶部的代码- 确认
next.config.js未禁用滚动恢复
内容的提问来源于stack exchange,提问作者GorvGoyl
相关产品推荐
相关产品推荐

