Skip to content

feat(js): add react helper export#233

Closed
nicklasl wants to merge 13 commits into
mainfrom
js/react
Closed

feat(js): add react helper export#233
nicklasl wants to merge 13 commits into
mainfrom
js/react

Conversation

@nicklasl

@nicklasl nicklasl commented Jan 20, 2026

Copy link
Copy Markdown
Member

React Flag Bundle Support

Adds lightweight React integration for consuming pre-resolved flags without bundling the 110KB WASM resolver.

New export: @spotify-confidence/openfeature-server-provider-local/react (1.1KB)

How it works:

  1. Server calls provider.createFlagBundle(context) → returns {bundle, applyFlag}
  2. Pass to <ConfidenceProvider bundle={bundle} apply={applyFlag}>
  3. Client uses useFlag('flag', default) - auto-logs exposure on mount
  4. Optional: useFlag('flag', default, {skipExposure: true}) returns {value, expose} for manual control

Usage

Server Component (Next.js App Router)

import { createConfidenceServerProvider } from '@spotify-confidence/openfeature-server-provider-local';
import { ConfidenceProvider } from '@spotify-confidence/openfeature-server-provider-local/react';

const provider = createConfidenceServerProvider({ flagClientSecret: '...' });

export default async function Layout({ children }) {
  const { bundle, applyFlag } = await provider.createFlagBundle({
    targetingKey: 'user-123'
  });

  async function apply(flagName: string) {
    'use server';
    applyFlag(flagName);
  }

  return (
    <ConfidenceProvider bundle={bundle} apply={apply}>
      {children}
    </ConfidenceProvider>
  );
}

Client Component - Auto Exposure

'use client';
import { useFlag } from '@spotify-confidence/openfeature-server-provider-local/react';

export function FeatureButton() {
  // Automatically logs exposure on mount
  const enabled = useFlag('my-feature.enabled', false);

  return enabled ? <NewButton /> : <OldButton />;
}

Client Component - Manual Exposure

'use client';
import { useFlag } from '@spotify-confidence/openfeature-server-provider-local/react';

export function Checkout() {
  // Skip auto-exposure, get expose() function instead
  const { value: discountEnabled, expose } = useFlag(
    'checkout.discount',
    false,
    { skipExposure: true }
  );

  const handlePurchase = () => {
    if (discountEnabled) {
      expose(); // Log exposure only when user interacts
      applyDiscount();
    }
    completePurchase();
  };

  return <button onClick={handlePurchase}>Buy Now</button>;
}

@nicklasl nicklasl changed the title feat(js): add react helper lib feat(js): add react helper export Jan 20, 2026
@nicklasl nicklasl changed the title feat(js): add react helper export feat(js): add react helper bundle Jan 20, 2026
@nicklasl nicklasl changed the title feat(js): add react helper bundle feat(js): add react helper export Jan 20, 2026
@nicklasl nicklasl closed this Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant