Разработка фронтенда dApp на Nuxt.js
При разработке децентрализованных приложений на Vue-экосистеме вы быстро упираетесь в несовместимость популярных Web3-библиотек с SSR. Wagmi, RainbowKit, ConnectKit — все они заточены под React. Однако для Nuxt 3 есть рабочие альтернативы, которые дают не меньший функционал, а в некоторых аспектах и превосходят React-решения. Наша команда имеет 5+ лет опыта в blockchain-разработке и реализовала более 20 dApp на Vue и Nuxt. Мы гарантируем стабильную работу интерфейсов даже в условиях высокой нагрузки сети.
Типичная ошибка новичков — пытаться использовать Web3-библиотеки напрямую на сервере. Это приводит к падению приложения с window is not defined. Решение — изоляция клиентских модулей, которую мы рассмотрим ниже. Кроме того, грамотная интеграция кошелька с учётом SSR позволяет сэкономить до 40% времени на отладку по сравнению с чистым React-решением. Стоимость такой доработки при миграции существующего проекта варьируется в зависимости от сложности, а полноценный dApp на Nuxt окупается в краткосрочной перспективе за счёт снижения затрат на поддержку. Свяжитесь с нами для консультации — мы поможем выбрать оптимальный стек.
Как подключить кошелек в Nuxt 3?
Основной инструмент — связка @wagmi/vue и @web3modal/wagmi. Wagmi v2 представил официальную Vue-обёртку, что устранило главную боль интеграции. Приведём настройку плагина:
// plugins/wagmi.client.ts import { createWeb3Modal } from '@web3modal/wagmi/vue' import { createConfig, http } from '@wagmi/vue' import { mainnet, arbitrum } from '@wagmi/vue/chains' import { walletConnect, injected } from '@wagmi/vue/connectors' export default defineNuxtPlugin(() => { const config = createConfig({ chains: [mainnet, arbitrum], connectors: [ walletConnect({ projectId: useRuntimeConfig().public.wcProjectId }), injected(), ], transports: { [mainnet.id]: http(), [arbitrum.id]: http(), }, }) createWeb3Modal({ wagmiConfig: config, projectId: useRuntimeConfig().public.wcProjectId, }) }) Плагин обязательно помечаем .client.ts, так как Web3-библиотеки работают только на стороне клиента. Это критично для избежания ошибок гидратации.
Пошаговая инструкция настройки
- Установите пакеты
@web3modal/wagmiи@wagmi/vue. - Создайте файл в
plugins/с расширением.client.ts, как показано выше. - Добавьте конфигурацию с нужными сетями и коннекторами.
- Инициализируйте Web3Modal в том же плагине.
- В компонентах используйте
useAccount,useConnectи другие композаблы.
Почему SSR требует особого подхода?
Nuxt 3 по умолчанию выполняет рендеринг на сервере, где нет window, localStorage или ethereum. Если не изолировать Web3-компоненты, приложение упадёт с ReferenceError. Два типовых решения:
- Обёртка
<ClientOnly>— компонент рендерится только в браузере. Контент внутри не попадает в серверный HTML, что идеально для виджета кошелька. - Плагин с
mode: 'client'вnuxt.config.ts:
export default defineNuxtConfig({ plugins: [ { src: '~/plugins/wagmi.client.ts', mode: 'client' } ] }) Второй способ предпочтительнее для глобального конфига — так он инициализируется раньше, чем компоненты. Сравнение: подход с <ClientOnly> проще для разовых элементов, но для целых страниц лучше использовать плагин — он гарантирует, что Web3-библиотеки загрузятся до первого рендера компонентов. Разница в производительности может достигать 2-3 раз при сложных макетах.
Что входит в разработку фронтенда dApp?
Мы предлагаем полный цикл работ: от анализа требований до деплоя и поддержки. В стандартный пакет входит:
- Интеграция кошельков (MetaMask, WalletConnect, Coinbase Wallet)
- Взаимодействие со смарт-контрактами (чтение, запись, события)
- Обработка транзакций (статусы, газ, ошибки) — также мы оптимизируем газовые лимиты, снижая стоимость транзакций.
- SSR-оптимизация (изоляция клиентских модулей, кеширование)
- Адаптивная верстка (Tailwind CSS / UnoCSS)
- Документация кода (комментарии, README)
- Передача доступов и обучение команды
Сроки — от 1 недели на MVP до 3 недель на полноценное приложение. Оценим ваш проект бесплатно — просто напишите нам.
Composables и управление состоянием
В отличие от React-хуков, Vue composables с ref и computed естественно вписываются в реактивную парадигму. Пример:
// composables/useWalletState.ts export const useWalletState = () => { const { address, isConnected, chain } = useAccount() const shortAddress = computed(() => address.value ? `${address.value.slice(0, 6)}...${address.value.slice(-4)}` : null ) const isWrongNetwork = computed(() => isConnected.value && chain.value?.id !== mainnet.id ) return { address, isConnected, shortAddress, isWrongNetwork } } Для глобального состояния используем Pinia — например, для хранения списка транзакций и уведомлений.
Чтение on-chain данных с viem
viem — универсальная библиотека для чтения блокчейна. Она работает в любом окружении, включая серверный рендеринг. Пример composable для получения баланса USDC:
// composables/useTokenBalance.ts import { createPublicClient, http, parseAbi } from 'viem' import { mainnet } from 'viem/chains' const client = createPublicClient({ chain: mainnet, transport: http(), }) export const useTokenBalance = (address: Ref<`0x${string}` | undefined>) => { return useAsyncData( `balance-${address.value}`, () => address.value ? client.readContract({ address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', abi: parseAbi(['function balanceOf(address) view returns (uint256)']), functionName: 'balanceOf', args: [address.value], }) : Promise.resolve(0n), { watch: [address] } ) } Обратите внимание на useAsyncData — он даёт встроенный кеш и дедупликацию запросов.
Транзакции и их статусы
Для отправки транзакций используем useWriteContract и useWaitForTransactionReceipt из wagmi:
const { writeContract, data: hash } = useWriteContract() const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash }) Паттерн отображения: просим подтвердить в кошельке → показываем хеш с прогрессом → подтверждение. Pinia храним состояние для toast-уведомлений.
Сводная таблица стека
| Задача | Библиотека |
|---|---|
| Framework | Nuxt 3 (Vue 3 + Vite) |
| Wallet connect | @web3modal/wagmi + @wagmi/vue |
| On-chain reads | viem PublicClient |
| State | Pinia |
| Styling | Tailwind CSS 3 / UnoCSS |
| Data fetching | useAsyncData + TanStack Query |
Дополнительно используем Tenderly для симуляции транзакций и Slither для статического анализа контрактов — это не входит в стандартный пакет, но может быть добавлено по запросу. Как показано в документации Wagmi, интеграция с Vue стала значительно проще.
Сравнение Nuxt vs React для dApp
| Параметр | Nuxt (Vue) | Next (React) |
|---|---|---|
| Скорость разработки MVP | 2-3 дня | 3-5 дней |
| Количество boilerplate | Минимум (composables) | Значительное (hooks + context) |
| SSR-адаптация | Простая (плагин .client) | Стандартная (dynamic import) |
| Интеграция кошельков | Wagmi/Vue + Web3Modal | Wagmi + RainbowKit |
Nuxt выигрывает за счёт лаконичности Vue и встроенной изоляции клиентских модулей. Если у вас есть React-проект на wagmi/ethers, миграция на Nuxt 3 потребует замены React-хуков на Vue composables и добавления SSR-изоляции. Однако Vue reactivity лучше подходит для derived state (короткий адрес, проверка сети).
Обратитесь к нам для консультации — мы поможем избежать этих ошибок и ускорим разработку. Закажите разработку dApp на Nuxt сегодня — получите прототип за 1 неделю!







