Skip to main content

Next.js

AppKit has support for Wagmi and Ethers v6 on Ethereum and @solana/web3.js on Solana. Choose one of these Ethereum Libraries or 'Solana' to get started.

Note

These steps are specific to Next.js app router. For other React frameworks read the React documentation.

Installation

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

Cloud Configuration

Create a new project on WalletConnect Cloud at https://cloud.walletconnect.com and obtain a new project ID.

Don't have a project ID?

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

Get startedcloud illustration

Implementation

For a quick integration you can use defaultWagmiConfig function which wraps Wagmi's createConfig function with a predefined configuration. This includes WalletConnect, Coinbase and Injected connectors, and the Blockchain API as a transport

Wagmi config

Create a new file for your Wagmi configuration, since we are going to be calling this function on the client and the server it cannot live inside a file with the 'use client' directive.

For this example we will create a file called config/index.tsx outside our 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 from 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
const chains = [mainnet, sepolia] as const
export const config = defaultWagmiConfig({
chains,
projectId,
metadata,
ssr: true,
storage: createStorage({
storage: cookieStorage
}),
})
info
  • Notice that we are using here the recommended configuration from Wagmi for SSR.
  • Using cookies is completely optional and by default Wagmi will use localStorage instead if the storage param is not defined.
  • The ssr flag will delay the hydration of the Wagmi's store to avoid hydration mismatch errors.

Context Provider

Let's create now a context provider that will wrap our application and initialized Web3Modal (createWeb3Modal needs to be called inside a React Client Component file).

In this example we will create a file called context/index.tsx outside our app directory and set up the following configuration

'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
enableOnramp: true // Optional - false as default
})

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

Layout

Next, in our app/layout.tsx file, we will import our Web3ModalProvider component and call the Wagmi's function cookieToInitialState.

The initialState returned by cookieToInitialState, contains the optimistic values that will populate the Wagmi's store both on the server and client.

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

import { cookieToInitialState } from 'wagmi'

import { config } from '@/config'
import Web3ModalProvider 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>
<Web3ModalProvider initialState={initialState}>{children}</Web3ModalProvider>
</body>
</html>
)
}

Trigger the modal

To open Web3Modal you can use our web component or build your own button with Web3Modal hooks. In this example we are going to use the <w3m-button> component.

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

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

Learn more about the Web3Modal web components here

Smart Contract Interaction

Wagmi hooks can help us interact with wallets and smart contracts:

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
}
}