FEATURE FLAGS
Feature Flags
Section titled “Feature Flags”Feature flags allow features to be enabled or disabled without code changes, supporting gradual rollouts, A/B testing, and per-environment configuration.
Available Feature Flags
Section titled “Available Feature Flags”All flags default to false (disabled) unless set via environment variable.
| Flag (camelCase) | Environment Variable | Route(s) | Description | E2E Tests |
|---|---|---|---|---|
anonymousCrimeData | VITE_FEATURE_ANONYMOUS_CRIME_DATA | /map (embedded) | Crowdsourced suspicious activity reporting and map markers | anonymous-crime-data.spec.ts |
communityQA | VITE_FEATURE_COMMUNITY_QA | /qa, /qa/ask, /qa/questions/:id | Community Q&A forum | community-qa.spec.ts |
insuranceClaims | VITE_FEATURE_INSURANCE_CLAIMS | /claims, /claims/new, /claims/:id | Insurance claim filing and tracking assistant | insurance-claims.spec.ts |
learningHub | VITE_FEATURE_LEARNING_HUB | /learning-hub, /learning-hub/module/:id | Educational content, courses, badges, leaderboard | learning-hub.spec.ts |
mentorship | VITE_FEATURE_MENTORSHIP | /mentorship, /mentorship/* | Peer support mentorship program | mentorship.spec.ts |
multiLanguageSupport | VITE_FEATURE_MULTI_LANGUAGE_SUPPORT | Global (language selector) | Multi-language UI support | — |
recoveryProgressTracker | VITE_FEATURE_RECOVERY_PROGRESS_TRACKER | /recovery | Structured recovery journey with milestones and tasks | recovery-progress.spec.ts |
riskDashboard | VITE_FEATURE_RISK_DASHBOARD | /risk-dashboard | Incident risk intelligence dashboard with area search | risk-dashboard.spec.ts |
smartNeighborhoodAlerts | VITE_FEATURE_SMART_NEIGHBORHOOD_ALERTS | /alerts | Location-based crime alerts and notifications | smart-neighborhood-alerts.spec.ts |
smartProductRecommendations | VITE_FEATURE_SMART_PRODUCT_RECOMMENDATIONS | /recommendations | AI-powered security product recommendation quiz | smart-product-recommendations.spec.ts |
virtualSecurityAssessment | VITE_FEATURE_VIRTUAL_SECURITY_ASSESSMENT | /recovery-resources/security-assessment | AI-powered photo-analysis security assessment (page always accessible; flag gates AI tab) | virtual-security-assessment.spec.ts |
Setting Flags
Section titled “Setting Flags”.env / .env.local.custom
Section titled “.env / .env.local.custom”VITE_FEATURE_RISK_DASHBOARD=trueVITE_FEATURE_COMMUNITY_QA=trueVITE_FEATURE_MENTORSHIP=falseOnly values of exactly true enable a flag. Anything else (false, omitted, 0) disables it.
Restart the dev server after changing .env.
All flags on (development / E2E)
Section titled “All flags on (development / E2E)”The Playwright test runner sets all flags to true via webServer.env in playwright.config.ts.
The .env.test file does the same for local E2E runs.
Usage in Code
Section titled “Usage in Code”Route gating (App.tsx pattern)
Section titled “Route gating (App.tsx pattern)”import { getFeatureFlags } from '@/config/featureFlags';
const featureFlags = getFeatureFlags();
// Inside the router:{featureFlags.riskDashboard && ( <Route path="/risk-dashboard" element={<RiskDashboardPage />} />)}Imperative check
Section titled “Imperative check”import { isFeatureEnabled } from '@/config/featureFlags';
if (isFeatureEnabled('mentorship')) { // show mentorship nav item}React hook (inside components)
Section titled “React hook (inside components)”import { useFeatureFlag } from '@/hooks/useFeatureFlag';
function MyComponent() { const isEnabled = useFeatureFlag('virtualSecurityAssessment'); return isEnabled ? <AiAssessment /> : <ManualChecklist />;}Mocking in Unit Tests
Section titled “Mocking in Unit Tests”vi.mock('@/config/featureFlags', () => ({ getFeatureFlags: () => ({ riskDashboard: true, mentorship: false, // ... all other flags }), isFeatureEnabled: (flag: string) => flag === 'riskDashboard',}));
vi.mock('@/hooks/useFeatureFlag', () => ({ useFeatureFlag: (flag: string) => flag === 'riskDashboard',}));Adding a New Flag
Section titled “Adding a New Flag”- Add to
FeatureFlagsinterface inpackages/webapp/src/config/featureFlags.ts:
export interface FeatureFlags { // ... existing flags myNewFeature: boolean;}- Add to
defaultFeatureFlagsin the same file:
export const defaultFeatureFlags: FeatureFlags = { // ... existing flags myNewFeature: import.meta.env.VITE_FEATURE_MY_NEW_FEATURE === 'true',};- Add to
shared-types/src/features.ts(kebab-case string literal):
export type FeatureFlag = 'my-new-feature';// ... existing flags-
Add to
FeatureFlagPanel.tsxmetadata record so it appears in the admin panel. -
Add to
.env.example:
VITE_FEATURE_MY_NEW_FEATURE=false- Enable in Playwright (
packages/webapp/playwright.config.tswebServer.env):
VITE_FEATURE_MY_NEW_FEATURE: 'true',-
Write E2E tests in
e2e-tests/my-new-feature.spec.ts. -
Update this table.
Architecture Notes
Section titled “Architecture Notes”Feature flags are build-time / deploy-time values baked in by Vite via import.meta.env.
They cannot be changed at runtime without restarting the server.
There is also a FeatureFlagsContext / FeatureToggleContext that wraps the same values
in React context, seeding from getFeatureFlags(). This supports runtime overrides (e.g.
admin toggleFlag) on top of the env-var base, but this capability is not currently
exposed in the production UI.
Related Files
Section titled “Related Files”| File | Purpose |
|---|---|
packages/webapp/src/config/featureFlags.ts | Authoritative flag definitions and env-var loading |
packages/webapp/src/hooks/useFeatureFlag.ts | React hook wrapper |
packages/webapp/src/components/feature-flags/FeatureGate.tsx | JSX gate component |
packages/webapp/src/components/FeatureFlagPanel.tsx | Read-only admin panel (all flags + descriptions) |
packages/shared-types/src/features.ts | Shared FeatureFlag string-literal type |
packages/webapp/playwright.config.ts | E2E: enables all flags via webServer.env |
.env.example | Template showing all flag env vars (all false) |