Інтеграція Web3Modal у фронтенд
Якщо вашому dApp потрібна підтримка декількох гаманців, не пишіть власний wallet selector з нуля. Web3Modal v3 від WalletConnect розв'язує це: 300+ гаманців, QR WalletConnect, мобільні deep link'и, email/соціальна авторизація через Web3Auth — всі готово до використання. Завдання інтеграції — правильно налаштувати конфіг та уникнути типових помилок з hydration та SSR.
Встановлення та базова конфігурація
npm install @web3modal/wagmi wagmi viem @tanstack/react-query
Отримайте свій Project ID на cloud.walletconnect.com. Без нього модалі запуститись, але WalletConnect з'єднання не працюватимуть.
// config/web3modal.ts
import { createWeb3Modal } from '@web3modal/wagmi/react'
import { defaultWagmiConfig } from '@web3modal/wagmi/react/config'
import { mainnet, arbitrum, base, polygon } from 'wagmi/chains'
const projectId = import.meta.env.VITE_WC_PROJECT_ID
const metadata = {
name: 'My dApp',
description: 'My dApp description',
url: 'https://mydapp.xyz', // має відповідати домену в WC Cloud
icons: ['https://mydapp.xyz/icon.png'],
}
export const config = defaultWagmiConfig({
chains: [mainnet, arbitrum, base, polygon],
projectId,
metadata,
})
createWeb3Modal({
wagmiConfig: config,
projectId,
enableAnalytics: true,
enableOnramp: true, // вбудований fiat on-ramp
themeMode: 'dark',
themeVariables: {
'--w3m-accent': '#7c3aed',
'--w3m-border-radius-master': '4px',
},
})
Інтеграція у React додаток
// main.tsx
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from './config/web3modal'
const queryClient = new QueryClient()
export function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<Router />
</QueryClientProvider>
</WagmiProvider>
)
}
Кнопка підключення — це готовий компонент або кастомний через hook:
// Готовий компонент
<w3m-button />
// Кастомна кнопка
import { useWeb3Modal } from '@web3modal/wagmi/react'
import { useAccount } from 'wagmi'
function ConnectWallet() {
const { open } = useWeb3Modal()
const { address, isConnected } = useAccount()
return (
<button onClick={() => open()}>
{isConnected ? `${address?.slice(0, 6)}...${address?.slice(-4)}` : 'Connect Wallet'}
</button>
)
}
Користувацькі мережі
Додавання мереж, яких немає в wagmi/chains:
import { defineChain } from 'viem'
const sonic = defineChain({
id: 146,
name: 'Sonic',
nativeCurrency: { name: 'Sonic', symbol: 'S', decimals: 18 },
rpcUrls: { default: { http: ['https://rpc.soniclabs.com'] } },
blockExplorers: { default: { name: 'SonicScan', url: 'https://sonicscan.org' } },
})
export const config = defaultWagmiConfig({
chains: [mainnet, sonic],
// ...
})
Перемикання мережі
Web3Modal автоматично показує перемикач мереж. Для програмного перемикання:
import { useWeb3Modal } from '@web3modal/wagmi/react'
const { open } = useWeb3Modal()
// Відкрити відразу на вкладці мереж
<button onClick={() => open({ view: 'Networks' })}>Switch Network</button>
SSR / Next.js
У Next.js App Router виникає проблема гідрації: Web3Modal ініціалізується на клієнті, але серверний рендер не знає про підключений гаманець. Розв'язання — 'use client' директива для провайдера та ліна ініціалізація:
// providers/Web3Provider.tsx
'use client'
import { createWeb3Modal } from '@web3modal/wagmi/react'
import { useEffect, useState } from 'react'
// Ініціалізація поза компонентом — виконується один раз
createWeb3Modal({ wagmiConfig: config, projectId })
export function Web3Provider({ children }: { children: React.ReactNode }) {
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{mounted ? children : null}
</QueryClientProvider>
</WagmiProvider>
)
}
Охорона mounted запобігає розбіжності гідрації — без неї React видає попередження про різницю між серверним та клієнтським рендером адреси гаманця.
Email та соціальна авторизація
Web3Modal підтримує вбудовані гаманці через Web3Auth. Увімкніть у конфігу:
createWeb3Modal({
// ...
featuredWalletIds: [], // видаліть рекомендовані гаманці, якщо хочете чистий UI
emailEnabled: true, // email OTP гаманець
})
Користувачі можуть авторизуватися через email або Google/GitHub — вони отримують non-custodial гаманець. Для широкої аудиторії без крипто-досвіду це значно знижує барʼєр входу.







