Headless SDK setup
Install the SDK, wrap your app in the provider, mint a participant token, and start rendering points, tier, and challenges from real data. Five minutes from npm install to first hook.
Key takeaways
Quick read- Wrap the app in BricqsProvider once. Every hook reads from this context.
- Mint participant tokens server-side. Never put admin keys in client code.
- Pass the env explicitly. Mixing test and live keys is the most common foot-gun.
- All hooks ship loading and error states. Render skeletons; do not block on them.
- Use the same provider for SSR. The SDK hydrates safely.
Install
Add the package
npm install @bricqs/headless-react
# or
pnpm add @bricqs/headless-react
yarn add @bricqs/headless-reactProvider
Wrap your app once
The provider sits at the root of your tree. All hooks read from it.
"use client";
import { BricqsProvider } from "@bricqs/headless-react";
export function Providers({
children,
participantToken,
}: {
children: React.ReactNode;
participantToken: string;
}) {
return (
<BricqsProvider
tenantId={process.env.NEXT_PUBLIC_BRICQS_TENANT!}
participantToken={participantToken}
env={process.env.NEXT_PUBLIC_BRICQS_ENV as "production" | "test"}
// optional: override the API base URL for self-hosted deployments
// apiBaseUrl="https://your-bricqs-instance.com"
>
{children}
</BricqsProvider>
);
}Auth
Mint participant tokens server-side
The participant token is the only thing the client sees. It expires; refresh from the server.
import { cookies } from "next/headers";
export async function POST() {
const userId = await getCurrentUserId(); // your auth
if (!userId) return new Response("Unauthorized", { status: 401 });
// Trade your server-side admin key for a short-lived participant token.
const res = await fetch("https://api.bricqs.co/api/v1/auth/participant-token", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.BRICQS_ADMIN_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ participant_id: userId, ttl_seconds: 3600 }),
});
const { token } = await res.json();
cookies().set("bq_token", token, {
httpOnly: true,
sameSite: "lax",
maxAge: 3600,
path: "/",
});
return new Response(JSON.stringify({ ok: true }));
}Never expose the admin key to the browser. The participant token is scoped to one user and expires inside an hour.
Environments
Live and test keys
Test environment
Test keys (bq_test_...) and a separate tenant. Free to mutate. Most teams use this for staging and CI.
Production environment
Live keys (bq_live_...). Real points, real rewards, real liability. Restrict admin keys to the smallest possible team.
# Public (browser-visible). Tenant ID is safe to expose.
NEXT_PUBLIC_BRICQS_TENANT=tenant_brand_xyz
NEXT_PUBLIC_BRICQS_ENV=production
# Server-only. Never prefix with NEXT_PUBLIC_.
BRICQS_ADMIN_KEY=bq_live_aV7p...First hook
Render points in 10 lines
"use client";
import { usePoints } from "@bricqs/headless-react";
export function PointsBadge() {
const { available, lifetime, isLoading, error } = usePoints();
if (error) return <span className="text-red-500">Could not load points</span>;
if (isLoading) return <span className="opacity-50">Loading...</span>;
return (
<span className="inline-flex items-center gap-2">
<strong>{available.toLocaleString()}</strong> pts
<small className="text-slate-500">
(lifetime {lifetime.toLocaleString()})
</small>
</span>
);
}SSR notes
Server components and hydration
The SDK is client-only. Use it inside Client Components. The provider safely hydrates so initial render is consistent.
import { Providers } from "./providers";
import { getParticipantToken } from "@/lib/auth";
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const token = await getParticipantToken(); // server-side
return (
<html lang="en">
<body>
<Providers participantToken={token}>{children}</Providers>
</body>
</html>
);
}The token is fetched server-side and passed in as a prop. The Provider is the only client boundary; everything else can stay server-rendered.
Common mistakes
What goes wrong on first integration
Putting the admin key in client env (NEXT_PUBLIC_BRICQS_KEY).
Admin keys are server-only. Mint short-lived participant tokens in a server route and pass them to the Provider.
Mixing test and live keys across environments.
Use a separate tenant for test. Keep BRICQS_ENV in .env and assert it on every server boot.
Calling hooks outside the Provider.
Wrap the entire authenticated app in BricqsProvider. Hooks throw if no provider is found.
Blocking the entire page on isLoading.
Render skeletons for points, tier, badges. The hooks return data within 200 to 400ms; UX is better with a placeholder than a spinner.
Forgetting to refresh the participant token before it expires.
Call your /api/bricqs/token route on app focus or via setInterval at 80 percent of TTL. The Provider exposes a refreshToken hook for this.
Developer FAQ
Common questions when integrating gamification with Bricqs.
Ready to ship?
Wire it up with the Bricqs SDK or API
Headless SDK for React UIs, REST API for any backend. Same engine behind both.
