Skip to main content

Next.js

Web3Modal SDK has support for Wagmi and Ethers v6. Choose one of these ethereum libraries to get started.

Note

These steps are specific to Next.js app router.

Installation

npm install @web3modal/wagmi wagmi viem @tanstack/react-query

Don't have a project ID?

Head over to WalletConnect Cloud and create a new project now!

Get startedcloud illustration

Implementation

You can start Web3Modal configuration using either default or custom mode.

Default mode will implement WalletConnect, Browser Wallets (injected) and Coinbase options in addition to the WalletConnect's provider.

Create a new file called config/index.tsx or config/index.jsx (outside your app directory) and set up the following configuration

import { defaultWagmiConfig } from '@web3modal/wagmi/react/config'

import { cookieStorage, createStorage } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'

// Get projectId at https://cloud.walletconnect.com
export const projectId = process.env.NEXT_PUBLIC_PROJECT_ID

if (!projectId) throw new Error('Project ID is not defined')

const metadata = {
name: 'Web3Modal',
description: 'Web3Modal Example',
url: 'https://web3modal.com', // origin must match your domain & subdomain
icons: ['https://avatars.githubusercontent.com/u/37784886']
}

// Create wagmiConfig
export const config = defaultWagmiConfig({
chains: [mainnet, sepolia], // required
projectId, // required
metadata, // required
ssr: true,
storage: createStorage({
storage: cookieStorage
}),
enableWalletConnect: true, // Optional - true by default
enableInjected: true, // Optional - true by default
enableEIP6963: true, // Optional - true by default
enableCoinbase: true, // Optional - true by default
...wagmiOptions // Optional - Override createConfig parameters
})
info

Notice that defaultWagmiConfig is now imported from '@web3modal/wagmi/react/config'

Create another file called context/index.tsx or context/index.jsx (outside your app directory) and set up the following configuration, making sure that all functions are called outside any React component to avoid unwanted rerenders.

'use client'

import React, { ReactNode } from 'react'
import { config, projectId } from '@/config'

import { createWeb3Modal } from '@web3modal/wagmi/react'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

import { State, WagmiProvider } from 'wagmi'

// Setup queryClient
const queryClient = new QueryClient()

if (!projectId) throw new Error('Project ID is not defined')

// Create modal
createWeb3Modal({
wagmiConfig: config,
projectId,
enableAnalytics: true // Optional - defaults to your Cloud configuration
})

export function ContextProvider({
children,
initialState
}: {
children: ReactNode
initialState?: State
}) {
return (
<WagmiProvider config={config} initialState={initialState}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</WagmiProvider>
)
}

Next, in your app/layout.tsx or app/layout.jsx file, import the custom Web3Modal component and call cookieToInitialState

import './globals.css'
import type { Metadata } from 'next'
import { headers } from 'next/headers'

import { cookieToInitialState } from 'wagmi'

import { config } from '@/config'
import { ContextProvider } from '@/context'

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app'
}

export default function RootLayout({
children
}: Readonly<{
children: React.ReactNode
}>) {
const initialState = cookieToInitialState(config, headers().get('cookie'))
return (
<html lang="en">
<body>
<ContextProvider initialState={initialState}>{children}</ContextProvider>
</body>
</html>
)
}
info

createWeb3Modal must be called inside a client file, apart from Wagmi's configuration.

Trigger the modal

To open Web3Modal you can use our default web components or build your own logic using Web3Modal hooks.

export default function ConnectButton() {
return <w3m-button />
}

Learn more about the Web3Modal web components here

note

Web components are global html elements that don't require importing.

Smart Contract Interaction

import { useReadContract } from 'wagmi'
import { USDTAbi } from '../abi/USDTAbi'

const USDTAddress = '0x...'

function App() {
const result = useReadContract({
abi: USDTAbi,
address: USDTAddress,
functionName: 'totalSupply'
})
}

Read more about Wagmi hooks for smart contract interaction here.

Extra configuration

Next.js relies on SSR. This means some specific steps are required to make Web3Modal work properly.

  • Add the following code in the next.config.js file
// Path: next.config.js
const nextConfig = {
webpack: config => {
config.externals.push('pino-pretty', 'lokijs', 'encoding')
return config
}
}