Docs/Getting Started/

Using Flags in Code

Learn how to evaluate feature flags in your application code

This guide covers how to evaluate feature flags in your application using the Flagpool SDK.

Basic Flag Evaluation

The most common operation is checking whether a boolean flag is enabled:

const isEnabled = client.isEnabled('new-feature')

if (isEnabled) {
  // Feature is enabled
} else {
  // Feature is disabled
}
import { useFlag } from '@flagpool/react'

function MyComponent() {
  const isEnabled = useFlag('new-feature')

  return isEnabled ? <NewFeature /> : <OldFeature />
}
if client.is_enabled("new-feature"):
    # Feature is enabled
else:
    # Feature is disabled
if client.IsEnabled("new-feature") {
    // Feature is enabled
} else {
    // Feature is disabled
}
if (client.isEnabled("new-feature")) {
    // Feature is enabled
} else {
    // Feature is disabled
}
if (client.IsEnabled("new-feature"))
{
    // Feature is enabled
}
else
{
    // Feature is disabled
}

Getting Flag Values

For non-boolean flags (string, number, JSON), use getValue to retrieve the raw value:

// String flag
const variant = client.getValue('checkout-variant')

// Number flag
const maxItems = client.getValue('max-cart-items')

// JSON flag
const config = client.getValue('feature-config')
import { useFlagValue } from '@flagpool/react'

function MyComponent() {
  // String flag with default
  const variant = useFlagValue('checkout-variant', 'control')

  // Number flag with default
  const maxItems = useFlagValue('max-cart-items', 10)

  // JSON flag with default
  const config = useFlagValue('feature-config', { enabled: false })
}
# Get any flag value
variant = client.get_value("checkout-variant")
max_items = client.get_value("max-cart-items")
config = client.get_value("feature-config")
variant := client.GetValue("checkout-variant")
maxItems := client.GetValue("max-cart-items")
config := client.GetValue("feature-config")
Object variant = client.getValue("checkout-variant");
Object maxItems = client.getValue("max-cart-items");
Object config = client.getValue("feature-config");
var variant = client.GetValue("checkout-variant");
var maxItems = client.GetValue("max-cart-items");
var config = client.GetValue("feature-config");

User Context

Provide user context for targeting rules and percentage-based rollouts. Context is set during initialization and can be updated at any time.

// Set context at initialization
const client = new FlagpoolClient({
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
  decryptionKey: 'your-decryption-key',
  context: {
    userId: 'user-123',
    email: 'user@example.com',
    plan: 'enterprise',
  },
})

// Update context later (e.g., after login)
client.updateContext({
  userId: 'user-456',
  plan: 'pro',
})
import { FlagpoolProvider, useFlagpool } from '@flagpool/react'

// Set initial context via the provider
function App() {
  return (
    <FlagpoolProvider
      projectId="your-project-id"
      apiKey="your-api-key"
      decryptionKey="your-decryption-key"
      context={{ userId: 'user-123', plan: 'pro' }}
    >
      <YourApp />
    </FlagpoolProvider>
  )
}

// Update context later
function UserLoader() {
  const { setContext } = useFlagpool()
  const { user } = useAuth()

  useEffect(() => {
    if (user) {
      setContext({
        userId: user.id,
        email: user.email,
        plan: user.subscription.plan,
      })
    }
  }, [user, setContext])

  return <MainApp />
}
# Set context at initialization
client = FlagpoolClient(
    project_id="your-project-id",
    api_key="your-api-key",
    decryption_key="your-decryption-key",
    context={
        "userId": "user-123",
        "email": "user@example.com",
        "plan": "enterprise",
    },
)

# Update context later
client.update_context({
    "userId": "user-456",
    "plan": "pro",
})
// Set context at initialization
client := flagpool.NewClient(flagpool.ClientOptions{
    ProjectID:     "your-project-id",
    APIKey:        "your-api-key",
    DecryptionKey: "your-decryption-key",
    Context: flagpool.Context{
        "userId": "user-123",
        "email":  "user@example.com",
        "plan":   "enterprise",
    },
})

// Update context later
client.UpdateContext(flagpool.Context{
    "userId": "user-456",
    "plan":   "pro",
})
// Set context at initialization
FlagpoolClient client = new FlagpoolClient(
    new ClientOptions()
        .setProjectId("your-project-id")
        .setApiKey("your-api-key")
        .setDecryptionKey("your-decryption-key")
        .setContext(Map.of(
            "userId", "user-123",
            "email", "user@example.com",
            "plan", "enterprise"
        ))
);

// Update context later
client.updateContext(Map.of(
    "userId", "user-456",
    "plan", "pro"
));
// Set context at initialization
var client = new FlagpoolClient(new FlagpoolClientOptions
{
    ProjectId = "your-project-id",
    ApiKey = "your-api-key",
    DecryptionKey = "your-decryption-key",
    Context = new Dictionary<string, object?>
    {
        ["userId"] = "user-123",
        ["email"] = "user@example.com",
        ["plan"] = "enterprise",
    },
});

// Update context later
client.UpdateContext(new Dictionary<string, object?>
{
    ["userId"] = "user-456",
    ["plan"] = "pro",
});

If no userId is provided in the context, percentage-based rollouts will not be deterministic across evaluations.

React Hooks Reference

The React SDK provides several hooks for different use cases:

useFlag — Boolean flags

import { useFlag } from '@flagpool/react'

function MyComponent() {
  const isEnabled = useFlag('dark-mode')

  return isEnabled ? <DarkTheme /> : <LightTheme />
}

useFlagValue — Any flag type

import { useFlagValue } from '@flagpool/react'

function MyComponent() {
  const buttonColor = useFlagValue('cta-button-color', 'blue')
  const maxItems = useFlagValue('max-items', 10)

  return <Button color={buttonColor}>Add (max {maxItems})</Button>
}

useFlagDetails — With loading and error states

import { useFlagDetails } from '@flagpool/react'

function MyComponent() {
  const { value, isLoading, error } = useFlagDetails('new-feature', false)

  if (isLoading) return <Spinner />
  if (error) return <ErrorMessage error={error} />

  return value ? <NewFeature /> : <OldFeature />
}

useFlagpool — Access the client directly

import { useFlagpool } from '@flagpool/react'

function DebugPanel() {
  const { client, isReady, setContext } = useFlagpool()

  return (
    <div>
      <p>SDK Ready: {isReady ? 'Yes' : 'No'}</p>
      <button onClick={() => setContext({ plan: 'enterprise' })}>Switch to Enterprise</button>
    </div>
  )
}

Default Values

Always provide sensible default values. Defaults are returned when:

  • The SDK hasn't initialized yet
  • The flag doesn't exist
  • There's a network error
  • The flag is disabled
// Default to false for feature flags
const isEnabled = client.isEnabled('new-feature', false)

// getValue returns null if the flag doesn't exist
const variant = client.getValue('checkout-variant') ?? 'control'
// useFlag defaults to false
const isEnabled = useFlag('new-feature', false)

// useFlagValue accepts any default
const variant = useFlagValue('checkout-variant', 'control')
const limit = useFlagValue('rate-limit', 100)

Cleaning Up

When your application shuts down, close the client to stop polling and flush any pending analytics:

client.close()
client.close()
client.Close()
client.close();
client.Dispose();

The React SDK handles cleanup automatically when the FlagpoolProvider unmounts.

Best Practices

1. Initialize Early

Initialize the SDK as early as possible in your application lifecycle so flags are ready when needed.

2. Use Descriptive Flag Keys

Match flag keys to their purpose: enable-dark-mode, new-checkout-flow, max-upload-size.

3. Always Provide Defaults

Never assume a flag exists. Always provide a safe default value so your application degrades gracefully.

4. Clean Up Old Flags

Once a feature is fully rolled out, remove the flag check from your code and archive the flag in the dashboard.

Next Steps

Start Managing Feature Flags Today

Join teams who trust Flagpool to deliver features safely and efficiently.

No credit card required • Cancel anytime