React Integration Guide
Section titled “React Integration Guide”This guide will walk you through the process of integrating the Wallet SDK into your React application. By the end, you’ll have a basic setup that allows users to connect their Frak Wallet and perform simple interactions.
Prerequisites
Section titled “Prerequisites”Before you begin, ensure that:
- You have a React project set up.
- You have a merchant account on the Frak business dashboard with your storefront’s domain registered. The main domain is registered automatically at sign-up; for subdomains, add them under Allowed Domains on the dashboard.
If you haven’t completed these steps, please refer to the Getting Started guide.
Step 1: Install Dependencies
Section titled “Step 1: Install Dependencies”First, install the required packages:
npm install @frak-labs/react-sdk @tanstack/react-queryyarn add @frak-labs/react-sdk @tanstack/react-querypnpm add @frak-labs/react-sdk @tanstack/react-querybun add @frak-labs/react-sdk @tanstack/react-queryStep 2: Set Up the Frak Client
Section titled “Step 2: Set Up the Frak Client”Create a new component to set up the Frak client and iframe:
import { import FrakConfigProvider
FrakConfigProvider, import FrakIFrameClientProvider
FrakIFrameClientProvider,} from "@frak-labs/react-sdk";import { class QueryClient
QueryClient, const QueryClientProvider: ({ client, children, }: QueryClientProviderProps) => React.JSX.Element
QueryClientProvider } from "@tanstack/react-query";import type { type PropsWithChildren<P = unknown> = P & { children?: React.ReactNode | undefined;}
PropsWithChildren } from "react";
const const queryClient: QueryClient
queryClient = new new QueryClient(config?: QueryClientConfig): QueryClient
QueryClient();
const const frakConfig: { metadata: { name: string; };}
frakConfig = { metadata: { name: string;}
metadata: { name: string
name: "Your App Name", }, // The domain will be automatically set to window.location.host};
export function function FrakProvider({ children }: PropsWithChildren): React.JSX.Element
FrakProvider({ children: React.ReactNode
children }: type PropsWithChildren<P = unknown> = P & { children?: React.ReactNode | undefined;}
PropsWithChildren) { return ( <const QueryClientProvider: ({ client, children, }: QueryClientProviderProps) => React.JSX.Element
QueryClientProvider client: QueryClient
client={const queryClient: QueryClient
queryClient}> <import FrakConfigProvider
FrakConfigProvider config: { metadata: { name: string; };}
config={const frakConfig: { metadata: { name: string; };}
frakConfig}> <import FrakIFrameClientProvider
FrakIFrameClientProvider>{children: React.ReactNode
children}</import FrakIFrameClientProvider
FrakIFrameClientProvider> </import FrakConfigProvider
FrakConfigProvider> </const QueryClientProvider: ({ client, children, }: QueryClientProviderProps) => React.JSX.Element
QueryClientProvider> );}Wrap your main App component with this provider:
import { import FrakProvider
FrakProvider } from './FrakProvider';
function function App(): any
App() { return ( <import FrakProvider
FrakProvider> {/* Your app content */} </import FrakProvider
FrakProvider> );}
export default function App(): any
App;For more detailed configuration options, see FrakWalletSdkConfig.
Step 3: Check Wallet Status
Section titled “Step 3: Check Wallet Status”Create a component to check and display the wallet status using the useWalletStatus hook:
/** * Simple wallet status component */function function WalletStatus(): any
Simple wallet status component
WalletStatus() { const { any
data: const walletStatus: any
walletStatus, const isLoading: any
isLoading, const error: any
error } = any
useWalletStatus();
if (const isLoading: any
isLoading) return <any
div>Loading wallet status...</any
div>; if (const error: any
error) return <any
div>Error: {const error: any
error.any
message}</any
div>;
return ( <any
div> Wallet status:{" "} {const walletStatus: any
walletStatus?.any
key === "connected" ? "Connected" : "Not connected"} </any
div> );}Step 4: Implement Login Modal
Section titled “Step 4: Implement Login Modal”Create a component for the login modal, using the useDisplayModal hook:
/** * Simple login with frak button */function function LoginButton(): any
Simple login with frak button
LoginButton() { const { any
mutate: const displayModal: any
displayModal, const isPending: any
isPending } = any
useDisplayModal();
const const handleLogin: () => void
handleLogin = () => { const displayModal: any
displayModal({ steps: { login: {};}
steps: { login: {}
login: {}, }, metadata: { i18n: { "sdk.modal.login.description": string; };}
metadata: { i18n: { "sdk.modal.login.description": string;}
i18n: { "sdk.modal.login.description": "Login with Frak to receive up to {{ estimatedReward }}!", }, }, }); };
return ( <any
button onClick: () => void
onClick={const handleLogin: () => void
handleLogin} disabled: any
disabled={const isPending: any
isPending} type: string
type={"button"}> {const isPending: any
isPending ? "Logging in..." : "Login with Frak"} </any
button> );}Step 5: Put It All Together
Section titled “Step 5: Put It All Together”Update your main App component to include the wallet status and login button:
function function App(): any
App() { return ( <any
FrakProvider> <any
h1>My Frak Powered app</any
h1> <any
WalletStatus /> <any
LoginButton /> </any
FrakProvider> );}export default function App(): any
App;import { import useDisplayModal
useDisplayModal, import useWalletStatus
useWalletStatus } from "@frak-labs/react-sdk";import { import FrakProvider
FrakProvider } from "./FrakProvider";
function function App(): any
App() { return ( <import FrakProvider
FrakProvider> <any
h1>My Frak Powered app</any
h1> <function WalletStatus(): any
Simple wallet status component
WalletStatus /> <function LoginButton(): any
Simple login with frak button
LoginButton /> </import FrakProvider
FrakProvider> );}export default function App(): any
App;
/** * Simple wallet status component */function function WalletStatus(): any
Simple wallet status component
WalletStatus() { const { any
data: const walletStatus: any
walletStatus, const isLoading: any
isLoading, const error: any
error } = import useWalletStatus
useWalletStatus();
if (const isLoading: any
isLoading) return <any
div>Loading wallet status...</any
div>; if (const error: any
error) return <any
div>Error: {const error: any
error.any
message}</any
div>;
return ( <any
div> Wallet status:{" "} {const walletStatus: any
walletStatus?.any
key === "connected" ? "Connected" : "Not connected"} </any
div> );}
/** * Simple login with frak button */function function LoginButton(): any
Simple login with frak button
LoginButton() { const { any
mutate: const displayModal: any
displayModal, const isPending: any
isPending } = import useDisplayModal
useDisplayModal();
const const handleLogin: () => void
handleLogin = () => { const displayModal: any
displayModal({ steps: { login: {};}
steps: { login: {}
login: {}, }, metadata: { i18n: { "sdk.modal.login.description": string; };}
metadata: { i18n: { "sdk.modal.login.description": string;}
i18n: { "sdk.modal.login.description": "Login with Frak to receive up to {{ estimatedReward }}!", }, }, }); };
return ( <any
button onClick: () => void
onClick={const handleLogin: () => void
handleLogin} disabled: any
disabled={const isPending: any
isPending} type: string
type={"button"}> {const isPending: any
isPending ? "Logging in..." : "Login with Frak"} </any
button> );}import { import FrakConfigProvider
FrakConfigProvider, import FrakIFrameClientProvider
FrakIFrameClientProvider,} from "@frak-labs/react-sdk";import { class QueryClient
QueryClient, const QueryClientProvider: ({ client, children, }: QueryClientProviderProps) => React.JSX.Element
QueryClientProvider } from "@tanstack/react-query";import type { type PropsWithChildren<P = unknown> = P & { children?: React.ReactNode | undefined;}
PropsWithChildren } from "react";
const const queryClient: QueryClient
queryClient = new new QueryClient(config?: QueryClientConfig): QueryClient
QueryClient();
const const frakConfig: { metadata: { name: string; };}
frakConfig = { metadata: { name: string;}
metadata: { name: string
name: "Your App Name", }, // The domain will be automatically set to window.location.host};
export function function FrakProvider({ children }: PropsWithChildren): React.JSX.Element
FrakProvider({ children: React.ReactNode
children }: type PropsWithChildren<P = unknown> = P & { children?: React.ReactNode | undefined;}
PropsWithChildren) { return ( <const QueryClientProvider: ({ client, children, }: QueryClientProviderProps) => React.JSX.Element
QueryClientProvider client: QueryClient
client={const queryClient: QueryClient
queryClient}> <import FrakConfigProvider
FrakConfigProvider config: { metadata: { name: string; };}
config={const frakConfig: { metadata: { name: string; };}
frakConfig}> <import FrakIFrameClientProvider
FrakIFrameClientProvider>{children: React.ReactNode
children}</import FrakIFrameClientProvider
FrakIFrameClientProvider> </import FrakConfigProvider
FrakConfigProvider> </const QueryClientProvider: ({ client, children, }: QueryClientProviderProps) => React.JSX.Element
QueryClientProvider> );}Next Steps
Section titled “Next Steps”With this setup, you have a basic React application integrated with the Wallet SDK. Users can now connect their Frak Wallet and log in. From here, you can start implementing more advanced features such as:
- Sending interactions
- Implementing referral systems
- Creating reward campaigns
Refer to the specific action and hook documentation for details on implementing these features.