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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:57:22