React
@guapocado/react gives React components a browser-safe Guapocado client.
Use it for reads:
- feature gates
- usage balance display
- limit display
- upgrade prompts
- account settings UI
Do not use it for server-key actions like checkout or usage consumption. Those belong in backend routes, server actions, or framework integrations.
Install
Section titled “Install”npm install @guapocado/reactProvider
Section titled “Provider”Wrap the part of your app that needs billing reads.
import { GuapocadoProvider } from "@guapocado/react";import type { ReactNode } from "react";
export function BillingProvider({ children, customerId,}: { children: ReactNode; customerId: string;}) { return ( <GuapocadoProvider apiKey={import.meta.env.VITE_GUAPOCADO_CLIENT_KEY} customerId={customerId} > {children} </GuapocadoProvider> );}Use a client key:
ck_guap_test_...ck_guap_live_...Never pass a server key to GuapocadoProvider.
Feature Hook
Section titled “Feature Hook”import { useEntitlement } from "@guapocado/react";
export function AnalyticsButton() { const analytics = useEntitlement("advanced-analytics");
if (analytics.loading) return <button disabled>Checking...</button>;
if (!analytics.has) { return <a href="/billing">Upgrade for analytics</a>; }
return <a href="/analytics">Open analytics</a>;}Usage Balance Hook
Section titled “Usage Balance Hook”import { useUsageBalance } from "@guapocado/react";
export function ApiUsage() { const apiCalls = useUsageBalance("api-calls");
if (apiCalls.loading) return <span>Loading usage...</span>;
return ( <span> {apiCalls.balance} API calls left </span> );}Limit Hook
Section titled “Limit Hook”import { useLimit } from "@guapocado/react";
export function SeatUsage({ activeSeats }: { activeSeats: number }) { const seats = useLimit("seats");
if (seats.loading || !seats.limit) return null;
return ( <span> {activeSeats} / {seats.limit} seats used </span> );}Direct Client Access
Section titled “Direct Client Access”Use useGuapocado() when a component needs the read-only client directly.
import { useGuapocado } from "@guapocado/react";
export function RefreshBillingState() { const guap = useGuapocado();
async function refresh() { const [analytics, usage, seats] = await Promise.all([ guap.has("advanced-analytics"), guap.usage.balance("api-calls"), guap.limit("seats"), ]);
console.log({ analytics, usage, seats }); }
return <button onClick={refresh}>Refresh</button>;}Per-call Customer Override
Section titled “Per-call Customer Override”You can pass a different customer ID to a hook:
const usage = useUsageBalance("api-calls", { customerId: "org_456",});This is useful in internal dashboards. Most product UI should use one provider customer ID from the active account or workspace.
UI Primitives
Section titled “UI Primitives”The UI subpaths provide optional display helpers and small primitives:
import { GuapocadoUIProvider } from "@guapocado/react/ui";import { Badge, Button, Card } from "@guapocado/react/ui/primitives";GuapocadoUIProvider is UI-only. It does not create a SDK client.
Keep using GuapocadoProvider for runtime billing reads.
Next.js Note
Section titled “Next.js Note”In Next.js, put the provider in a client component and use a
NEXT_PUBLIC_GUAPOCADO_CLIENT_KEY.
Server actions and route handlers should use @guapocado/sdk with a server key.