Next.js使用next-pwa时如何在用户不刷新页面的情况下提示版本更新
你的现有实现只会在页面首次加载、刷新时注册Service Worker并检查更新,后台挂着的标签页不会主动触发更新检测,所以才会出现只有刷新才会弹出提示的问题。要实现用户切回标签页就收到新版本提示的效果,只要补充两个逻辑即可:
- 监听页面可见性变化事件,用户切回当前标签页时主动触发Service Worker更新检查
- 可选补充定时轮询检查,即使用户一直停留在当前页面也能定时检测新版本
修改后的完整代码如下:
const useServiceWorker = () => { const { showSnackbar } = useSnackbars() // 增加标识避免重复弹出提示 const hasShownNewVersionTip = useRef(false) const showUpdateTip = (wb) => { if (hasShownNewVersionTip.current) return hasShownNewVersionTip.current = true showSnackbar('应用有新版本可用!', { onClick: () => { wb.addEventListener('controlling', () => window.location.reload()) wb.messageSkipWaiting() }, onClose: () => { // 关闭提示后重置标识,后续有新版本还可以正常弹出 hasShownNewVersionTip.current = false }, }) } useEffect(() => { if (typeof window === 'undefined' || !('serviceWorker' in navigator) || !window.workbox) return const wb = window.workbox // 保留原有的waiting事件监听逻辑 wb.addEventListener('waiting', () => showUpdateTip(wb)) // 新增逻辑:页面从后台切回时主动检查更新 const handleVisibilityChange = () => { if (document.visibilityState === 'visible') { wb.update() } } document.addEventListener('visibilitychange', handleVisibilityChange) // 可选逻辑:每30分钟定时检查一次更新,可按需调整时长或者直接删除 const updateInterval = setInterval(() => { wb.update() }, 30 * 60 * 1000) wb.register() // 组件卸载时清理事件监听和定时器 return () => { document.removeEventListener('visibilitychange', handleVisibilityChange) clearInterval(updateInterval) } }, [showSnackbar]) }
注意事项
- 请确认
next.config.js中的next-pwa配置没有开启skipWaiting: true,如果开启该配置,新Service Worker安装后会直接跳过等待状态自动激活,不会触发waiting事件,也就无法弹出更新提示 - 如果需要适配多标签页打开的同步提示场景,可以额外增加message事件监听,接收其他标签页发送的更新通知,普通场景下上述代码已经可以满足需求
内容的提问来源于stack exchange,提问作者Andrew Korin
相关产品推荐
相关产品推荐

