Skip to content

The most common thing to do with a flag is decide whether a piece of UI renders at all. The <FeatureFlag> component does that declaratively, with optional fallback content for the off case. The snippets receive the evaluated value:

<script lang="ts">
  import { FeatureFlag } from '@nebulr-group/bridge-svelte/flags';
</script>

<FeatureFlag key="new_dashboard" defaultValue={false}>
  <NewDashboard />
</FeatureFlag>

<!-- With fallback for the non-matching case: -->
<FeatureFlag key="premium_feature" defaultValue={false}>
  {#snippet children(value)}
    <button>Use premium feature</button>
  {/snippet}
  {#snippet fallback(value)}
    <button disabled title="Upgrade to unlock">Premium (locked)</button>
  {/snippet}
</FeatureFlag>

The fallback snippet’s second argument says why the feature is off:

reasonMeans
'plan'The workspace’s plan doesn’t include it: an upgrade alone would turn it on. feature names the plan feature the rule asks for.
'permission'This person’s role or privileges keep it off.
'off'The flag is switched off for everyone.
'rule' / 'rollout'Another condition, or outside the rollout.
undefinedBridge hasn’t said (the flag isn’t loaded yet).

openUpgrade() opens the upgrade dialog for this feature, naming the plans that include it:

<FeatureFlag key="reports" defaultValue={false}>
  {#snippet children()}<Reports />{/snippet}
  {#snippet fallback(_value, { reason, openUpgrade })}
    {#if reason === 'plan'}
      <button onclick={openUpgrade}>Reports are on Pro. See plans</button>
    {:else if reason === 'permission'}
      <p>Ask a workspace admin for access to reports.</p>
    {/if}
  {/snippet}
</FeatureFlag>

Nothing opens by itself: a hidden feature with no fallback renders nothing and opens no dialog. For a ready-made prompt, add the one word upgrade. When the feature is off because of the plan, it renders an “Upgrade to use this” button in its place, and the dialog opens when the button is clicked:

<FeatureFlag key="reports" defaultValue={false} upgrade>
  <Reports />
</FeatureFlag>

<FeatureFlag> takes the same per-call eval context (the identity and attributes a flag rule evaluates against) as useFlag’s third argument. Use it when the rule targets an app-specific attribute Bridge doesn’t already know (see Send context from your code):

<FeatureFlag
  key="new_dashboard"
  defaultValue={false}
  context={{ attributes: { project_count: projects.length } }}
>
  <NewDashboard />
</FeatureFlag>

Since context is a plain prop, it’s reactive for free: Svelte re-evaluates the object expression (and re-renders the flag) whenever projects.length changes, with no getter function needed the way useFlag requires for its standalone rune.

Props:

PropTypeDefaultDescription
keystring(required)The flag key
defaultValueT(required)Safe value; also sets the flag’s inferred type
contextPartial<EvalContext>(none)Per-call eval context (attributes win on collision)
upgradebooleanfalseWith no fallback: show an “Upgrade to use this” button when the plan is the reason
childrensnippet(none)Rendered when the flag passes; receives the value
fallbacksnippet(none)Rendered when it doesn’t; receives the value and { reason, feature, openUpgrade }