2

I am trying to write a React-next.js app. I have the following file that exports an instance of Web3 by passing in window.ethereum to the constructor.

import Web3 from 'web3';

const web3 = new Web3(window.ethereum);

export default web3;

When next.js renders this on the server side, it throws the following error wherever I import this web3 on the browser.

ReferenceError: window is not defined

I have tried looking this up, but all the solutions suggest an if gate to check whether window is available or not inside functions that make use of window. But how to export web3 from this file?

2 Answers 2

0

Cong's answer there would work just fine but it doesn't give you a reason for the problem. Or alternate solutions... This question has also been asked many times outside of the ethereum fourm.

The gist is that the nextjs client code is first rendered on the server (i.e. not in a browser). On the server, window is not defined so you get an error like this. Cong gave you the javascript < 14 version with the typeof checks. For modern browsers you can simply do:

if (window?.ethereum) {
  // running on client and window + ethereum is avail
} else {
  // you are on the server.
  // OR user does not have a broswer wallet - i.e. metamask
}

If you need to do what Cong is suggesting to create a totally separate provider for some reason (maybe to load data without a browser wallet) then his way will work perfectly. If, however you don't want to load any web3 data without a connected wallet then you will want to "onboard" the user - have them install a browser wallet. I think either way you should add some kind of onboarding. I've strayed away from the answer now. =)

0

You can change your implement web3 as bellow

import Web3 from "web3";

let web3;

if (typeof window !== 'undefined' && typeof window.ethereum !== 'undefined')
{
    // we are in the browser and metamask is running
    window.ethereum.request({ method: "eth_requestAccounts" });
    web3 = new Web3(window.ethereum);
}
else
{
    // we are on the server *OR* the user is not running metamask
    // https://medium.com/jelly-market/how-to-get-infura-api-key-e7d552dd396f
    const provider = new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/xxx_your_key_here_xxx");
    web3 = new Web3(provider);
}

export default web3;
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.