Skip to content

Flagsmith Feature Flags Configuration

This guide explains how to configure and use feature flags in the ERP-Unlocked platform using Flagsmith.

ERP-Unlocked uses Flagsmith for feature flag management. This enables:

  • Gradual rollouts: Roll out features to a percentage of users
  • Targeting: Enable features for specific organizations, users, or segments
  • A/B testing: Test different feature variants
  • Kill switches: Quickly disable features in production
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Flagsmith Server β”‚
β”‚ (Self-hosted or Flagsmith Cloud) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ @repo/feature-flags Package β”‚
β”‚ β”œβ”€β”€ server.ts - Server-side SDK (SSR, API routes) β”‚
β”‚ β”œβ”€β”€ client.ts - Client-side SDK (Browser) β”‚
β”‚ └── hooks.tsx - React hooks for components β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Webapp β”‚ β”‚ Python APIs β”‚
β”‚ (Astro/React)β”‚ β”‚ (via headers)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Terminal window
# Flagsmith environment key (server-side key)
FLAGSMITH_ENVIRONMENT_KEY=ser.xxxxx
# Flagsmith API URL (self-hosted or cloud)
FLAGSMITH_API_URL=https://flagsmith.yourdomain.com/api/v1
Terminal window
# Enable local evaluation (caches flags, reduces API calls)
FLAGSMITH_LOCAL_EVALUATION=true
# Cache refresh interval in seconds (default: 60)
FLAGSMITH_REFRESH_INTERVAL=60
---
import { getFeatureFlag } from '@repo/feature-flags';
// Check if feature is enabled for current user
const isNewDashboardEnabled = await getFeatureFlag('new_dashboard', {
identifier: Astro.locals.user?.id,
traits: {
organizationId: Astro.locals.organization?.id,
email: Astro.locals.user?.email,
}
});
---
{isNewDashboardEnabled ? (
<NewDashboard />
) : (
<LegacyDashboard />
)}
import { getFeatureFlag } from '@repo/feature-flags';
export const GET: APIRoute = async ({ locals }) => {
const useNewAlgorithm = await getFeatureFlag('new_matching_algorithm', {
identifier: locals.user?.id,
traits: {
organizationId: locals.organization?.id,
},
});
if (useNewAlgorithm) {
// Use new implementation
} else {
// Use existing implementation
}
};
import { useFeatureFlag } from '@repo/feature-flags/hooks';
export function OrderEditor() {
const showAdvancedOptions = useFeatureFlag('order_editor_advanced');
return (
<div>
<BasicOptions />
{showAdvancedOptions && <AdvancedOptions />}
</div>
);
}
import { useFeatureGate } from '@repo/feature-flags/hooks';
export function FeaturePreview() {
const { Gate } = useFeatureGate('beta_features');
return (
<Gate fallback={<UpgradeBanner />}>
<BetaFeaturePanel />
</Gate>
);
}
Flag NameDescriptionDefault
email_enabledEnable email processing for ordersfalse
dagster_enabledEnable Dagster-based data syncfalse
typesense_searchUse Typesense for product searchfalse
new_order_editorNew React-based order editorfalse
matching_shipto_resolver_v1Outer gate for the CK ship-to customer resolver (Temporal worker). See rollout doc below.false
email_triage_trusted_sender_auth_required_v1Temporal pull path only (Gmail/Graph β€” not webapp/Cloudflare email intake). Requires a dmarc=pass + provider marker in Authentication-Results before a trusted-sender domain match skips email triage (CWE-290 hardening; shadow-logs when off). No-op unless email_triage_trusted_senders_v1 is also on. See docs/PR-2849-CodeRabbit-trusted-sender-auth-gap.md.false
email_triage_internal_sender_v1Temporal pull path only. Skips mail sent by the organization’s own staff before content triage, so an org forwarding its own sales orders into its connected mailbox stops producing order rows. Matches the bare From address exactly (never by domain) against email_aliases rows with alias_type='user'. Evaluated per-connection, before the trusted-sender allowlist. Do not enable for any connection yet β€” the staff roster counts Ordermatic staff who join a customer org and never drops leavers; both blockers are tracked as P0 in TODOS.md.false

Flagsmith segments allow targeting users based on traits:

SegmentTargeting Rule
internal_teamemail CONTAINS @boonetek.com
beta_usersbetaEnabled = true
enterprise_orgssubscriptionTier = enterprise
staging_environmentenvironment = staging

Python services (pdf-api, pdf-worker) receive feature flag values via HTTP headers from the webapp:

from app.utils.feature_flags import get_feature_flags
@router.post("/process")
async def process_pdf(
features: FeatureFlags = Depends(get_feature_flags),
):
if features.is_enabled("pdf_extraction_v2"):
# Use new extraction pipeline
pass

The webapp passes flags via X-Feature-* headers when calling Python services.

  1. Create the flag in Flagsmith UI

    • Go to your Flagsmith project
    • Create a new feature flag with a descriptive name (snake_case)
    • Set default state (enabled/disabled)
    • Add any targeting rules or segments
  2. Use the flag in code

    const isEnabled = await getFeatureFlag('your_new_flag', identity);
  3. Update this documentation

    • Add the flag to the β€œCurrent Feature Flags” table above
  1. Use descriptive names: order_processing_v2 not flag1
  2. Default to disabled: New features should be off by default
  3. Remove stale flags: After 100% rollout, remove flag checks from code
  4. Document flags: Keep this guide updated with current flags
  5. Use segments: Target internal team first, then beta users, then gradual rollout
  • Check FLAGSMITH_REFRESH_INTERVAL setting
  • Verify FLAGSMITH_API_URL is correct
  • Check Flagsmith server health
  • Verify FLAGSMITH_ENVIRONMENT_KEY is correct
  • Check flag exists in Flagsmith for the correct environment
  • Verify identity traits match targeting rules
  • Enable local evaluation: FLAGSMITH_LOCAL_EVALUATION=true
  • Increase refresh interval for stable flags
  • Use caching for high-traffic routes