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-plugin
pnpm add @swapkit/sdk node-polyfill-webpack-plugin
npm install @swapkit/sdk node-polyfill-webpack-plugin
yarn add @swapkit/sdk node-polyfill-webpack-plugin
Additional polyfill dependencies:
bun add buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserify
pnpm add buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserify
npm install buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserify
yarn add buffer crypto-browserify stream-browserify stream-http https-browserify os-browserify path-browserify
Next.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_here
Server 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: