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

Next.js 13中使用window.ethereum报错,求替代方案

Next.js 13中window.ethereum报错的解决方案

问题原因

Next.js 13的App Router默认采用服务器组件,服务器端渲染时不存在window对象——你的代码直接访问window.ethereum,这就是报错的核心原因。Next.js 12的Pages Router默认是客户端组件,因此不会出现该问题。

替代方案

方案1:标记组件为客户端组件

在组件文件顶部添加'use client'指令,强制组件在浏览器端渲染,即可安全访问window对象:

'use client';

import { ethers } from 'ethers';

export default function WalletConnect() {
  const connectWallet = async () => {
    // 先判断window和钱包是否存在
    if (typeof window === 'undefined' || !window.ethereum) {
      alert('请安装MetaMask或其他以太坊钱包');
      return;
    }

    const provider = new ethers.providers.Web3Provider(window.ethereum);
    await provider.send("eth_requestAccounts", []);
    const signer = provider.getSigner();
    console.log(signer);
  };

  return (
    <button onClick={connectWallet}>连接以太坊钱包</button>
  );
}

方案2:动态导入组件(禁用SSR)

如果不想把整个页面改为客户端组件,可使用Next.js的dynamic导入,指定ssr: false让目标组件仅在客户端加载:

// 页面文件(服务器组件)
import dynamic from 'next/dynamic';

// 动态导入钱包组件,禁用服务器渲染
const WalletComponent = dynamic(() => import('./WalletConnect'), {
  ssr: false,
  loading: () => <p>加载中...</p>
});

export default function Home() {
  return (
    <div>
      <h1>以太坊钱包连接</h1>
      <WalletComponent />
    </div>
  );
}

额外提示

  • 无论采用哪种方案,都要先判断typeof window !== 'undefined'和window.ethereum是否存在,避免客户端初始化阶段的潜在报错。
  • 若使用ethers v6,API有变更,对应代码需调整为:const provider = new ethers.BrowserProvider(window.ethereum);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:45:27