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
相关产品推荐
相关产品推荐

