npm.io
1.1.5 • Published yesterday

@dr-sentry/react

Licence
Apache-2.0
Version
1.1.5
Deps
0
Size
195 kB
Vulns
0
Weekly
0

@dr-sentry/react

Official React SDK for the DeploySentry feature flag platform. Provides React hooks and a context provider for evaluating feature flags with real-time SSE updates.

Installation

npm install @dr-sentry/react

React 18 or later is required as a peer dependency.

Quick Start

Wrap your application with DeploySentryProvider and use hooks anywhere in the tree:

import { DeploySentryProvider, useFlag } from '@dr-sentry/react';

function App() {
  return (
    <DeploySentryProvider
      apiKey="ds_live_abc123"
      baseURL="https://api.dr-sentry.com"
      environment="production"
      project="my-app"
      application="my-web-app"
      user={{ id: 'user-42' }}
    >
      <MyComponent />
    </DeploySentryProvider>
  );
}

function MyComponent() {
  const showBanner = useFlag('show-banner', false);

  if (!showBanner) return null;
  return <div>New feature banner!</div>;
}

Provider Props

Prop Type Required Description
apiKey string Yes API key for authenticating with DeploySentry.
baseURL string Yes Base URL of the DeploySentry API.
environment string Yes Environment identifier (e.g. "production").
project string Yes Project identifier.
application string Yes Application identifier
user UserContext No User context for targeting rules.
children ReactNode Yes React children.
mode string No SDK mode: server, file, or server-with-fallback.
flagData object No Pre-loaded flag config for file/fallback mode.
defaults object No Offline defaults consulted when the API call fails (fallback only).

Offline / File Mode

For offline use or testing, pass pre-loaded flag config via the flagData prop:

import flagConfig from './.deploysentry/flags.json';

<DeploySentryProvider
  apiKey="not-used"
  baseURL=""
  environment="staging"
  project="my-project"
  application="my-web-app"
  mode="file"
  flagData={flagConfig}
>
  <App />
</DeploySentryProvider>
Modes
Mode Behavior
server (default) API calls + SSE streaming
file Use flagData prop, evaluate locally. No server contact.
server-with-fallback Try server first. If unavailable, use flagData as fallback.

Export the config from the dashboard (App Settings → Export flags.yaml), then convert to JSON or import with a YAML plugin.

Offline Defaults (Fallback)

For resilience against transient API outages, pass a flag-export JSON via the defaults prop. Unlike flagData (which replaces the API), defaults only kicks in when the API call fails — successful live data overwrites the defaults per-key.

Generate the snapshot with the CLI:

deploysentry flags export --application web --env production -f flags.json

Then import it as a build-time asset:

import defaults from './flags.json';

<DeploySentryProvider
  apiKey={import.meta.env.VITE_DEPLOYSENTRY_API_KEY}
  baseURL="https://api.dr-sentry.com"
  environment="production"
  project="my-app"
  application="web"
  defaults={defaults}
>
  <App />
</DeploySentryProvider>

Environment matching: the environment prop is matched against the export's environments[] first by UUID, then by name (case-insensitive). When a match is found, that env's per-flag {enabled, value} overrides the flag's global default_value. When no match, the global default_value is used (the flag is treated as enabled).

Hooks

useFlag(key, defaultValue)

Returns the resolved flag value. Falls back to defaultValue while loading or if the flag does not exist.

const isEnabled = useFlag('dark-mode', false);
const variant = useFlag('checkout-flow', 'control');
useFlagDetail(key)

Returns detailed evaluation information including metadata.

const { value, enabled, metadata, loading } = useFlagDetail('new-checkout');

// metadata contains: category, purpose, owners, isPermanent, expiresAt, tags
useFlagsByCategory(category)

Returns all flags matching the given category.

const experiments = useFlagsByCategory('experiment');
const releases = useFlagsByCategory('release');

Categories: 'release' | 'feature' | 'experiment' | 'ops' | 'permission' | 'envvar'

useExpiredFlags()

Returns all non-permanent flags whose expiresAt date is in the past. Useful for admin dashboards.

const expired = useExpiredFlags();
useFlagsVersion()

Returns the project's flag-set version last loaded from the server (number), or null before the first successful fetch / in file mode. The version advances on any change to the project's flag state, so it validates exactly which flag set the app is serving. Re-renders when a refetch changes the version.

const version = useFlagsVersion();
return <span>flags v{version ?? '—'}</span>;
useDispatch(operation)

Returns the resolved handler for a registered operation based on current flag state. See Register / Dispatch Pattern below.

const checkout = useDispatch<() => Promise<void>>('checkout');
await checkout();
useDeploySentry()

Returns the raw DeploySentryClient instance for advanced use-cases.

const client = useDeploySentry();

Register / Dispatch Pattern

The register/dispatch pattern centralizes all flag-gated behavior in one place instead of scattering if/else checks across components.

Setup (single-point registration)

Create one registration file that runs at app initialization:

// src/flags/registrations.ts
import type { DeploySentryClient } from '@dr-sentry/react';
import { legacySearch, vectorSearch } from '../search';
import { classicCheckout, newCheckout } from '../checkout';

export function registerFlags(client: DeploySentryClient) {
  // Search — default handler, then flag-gated override
  client.register('search', legacySearch);
  client.register('search', vectorSearch, 'vector-search-v2');

  // Checkout
  client.register('checkout', classicCheckout);
  client.register('checkout', newCheckout, 'new-checkout-flow');
}

Call registerFlags(client) after the client initializes (e.g. in the provider setup or an app-level effect).

Usage in components
import { useDispatch } from '@dr-sentry/react';

function SearchBar() {
  const search = useDispatch<(query: string) => Promise<Results>>('search');

  return (
    <input onChange={(e) => search(e.target.value).then(setResults)} />
  );
}
How it works
  1. client.register(operation, handler, flagKey?) — Register a handler for a named operation. With flagKey, it's only selected when that flag is enabled. Without flagKey, it's the default fallback.
  2. useDispatch(operation) — Returns the first registered handler whose flag is enabled, or the default handler. The component never knows about flags.
Why single-point registration
  • One file shows every flag-gated behavior in the app
  • Easy auditing — search for a flag key and find every behavior it controls
  • Simple cleanup when a flag is retired (remove the registration, keep the handler)
  • LLMs and code review tools can read one file to understand all flag-gated behavior

Real-Time Updates

The provider automatically opens an SSE connection to receive flag updates in real time. When a flag changes on the server, all components consuming that flag re-render immediately. The connection reconnects automatically with exponential backoff if it drops.

SSR Compatibility

Hooks return default/empty values during server-side rendering. Flags are fetched client-side after the provider mounts.

Types

All types are exported from the package:

import type {
  Flag,
  FlagCategory,
  FlagDetail,
  FlagMetadata,
  ProviderProps,
  UserContext,
} from '@dr-sentry/react';

Authentication

All requests use an API key passed in the Authorization header:

Authorization: ApiKey <your-api-key>

Pass the key via the provider's apiKey prop. The SDK sets the header automatically.

Session Consistency

Bind evaluations to a session so the server caches results for a consistent user experience:

<DeploySentryProvider
  apiKey="ds_key_xxxxxxxxxxxx"
  baseURL="https://api.dr-sentry.com"
  environment="production"
  project="my-app"
  application="my-web-app"
  sessionId={`user:${userId}`}
>
  <App />
</DeploySentryProvider>
const client = useDeploySentry();
await client.refreshSession();
  • The session ID is sent as an X-DeploySentry-Session header on every request.
  • The server caches evaluation results per session for 30 minutes (sliding TTL).
  • Omit the session ID to always get fresh evaluations on each request.

License

Apache-2.0

Keywords