In an effort to make my dApp more user-friendly, especially for onboarding, I'm trying to guide new users into installing Metamask.

If no web3 provider is present, I show the user a "Create your wallet" button. When they click on it, they are headed to Metamask.io in a new tab.

The trouble arises when they install Metamask and go back to my dApp. There doesn't seem to be a way of detecting if a web3 provider is installed without reloading. I can't just programmatically reload the whole page, and asking my disengaged potential user to reload feels like very bad UX.

I created the following code snippet taken from Metamask's documentation to illustrate this behaviour.

  <script language="javascript">
  function checkProvider () {
    if (typeof window.ethereum !== 'undefined') {
      console.log('you already have a web3 provider');
    } else {
      console.log('please install Metamask');
  var interval = setInterval(checkProvider, 1000);

Basically it checks every second if you have a web3 provider. Since it can't run without a webserver, I put it online so you can quickly test it.

If I don't have Metamask installed, I get the expected message:

please install metamask

But after I install it and go back to this page, the same message keeps appearing:

metamask isn't detected without a refresh

Only after a refresh does my snippet detect metamask:

metamask is detected after a refresh

I can't be the only one facing onboarding issues with web3 providers. What workarounds have you thought of?

  • Same problem here. Any solutions? Commented Jun 4, 2022 at 11:14

2 Answers 2


You need to programmatically refresh the page to get web3 injected by metamask. You can write a recurisve function which will not run indefinetly and will refresh if metamask was not installed and installed later:

function checkWeb3ProviderRecursively(firstCall = true) {
    if (typeof window.ethereum !== 'undefined') {
        console.log("web3 provide detected")
        // reload the page
        if(!firstCall) document.location.reload()
    } else {
        console.log("Please install metamask")
        // add a delay here as you want
  • Wouldn't you need to put the reload statement in the else block? If you already detected the web3 provider, you don't need to refresh, whereas if you haven't detected it you need to refresh in order to re-check
    – e18r
    Commented Jul 3, 2020 at 22:50
  • I am using react and I found that when the user finishes installing MetaMask, the window object won't be updated which means this function will still find that window.ethereum is undefined until it gets reloaded. Recurring doesn't help in React. Commented Jun 4, 2022 at 10:58

ethereum.on('connect', (connectInfo) => { console.log("connected to wallet"); console.log(connectInfo); });



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.