Next.js
This guide will help you integrate SwapKit into your Next.js application with proper Node.js polyfills and WebAssembly support.
đ Next.js Playground Ready!
Skip the setup and start building immediately with our configured Next.js environment
Official Playgrounds
Online IDEs
Installation
Section titled âInstallationâInstall SwapKit and required dependencies:
bun add @swapkit/sdk node-polyfill-webpack-pluginpnpm add @swapkit/sdk node-polyfill-webpack-pluginnpm install @swapkit/sdk node-polyfill-webpack-pluginyarn add @swapkit/sdk node-polyfill-webpack-pluginAdditional polyfill dependencies:
bun add buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserifypnpm add buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserifynpm install buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserifyyarn add buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserifyNext.js Configuration
Section titled âNext.js ConfigurationâUpdate your next.config.mjs to include necessary polyfills and WebAssembly support:
import { createRequire } from "module";import NodePolyfillPlugin from "node-polyfill-webpack-plugin";
const require = createRequire(import.meta.url);
/** @type {import('next').NextConfig} */const nextConfig = { reactStrictMode: true,
webpack: (config, { isServer, webpack }) => { if (!isServer) { config.plugins.push(new NodePolyfillPlugin());
config.plugins.push( new webpack.ProvidePlugin({ global: require.resolve("global"), process: "process/browser", Buffer: ["buffer", "Buffer"], }) );
config.plugins.push( new webpack.DefinePlugin({ "global.crypto": "crypto", "global.msCrypto": "crypto", "global.process": "process", "global.Buffer": "Buffer", }) );
config.resolve.fallback = { ...config.resolve.fallback, buffer: require.resolve("buffer"), crypto: require.resolve("crypto-browserify"), fs: false, stream: require.resolve("stream-browserify"), path: require.resolve("path-browserify"), process: require.resolve("process/browser"), };
config.resolve.alias = { ...config.resolve.alias, crypto: require.resolve("crypto-browserify"), path: require.resolve("path-browserify"), process: require.resolve("process/browser"), stream: require.resolve("stream-browserify"), http: require.resolve("stream-http"), https: require.resolve("https-browserify"), os: require.resolve("os-browserify/browser"), }; }
config.experiments = { ...config.experiments, asyncWebAssembly: true, syncWebAssembly: true, topLevelAwait: true, };
return config; },};
export default nextConfig;Package.json Browser Field
Section titled âPackage.json Browser FieldâAdd browser field to your package.json to handle Node.js modules:
{ "browser": { "dns": false, "fs": false, "net": false, "perf_hooks": false, "stream": false, "timers": false, "tls": false, "zlib": false }}SwapKit Setup
Section titled âSwapKit SetupâCreate a SwapKit instance configuration:
// @noErrorValidation
import { createSwapKit } from "@swapkit/sdk";import { SKConfig } from "@swapkit/sdk";
if (process.env.NEXT_PUBLIC_SWAPKIT_API_KEY) { SKConfig.setApiKey("swapKit", process.env.NEXT_PUBLIC_SWAPKIT_API_KEY);}
if (process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID) { SKConfig.setApiKey( "walletConnectProjectId", process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID );}
export const swapKitClient = createSwapKit();React Component with App Router
Section titled âReact Component with App RouterâCreate a client component for wallet interactions:
"use client";
import { useState } from "react";import { swapKitClient } from "@/lib/swapKit";import { Chain, WalletOption } from "@swapkit/sdk";
export function WalletButton() { const [isConnected, setIsConnected] = useState(false); const [address, setAddress] = useState<string>(""); const [isLoading, setIsLoading] = useState(false);
const connectWallet = async () => { setIsLoading(true); try { await swapKitClient.connectEVMWallet( [Chain.Ethereum], WalletOption.METAMASK );
setIsConnected(true); const ethAddress = await swapKitClient.getAddress(Chain.Ethereum); setAddress(ethAddress); } catch (error) { console.error("Failed to connect wallet:", error); } finally { setIsLoading(false); } };
const disconnectWallet = () => { swapKitClient.disconnectWallet(Chain.Ethereum); setIsConnected(false); setAddress(""); };
if (isConnected) { return ( <div> <p> Connected: {address.slice(0, 6)}...{address.slice(-4)} </p> <button onClick={disconnectWallet}>Disconnect</button> </div> ); }
return ( <button onClick={connectWallet} disabled={isLoading}> {isLoading ? "Connecting..." : "Connect Wallet"} </button> );}Context Provider Pattern
Section titled âContext Provider PatternâFor more complex applications, use a context provider:
"use client";
import { createContext, useContext, ReactNode } from "react";import { SwapKit } from "@swapkit/sdk";import { swapKitClient } from "@/lib/swapKit";
const SwapKitContext = createContext<SwapKit | null>(null);
export function SwapKitProvider({ children }: { children: ReactNode }) { return ( <SwapKitContext.Provider value={swapKitClient}> {children} </SwapKitContext.Provider> );}
export function useSwapKit() { const context = useContext(SwapKitContext); if (!context) { throw new Error("useSwapKit must be used within SwapKitProvider"); } return context;}Use in your root layout:
import { SwapKitProvider } from "@/providers/SwapKitProvider";
export default function RootLayout({ children,}: { children: React.ReactNode;}) { return ( <html lang="en"> <body> <SwapKitProvider>{children}</SwapKitProvider> </body> </html> );}Environment Variables
Section titled âEnvironment VariablesâCreate a .env.local file:
NEXT_PUBLIC_SWAPKIT_API_KEY=your_api_key_hereNEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id_hereServer Components Considerations
Section titled âServer Components ConsiderationsâSwapKit operations that require wallet connections must be performed in client components. For server components, you can only use read-only operations:
import { AssetValue, SwapKitApi } from "@swapkit/sdk";
export async function TokenPrice({ symbol }: { symbol: string }) { const price = await SwapKitApi.getPrice({ identifier: symbol, currency: "USD", });
return <div>Price: ${price.price_usd}</div>;}Cosmos Wallets Integration
Section titled âCosmos Wallets IntegrationâFor Cosmos ecosystem wallets like Keplr and Cosmostation, create a specialized component:
"use client";
import { useState } from "react";import { swapKitClient } from "@/lib/swapKit";import { Chain, WalletOption } from "@swapkit/sdk";
export function CosmosWalletButton() { const [isConnected, setIsConnected] = useState(false); const [addresses, setAddresses] = useState<Record<string, string>>({}); const [isLoading, setIsLoading] = useState(false);
const connectCosmostation = async () => { setIsLoading(true); try { await swapKitClient.connectCosmostation([ Chain.Cosmos, Chain.THORChain, Chain.Kujira, ]);
setIsConnected(true); const chains = [Chain.Cosmos, Chain.THORChain, Chain.Kujira]; const newAddresses: Record<string, string> = {};
for (const chain of chains) { try { const address = await swapKitClient.getAddress(chain); if (address) { newAddresses[chain] = address; } } catch {} }
setAddresses(newAddresses); } catch (error) { console.error("Failed to connect Cosmostation:", error); } finally { setIsLoading(false); } };
const disconnectWallet = () => { Object.keys(addresses).forEach((chain) => { swapKitClient.disconnectWallet(chain as Chain); }); setIsConnected(false); setAddresses({}); };
if (isConnected) { return ( <div className="space-y-2"> <h3>Connected Cosmos Chains:</h3> {Object.entries(addresses).map(([chain, address]) => ( <p key={chain}> {chain}: {address.slice(0, 8)}...{address.slice(-6)} </p> ))} <button onClick={disconnectWallet}>Disconnect</button> </div> ); }
return ( <button onClick={connectCosmostation} disabled={isLoading}> {isLoading ? "Connecting..." : "Connect Cosmostation"} </button> );}Common Issues
Section titled âCommon IssuesâWebAssembly errors
Section titled âWebAssembly errorsâThe webpack configuration should handle WebAssembly modules. If issues persist, check that experiments.asyncWebAssembly is enabled in your next.config.js.
Example Repository
Section titled âExample RepositoryâFor a complete working example, check out the [Next.js playground](https: