When building a DApp, you want your users to be able to interact with it!
This tutorial shows you the basic JavaScript code needed to connect a webpage to MetaMask; use it to develop your dApp!
In this case, we'll use the window.ethereum
global API injected directly by MetaMask, but there are other ways to do it, using ethers.js
or web3.js
, for example.
This article has the full code, but you can find the repo on Github to also find the CSS code.
Serve the webpage and see how it works.
You can find the reference code in the MetaMask docs.
The repository contains
- index.html - Content and structure of the webpage
- style.css - Styling of the webpage
How to run and serve the page
To serve the webpage, you can use a simple node server. Follow these instructions:
- Install Node.js - Download and instructions.
Install lite-server (with NPM in a terminal/command prompt).
npm install -g lite-server
Now, you have the tools to serve a webpage on localhost.
- Create a new folder and save the files from this project in it.
Serve the webpage via terminal/command prompt from the directory that has
index.html
in it and run:lite-server
Now, your webpage will be available on http://127.0.0.1:3000/.
Create the HTML file
For this example, we start with an empty HTML boilerplate. Since we use the window.ethereum
API injected by MetaMask, we don't need to import any library, but note that MetaMask must be installed!
Start by creating a new index.html
file in your project directory.
You can use the following boilerplate.
Note that the file in the repository is linked to a
.css
stylesheet. The project works without the stylesheet, but it will look different than the images from this tutorial. Take the CSS code from the repository if you want the same styling.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <link rel="stylesheet" type="text/css" href="./style.css"/> -->
<title>Connect MetaMask</title>
</head>
<body>
</body>
</html>
I named the page Connect MetaMask
.
Once the main file is created, let's add some basic HTML elements. We just add a few sentences to describe what the page does and a button to prompt the user to connect MetaMask.
Inside the <body>
tag place:
<div class="parent">
<div class="div1">
<h1 class="center">Connect MetaMask to a webpage</h1>
<h2 class="center">This page shows you how to connect MetaMask to a webpage to create a DApp!</h2>
<h3 class="center">Check the source code in the <a href="https://github.com/soos3d/connect-metamask-to-webpage" target="_blank">GitHub repo</a>.</h3>
<p class="center">Click the button to prompt MetaMask to connect</p>
</div>
<div class="div2">
<h3>Click the button to connect MetaMask to the website</h3>
<button onclick="connect()">Connect Wallet</button> <!-- The `onclick` event means we'll call the specified function when we click the button. -->
</div>
</div>
Note that the
class
tags refer to the CSS code included in the repo; the code still works without the stylesheet; it just looks different.
At this point, we can already serve the page and run lite-server
in the terminal from the folder where the index.html
file lives.
Now that our HTML skeleton is ready, we can work on the connection itself; you won't believe how easy it is!
It will look like this:
Connect MetaMask to the webpage
Now that our HTML skeleton is ready, we can work on the connection itself; you won't believe how easy it is!
To prompt the user to connect their MetaMask to the page, we'll use some simple JavaScript code, and we can place it in a <script>
tag inside the HTML body. This is excellent for testing and learning, but you should use a separate .js
file for more complex apps.
Make sure to name the function the way you specified in the
onclick
event on the HTML button.
<script>
// Identify the accounts and connect MetaMask to the website.
function connect() {
ethereum.request({
method: 'eth_requestAccounts' // Use the eth_requestAccounts method to promt the user to select and connect an account.
// Log and error in the console if the user refuses the connection.
}).then(handleAccountsChanged).catch((error) => {
if (error.code === 4001) {
// EIP-1193 userRejectedRequest error
console.log('Please connect to MetaMask.');
} else {
console.error(error);
}
});
}
</script>
That's it! Now you can connect MetaMask to this webpage! The reference code can be found in the MetaMask docs.
At this point, the HTML file should look like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="./style.css" />
<title>Connect MetaMask</title>
</head>
<body>
<div class="parent">
<div class="div1">
<h1 class="center">Connect MetaMask to a webpage</h1>
<h2 class="center">This page shows you how to connect MetaMask to a webpage to create a DApp!</h2>
<h3 class="center">Check the source code in the <a href="https://github.com/soos3d/connect-metamask-to-webpage" target="_blank">GitHub repo</a>.</h3>
<p class="center">Click the button to prompt MetaMask to connect</p>
</div>
<div class="div2">
<h3>Click the button to connect MetaMask to the website</h3>
<button onclick="connect()">Connect Wallet</button>
</div>
</div>
<script>
// Identify the accounts and connect MetaMask to the website.
function connect() {
ethereum
.request({
method: 'eth_requestAccounts'
})
.then(handleAccountsChanged)
.catch((error) => {
if (error.code === 4001) {
// EIP-1193 userRejectedRequest error
console.log('Please connect to MetaMask.');
} else {
console.error(error);
}
});
}
</script>
</body>
</html>
Add more functionality
Although this code allows us to already connect the page to MetaMask, we can add some functionality. For example, prompt the user to switch to the network used by our DApp.
In this case, I'll show you how to prompt the user to switch to the Polygon network, and if the network is not configured in the user's MetaMask, prompt to add it.
We just need a couple of additions. First, add a button above the connect
button.
<button onclick="switchNetwork()">Switch to Polygon</button>
This button will call the switchNetwork()
function, which we'll code in the next step. Also, find the reference code in the MetaMask docs.
Inside the <script>
tag add this function:
async function switchNetwork() {
try {
// Prompt user to switch to Polygon
await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{
chainId: '0x89' // Note that the chainId must be an HEX number starting with 0x.
}],
});
} catch (switchError) {
// This error code indicates that the chain has not been added to MetaMask.
if (switchError.code === 4902) {
try {
// Prompt user to add Polygon to MetaMask if not already configured
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0x89',
chainName: 'Polygon mainnet',
rpcUrls: ['https://polygon-rpc.com/'] /* ... */ ,
}, ],
});
} catch (addError) {
// handle "add" error
}
}
// handle other "switch" errors
}
}
When clicking the Switch to Polygon
button, MetaMask will prompt you to change the network or add it in case you don't have it.
Full code
Here is the full HTML file with both buttons and functions.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="./style.css" />
<title>Connect MetaMask</title>
</head>
<body>
<div class="parent">
<div class="div1">
<h1 class="center">Connect MetaMask to a webpage</h1>
<h2 class="center">This page shows you how to connect MetaMask to a webpage to create a DApp!</h2>
<h3 class="center">Check the source code in the <a href="https://github.com/soos3d/connect-metamask-to-webpage" target="_blank">GitHub repo</a>.</h3>
<p class="center">Click the button to prompt MetaMask to connect</p>
</div>
<div class="div2">
<h3>Click the button to connect MetaMask to the website</h3>
<button onclick="switchNetwork()">Switch to Polygon</button>
<button onclick="connect()">Connect Wallet</button>
</div>
</div>
<script>
// Identify the accounts and connect MetaMask to the website.
function connect() {
ethereum
.request({
method: 'eth_requestAccounts'
})
.then(handleAccountsChanged)
.catch((error) => {
if (error.code === 4001) {
// EIP-1193 userRejectedRequest error
console.log('Please connect to MetaMask.');
} else {
console.error(error);
}
});
}
async function switchNetwork() {
try {
// Prompt user to switch to Polygon
await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{
chainId: '0x89'
}],
});
} catch (switchError) {
// This error code indicates that the chain has not been added to MetaMask.
if (switchError.code === 4902) {
try {
// Prompt user to add Polygon to MetaMask if not already configured
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0x89',
chainName: 'Polygon mainnet',
rpcUrls: ['https://polygon-rpc.com/'] /* ... */ ,
}, ],
});
} catch (addError) {
// handle "add" error
}
}
// handle other "switch" errors
}
}
</script>
</body>
</html>
Conclusion
Congrats on going through this and learning how to work with MetaMask! Use this as a base to create your decentralized application.