Next.js实现类似WhatsApp Web的断网提示页面
Next.js 实现类WhatsApp网页版断网提示方案
核心基于浏览器原生网络状态API实现,可覆盖无网络、弱网两种场景,状态变更时自动展示/隐藏全屏提示,和WhatsApp网页版交互逻辑一致。
核心实现逻辑
- 监听浏览器原生
online/offline事件,实时捕获网络通断状态 - 初始状态读取
navigator.onLine属性,注意该属性仅能判断设备是否接入网络,无法识别网络质量差的场景 - 补充弱网检测:结合
Network Information API判断网络制式,加定时小资源请求探针兜底,超时即判定为弱网 - 网络异常时展示最高层级全屏提示,网络恢复后自动隐藏,无需用户手动操作
App Router 实现(Next.js 13+ 版本)
1. 编写全局网络状态组件
新建app/components/NetworkStatusProvider.tsx,标记为客户端组件,统一管理网络状态和提示UI:
'use client' import { createContext, useContext, useEffect, useState } from 'react' const NetworkContext = createContext({ isOnline: true, isPoorConnection: false }) export function NetworkStatusProvider({ children }: { children: React.ReactNode }) { const [isOnline, setIsOnline] = useState(true) const [isPoorConnection, setIsPoorConnection] = useState(false) // 弱网检测方法 const checkConnectionQuality = async () => { // 优先用原生网络信息API判断 const conn = (navigator as any).connection if (conn) { const type = conn.effectiveType if (type === 'slow-2g' || type === '2g') { setIsPoorConnection(true) return } } // 兜底:请求极小静态资源,超时判定为网络异常 try { const controller = new AbortController() const timer = setTimeout(() => controller.abort(), 3000) await fetch('/1px.gif', { signal: controller.signal, cache: 'no-store' }) clearTimeout(timer) setIsPoorConnection(false) } catch { setIsPoorConnection(true) } } useEffect(() => { // 初始化状态 setIsOnline(navigator.onLine) checkConnectionQuality() const handleOnline = () => { setIsOnline(true) checkConnectionQuality() } const handleOffline = () => setIsOnline(false) window.addEventListener('online', handleOnline) window.addEventListener('offline', handleOffline) // 每30秒轮询一次网络质量 const pollTimer = setInterval(checkConnectionQuality, 30000) return () => { window.removeEventListener('online', handleOnline) window.removeEventListener('offline', handleOffline) clearInterval(pollTimer) } }, []) return ( <NetworkContext.Provider value={{ isOnline, isPoorConnection }}> {children} {/* 网络异常时展示全屏提示 */} {(!isOnline || isPoorConnection) && ( <div className="fixed inset-0 z-[9999] bg-white flex flex-col items-center justify-center gap-3"> <svg className="w-16 h-16 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18.364 5.636a9 9 0 010 12.728m0 0l-2.829-2.829m2.829 2.829L21 21M15.536 8.464a5 5 0 010 7.072m0 0l-2.829-2.829m-4.243 2.829a4.978 4.978 0 01-1.414-2.83m-1.414 5.658a9 9 0 01-2.167-9.238m7.824 2.167a1 1 0 111.414 1.414m-1.414-1.414L3 3" /> </svg> <p className="text-xl font-medium text-gray-800">Your internet connection is down</p> <p className="text-sm text-gray-500">网络恢复后页面将自动加载</p> </div> )} </NetworkContext.Provider> ) } export const useNetworkStatus = () => useContext(NetworkContext)
2. 根布局注入全局组件
修改app/layout.tsx,将Provider包裹所有页面内容:
import { NetworkStatusProvider } from './components/NetworkStatusProvider' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <NetworkStatusProvider> {children} </NetworkStatusProvider> </body> </html> ) }
Pages Router 实现(Next.js 12 及更早版本)
直接在自定义_app.tsx中写入监听逻辑即可,无需单独抽离组件:
import type { AppProps } from 'next/app' import { useEffect, useState } from 'react' export default function MyApp({ Component, pageProps }: AppProps) { const [showNetworkTip, setShowNetworkTip] = useState(false) useEffect(() => { setShowNetworkTip(!navigator.onLine) const setOnline = () => setShowNetworkTip(false) const setOffline = () => setShowNetworkTip(true) window.addEventListener('online', setOnline) window.addEventListener('offline', setOffline) return () => { window.removeEventListener('online', setOnline) window.removeEventListener('offline', setOffline) } }, []) return ( <> <Component {...pageProps} /> {showNetworkTip && ( <div className="fixed inset-0 z-[9999] bg-white flex items-center justify-center"> <p className="text-xl font-medium text-gray-800">Your internet connection is down</p> </div> )} </> ) }
配置注意事项
- 在项目
public目录存放一个体积小于1KB的1px.gif静态资源,作为弱网检测的请求探针,避免跨域、接口权限等问题 - 提示层的
z-index设置为足够大的数值,保证能覆盖所有页面元素,和WhatsApp提示层级一致 - 无需额外添加手动刷新按钮,网络恢复后事件会自动触发隐藏提示,用户可无缝继续操作
- 可根据业务需求调整弱网检测的超时阈值,比如设置2秒超时即判定为弱网
内容的提问来源于stack exchange,提问作者fatemeh kazemi
相关产品推荐
相关产品推荐

