1

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.

<html>
<body>
  <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);
  </script>
</body>
</html>

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?

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
        checkWeb3ProviderRecursively(false)
    }
}
| improve this answer | |
  • 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 Jul 3 at 22:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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