You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:55:29