Skip to main content
The Flagmint React SDK provides hooks for evaluating feature flags in React and Next.js applications. Flags update in real-time via WebSocket.

Installation

npm install flagmint-react-sdk

Setup

Add the Provider

FlagmintProvider initialises the SDK and provides flag context to all child components. Place it as high as possible in your component tree.
// app/providers.tsx
'use client';
import { FlagmintProvider } from 'flagmint-react-sdk/client';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <FlagmintProvider
      options={{
        apiKey: process.env.NEXT_PUBLIC_FLAGMINT_KEY!,
        transportMode: 'websocket',
      }}
    >
      {children}
    </FlagmintProvider>
  );
}
Do not place FlagmintProvider inside a nested layout or page component. Doing so creates a new WebSocket connection on every route navigation.

Provider Props

PropTypeDefaultDescription
optionsFlagClientOptionsRequiredSDK configuration (see below)
initialFlagsRecord<string, any>{}Pre-evaluated flags for SSR hydration
deferInitializationbooleanfalseIf true, don’t connect until context is set

FlagClientOptions

OptionTypeDefaultDescription
apiKeystringRequiredYour environment’s SDK key (starts with ff_)
contextobjectundefinedEvaluation context (user, org attributes)
transportMode'auto' | 'websocket' | 'long-polling''auto'Connection method
enableOfflineCachebooleantrueCache flags in localStorage for offline use
persistContextbooleanfalsePersist context across page reloads
onError(error: Error) => voidundefinedError handler callback

Evaluating Flags

useFlag

Returns the evaluated value of a single flag. Re-renders the component when the flag value changes.
import { useFlag } from 'flagmint-react-sdk/client';

// Boolean flag
const showFeature = useFlag<boolean>('new-feature', false);

// String flag
const buttonColor = useFlag<string>('button-color', 'blue');

// Number flag
const maxItems = useFlag<number>('max-items', 10);

// JSON flag
const config = useFlag<{ retries: number }>('api-config', { retries: 3 });
Parameters:
ParameterTypeDescription
keystringThe flag key (must match the key in the dashboard)
defaultValueTFallback value used when the SDK isn’t ready or the flag doesn’t exist

useFlagmintReady

Returns true once the SDK has connected and received its initial flag values.
import { useFlag, useFlagmintReady } from 'flagmint-react-sdk/client';

export function Feature() {
  const isReady = useFlagmintReady();
  const showFeature = useFlag<boolean>('new-feature', false);

  if (!isReady) return <LoadingSpinner />;
  if (!showFeature) return null;

  return <NewFeature />;
}
Use useFlagmintReady to prevent a flash of default content before flags load. For pages that work fine without flags (login, signup), skip the ready check and let children render immediately.

User Context

Setting Context at Init

Pass context when the user is known (typically after login):
<FlagmintProvider
  options={{
    apiKey: process.env.NEXT_PUBLIC_FLAGMINT_KEY!,
    context: {
      kind: 'multi',
      user: {
        kind: 'user',
        key: user.id,
        email: user.email,
        country: user.country,
      },
      organization: {
        kind: 'organization',
        key: user.orgId,
        plan: user.plan,
      },
    },
  }}
>

Authentication Pattern

The recommended pattern for apps with login is to always render children, but only pass context after authentication:
'use client';
import { FlagmintProvider } from 'flagmint-react-sdk/client';
import { useUser } from '@/hooks/useUser';

export function FlagmintWithAuth({ children }: { children: React.ReactNode }) {
  const { user, isLoading } = useUser();

  const apiKey = process.env.NEXT_PUBLIC_FLAGMINT_KEY;
  if (!apiKey) return <>{children}</>;

  // Not logged in yet — render without flags
  if (!user || isLoading) return <>{children}</>;

  return (
    <FlagmintProvider
      options={{
        apiKey,
        transportMode: 'websocket',
        context: {
          kind: 'multi',
          user: { kind: 'user', key: user.id, email: user.email },
          organization: { kind: 'organization', key: user.orgId, plan: user.plan },
        },
      }}
    >
      {children}
    </FlagmintProvider>
  );
}
This ensures public pages (login, signup, marketing) render immediately without waiting for the SDK.

Transport Modes

ModeBest ForReal-Time?
websocketBrowser apps, dashboardsYes — server pushes updates instantly
long-pollingServer-side rendering, restricted networksNo — polls every 10 seconds
autoMost apps (default)Tries WebSocket, falls back to polling
For client-side React apps, websocket is recommended. The SDK maintains a single persistent connection and receives flag updates the moment they change in the dashboard.

Offline & Caching

When enableOfflineCache is true (the default), the SDK caches flag values in localStorage. If the server is unreachable on the next page load, the SDK serves cached values until a connection is re-established. Cached values expire after 24 hours.

TypeScript

The SDK is fully typed. Use generics with useFlag to get type-safe flag values:
interface FeatureConfig {
  maxRetries: number;
  timeout: number;
  enableLogging: boolean;
}

const config = useFlag<FeatureConfig>('api-config', {
  maxRetries: 3,
  timeout: 5000,
  enableLogging: false,
});

// config is typed as FeatureConfig
console.log(config.maxRetries); // ✓ type-safe

Troubleshooting

The SDK can’t connect to the server. Check that your API key is correct, the API URL is reachable, and CORS allows your app’s origin.
Verify you’re using transportMode: 'websocket'. If you’re behind a corporate proxy that blocks WebSocket connections, switch to 'long-polling'.
The server doesn’t have flag values during SSR. Use the initialFlags prop to pass pre-evaluated flags, or wrap the flag-dependent UI with useFlagmintReady to defer rendering until the client has connected.
Check your server’s heartbeat interval. The SDK sends a ping every 25 seconds. If your server’s heartbeat timeout is shorter than the SDK’s ping interval, the server will terminate the connection. Align both to 30 seconds.
Your Flagmint API must include your app’s origin in its CORS configuration. For local development, ensure localhost:3000 (or your dev port) is allowed. The WebSocket upgrade request also needs CORS headers.

Next Steps

Targeting Rules

Control which users see which features.

API Reference

Direct API access for custom integrations.