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

Next.js中浏览器返回按钮不触发离开确认弹窗问题

Next.js中浏览器返回按钮不触发离开确认弹窗的解决方案

问题分析

你当前通过beforeunload事件实现的离开确认逻辑,仅在页面刷新、浏览器关闭这类页面卸载场景下生效。但Next.js的客户端路由(包括浏览器返回按钮触发的导航)属于SPA内部的路由切换,不会触发页面卸载,因此beforeunload事件不会被触发,也就不会弹出确认弹窗。

解决方案

需要同时监听Next.js的客户端路由变化事件,结合beforeunload覆盖所有场景:

完整代码实现

import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default function YourComponent() {
  const router = useRouter();
  const latestGeneratedImages = []; // 替换为你的实际状态变量

  useEffect(() => {
    // 处理页面卸载场景(刷新、关闭浏览器)
    const handleBeforeUnload = (event: BeforeUnloadEvent) => {
      if (latestGeneratedImages.length > 1) {
        event.preventDefault();
        event.returnValue = true;
      }
    };

    // 处理客户端路由切换场景(浏览器返回、页面内链接跳转)
    const handleRouteChangeStart = (url: string) => {
      if (latestGeneratedImages.length > 1) {
        const confirmLeave = window.confirm('你有未完成的内容,确定要离开吗?');
        if (!confirmLeave) {
          // 终止路由跳转流程
          router.events.emit('routeChangeError');
          throw '路由跳转已取消';
        }
      }
    };

    window.addEventListener('beforeunload', handleBeforeUnload);
    router.events.on('routeChangeStart', handleRouteChangeStart);

    return () => {
      window.removeEventListener('beforeunload', handleBeforeUnload);
      router.events.off('routeChangeStart', handleRouteChangeStart);
    };
  }, [latestGeneratedImages, router]);

  return <div>你的组件内容</div>;
}

关键说明

  • routeChangeStart:Next.js路由开始变化时触发的事件,通过它可以拦截所有客户端路由跳转行为,包括浏览器返回按钮触发的导航。
  • 手动确认弹窗:beforeunload的弹窗是浏览器原生样式,客户端路由切换场景需要手动调用window.confirm实现一致的确认逻辑。
  • 终止路由跳转:当用户选择不离开时,通过router.events.emit('routeChangeError')并抛出错误,来中断Next.js的路由切换流程。

注意事项

  • 务必将router加入依赖数组,避免因路由实例更新导致监听失效。
  • 弹窗提示语尽量明确,告知用户离开可能带来的影响(比如未保存内容丢失)。

内容的提问来源于stack exchange,提问作者Farhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:12:11