Read How the loader works first if you want to understand why the code is split this way. In short: the script loads once at the app root, and the widget attaches to whichever container is currently rendered.
Prerequisites
- React 18 or later.
- Your organization ID and campaign ID from Publish > Get embed code in the Claimr admin panel.
Set up the integration
1
Add environment variables
Create or update With Create React App, use the
.env in your project root. These values are public..env
REACT_APP_ prefix and read them from process.env instead of import.meta.env.2
Add the shared loader module
Create
src/lib/claimr.ts with the contents of the shared loader module. Copy it as is. It has no dependencies.3
Create the provider
The provider is the only place that loads the script and assigns callbacks. It turns SDK callbacks into React state.
src/claimr/ClaimrProvider.tsx
4
Create the widget component
The widget component only renders the container. The loader notices it and attaches the widget. When the component unmounts, the loader removes the widget on its own.
src/claimr/ClaimrWidget.tsx
5
Create the hook
src/claimr/useClaimr.ts
6
Wrap your app
Wrap the whole app once, above your router, so the script survives route changes.
src/main.tsx
7
Render the widget
Place With React Router, other routes simply do not render the container, and the loader detaches the widget when you leave this route.
ClaimrWidget on the page or route where the campaign should appear.src/pages/QuestsPage.tsx
Use the SDK from components
Call SDK methods through the hook. Methods that need a loaded widget are wrapped inwithWidget, so they are safe to call at any time.
complete_task only works for tasks configured as front-end tasks in the campaign. See SDK tasks.
To react to other widget events, add more callbacks in the provider’s setup function, for example claimr.on_leaderboard_open or claimr.on_analytics_event, and expose them through context. Do not assign callbacks from other components: each callback has a single owner, so the last assignment wins.
Sign users in with your own accounts
If your users already sign in to your app, give them a Claimr user token so they do not have to sign in again inside the widget.1
Generate the token on your server
Your API token is secret. Call the token endpoint from your backend, never from React code.Expose it through an authenticated endpoint of your own, for example
server/claimr-token.ts
GET /api/claimr-token, that reads the current user from the session. The token does not expire, so you can store it with the user record.2
Pass the token to the provider
Wrap
ClaimrProvider in a component that knows your signed-in user, and use it in main.tsx in place of the plain <ClaimrProvider>. It must render inside your auth provider.src/claimr/ClaimrAuthProvider.tsx
3
Log out of Claimr when the user logs out of your app
logout() before the new token reaches set_user_token.Connect the user’s wallet (dApps)
If your app already connects a wallet, let the widget use it instead of asking the user to connect again. Setplatform: 'dapp' in the provider config and implement on_wallet_request. This example uses wagmi and RainbowKit, and must render inside WagmiProvider and RainbowKitProvider.
src/claimr/ClaimrWalletBridge.tsx
Render
ClaimrWalletBridge inside ClaimrProvider and only after the provider reports loaded, for example {loaded && <ClaimrWalletBridge />}. That guarantees window.claimr exists when the handler is assigned.op must return a value or throw. Throwing reports a failure to the widget immediately, instead of leaving it waiting. See on_wallet_request for the full contract and Integrate Claimr widget into your dApp for the campaign settings a dApp needs.
Verify the integration
- Run the app and open the page with
ClaimrWidget. The campaign renders inside the container. - In the browser console, run
window.claimr.is_claimr_ready. It returnstrue. - Navigate to another route and back. The widget disappears and comes back, and
document.querySelectorAll('#claimr-script').lengthis still1. - Open a quest, then press the browser back button. The page still scrolls.
- If you use user tokens, sign in to your app and confirm the widget shows the same user without a second sign-in.
debug: true to the provider config. The loader then logs its steps to the console.