diff --git a/contents/docs/feature-flags/property-overrides.mdx b/contents/docs/feature-flags/property-overrides.mdx index 36940ea7e344..de4755e7d6c6 100644 --- a/contents/docs/feature-flags/property-overrides.mdx +++ b/contents/docs/feature-flags/property-overrides.mdx @@ -40,33 +40,33 @@ When you call `identify()` with person properties, those properties are automati // Properties are automatically available for flag evaluation posthog.identify('user-123', { email: 'user@company.com', - plan: 'enterprise' + is_beta_user: true }) -// This flag check can use 'plan' immediately -const showFeature = posthog.isFeatureEnabled('enterprise-feature') +// This flag check can use 'is_beta_user' immediately +const showFeature = posthog.isFeatureEnabled('beta-feature') ``` ```react-native // Properties are automatically available for flag evaluation posthog.identify('user-123', { email: 'user@company.com', - plan: 'enterprise' + is_beta_user: true }) -// This flag check can use 'plan' immediately -const showFeature = posthog.isFeatureEnabled('enterprise-feature') +// This flag check can use 'is_beta_user' immediately +const showFeature = posthog.isFeatureEnabled('beta-feature') ``` ```swift file=iOS // Properties are automatically available for flag evaluation PostHogSDK.shared.identify("user-123", userProperties: [ "email": "user@company.com", - "plan": "enterprise" + "is_beta_user": true ]) -// This flag check can use 'plan' immediately -let showFeature = PostHogSDK.shared.isFeatureEnabled("enterprise-feature") +// This flag check can use 'is_beta_user' immediately +let showFeature = PostHogSDK.shared.isFeatureEnabled("beta-feature") ``` ```kotlin file=Android @@ -75,12 +75,26 @@ PostHog.identify( "user-123", userProperties = mapOf( "email" to "user@company.com", - "plan" to "enterprise" + "is_beta_user" to true ) ) -// This flag check can use 'plan' immediately -val showFeature = PostHog.isFeatureEnabled("enterprise-feature") +// This flag check can use 'is_beta_user' immediately +val showFeature = PostHog.isFeatureEnabled("beta-feature") +``` + +```dart +// Properties are automatically available for flag evaluation +await Posthog().identify( + userId: 'user-123', + userProperties: { + 'email': 'user@company.com', + 'is_beta_user': true, + }, +) + +// This flag check can use 'is_beta_user' immediately +final showFeature = await Posthog().isFeatureEnabled('beta-feature') ``` @@ -135,6 +149,20 @@ PostHog.group( val showFeature = PostHog.isFeatureEnabled("enterprise-companies-feature") ``` +```dart +await Posthog().group( + groupType: 'company', + groupKey: 'company-123', + groupProperties: { + 'name': 'Acme Inc', + 'plan': 'enterprise', + }, +) + +// Group properties are available for flag evaluation +final showFeature = await Posthog().isFeatureEnabled('enterprise-companies-feature') +``` + ### Default properties in the web SDK @@ -203,7 +231,7 @@ This adds the following properties to flag requests: ### Default properties in mobile SDKs -Mobile SDKs (React Native, iOS, and Android) include common device and app properties in every feature flag evaluation request. The `setDefaultPersonProperties` configuration option controls this behavior and defaults to `true`. +Mobile SDKs (React Native, iOS, Android, and Flutter) include common device and app properties in every feature flag evaluation request. The `setDefaultPersonProperties` configuration option controls this behavior and defaults to `true`. | Property | Description | |----------|-------------| @@ -225,47 +253,58 @@ Use `setPersonPropertiesForFlags()` to explicitly set properties for flag evalua ```js file=Web // Set properties for flag evaluation posthog.setPersonPropertiesForFlags({ - plan: 'enterprise', - company_size: 'large' + is_beta_user: true, + email: 'user@company.com' }) // Properties persist across flag evaluations -const showFeature = posthog.isFeatureEnabled('enterprise-feature') +const showFeature = posthog.isFeatureEnabled('beta-feature') ``` ```react-native // Set properties for flag evaluation posthog.setPersonPropertiesForFlags({ - plan: 'enterprise', - company_size: 'large' + is_beta_user: true, + email: 'user@company.com' }) // Properties persist across flag evaluations -const showFeature = posthog.isFeatureEnabled('enterprise-feature') +const showFeature = posthog.isFeatureEnabled('beta-feature') ``` ```swift file=iOS // Set properties for flag evaluation PostHogSDK.shared.setPersonPropertiesForFlags([ - "plan": "enterprise", - "company_size": "large" + "is_beta_user": true, + "email": "user@company.com" ]) // Properties persist across flag evaluations -let showFeature = PostHogSDK.shared.isFeatureEnabled("enterprise-feature") +let showFeature = PostHogSDK.shared.isFeatureEnabled("beta-feature") ``` ```kotlin file=Android // Set properties for flag evaluation PostHog.setPersonPropertiesForFlags( mapOf( - "plan" to "enterprise", - "company_size" to "large" + "is_beta_user" to true, + "email" to "user@company.com" ) ) // Properties persist across flag evaluations -val showFeature = PostHog.isFeatureEnabled("enterprise-feature") +val showFeature = PostHog.isFeatureEnabled("beta-feature") +``` + +```dart +// Set properties for flag evaluation +await Posthog().setPersonPropertiesForFlags({ + 'is_beta_user': true, + 'email': 'user@company.com', +}) + +// Properties persist across flag evaluations +final showFeature = await Posthog().isFeatureEnabled('beta-feature') ``` @@ -280,8 +319,8 @@ By default, calling `setPersonPropertiesForFlags()` triggers an automatic reload ```js file=Web // Set properties without reloading -posthog.setPersonPropertiesForFlags({ plan: 'enterprise' }, false) -posthog.setPersonPropertiesForFlags({ company_size: 'large' }, false) +posthog.setPersonPropertiesForFlags({ is_beta_user: true }, false) +posthog.setPersonPropertiesForFlags({ email: 'user@company.com' }, false) // Manually reload when ready posthog.reloadFeatureFlags() @@ -289,8 +328,8 @@ posthog.reloadFeatureFlags() ```react-native // Set properties without reloading -posthog.setPersonPropertiesForFlags({ plan: 'enterprise' }, false) -posthog.setPersonPropertiesForFlags({ company_size: 'large' }, false) +posthog.setPersonPropertiesForFlags({ is_beta_user: true }, false) +posthog.setPersonPropertiesForFlags({ email: 'user@company.com' }, false) // Manually reload when ready posthog.reloadFeatureFlags() @@ -298,8 +337,8 @@ posthog.reloadFeatureFlags() ```swift file=iOS // Set properties without reloading -PostHogSDK.shared.setPersonPropertiesForFlags(["plan": "enterprise"], reloadFeatureFlags: false) -PostHogSDK.shared.setPersonPropertiesForFlags(["company_size": "large"], reloadFeatureFlags: false) +PostHogSDK.shared.setPersonPropertiesForFlags(["is_beta_user": true], reloadFeatureFlags: false) +PostHogSDK.shared.setPersonPropertiesForFlags(["email": "user@company.com"], reloadFeatureFlags: false) // Manually reload when ready PostHogSDK.shared.reloadFeatureFlags() @@ -307,13 +346,22 @@ PostHogSDK.shared.reloadFeatureFlags() ```kotlin file=Android // Set properties without reloading -PostHog.setPersonPropertiesForFlags(mapOf("plan" to "enterprise"), reloadFeatureFlags = false) -PostHog.setPersonPropertiesForFlags(mapOf("company_size" to "large"), reloadFeatureFlags = false) +PostHog.setPersonPropertiesForFlags(mapOf("is_beta_user" to true), reloadFeatureFlags = false) +PostHog.setPersonPropertiesForFlags(mapOf("email" to "user@company.com"), reloadFeatureFlags = false) // Manually reload when ready PostHog.reloadFeatureFlags() ``` +```dart +// Set properties without reloading +await Posthog().setPersonPropertiesForFlags({'is_beta_user': true}, reloadFeatureFlags: false) +await Posthog().setPersonPropertiesForFlags({'email': 'user@company.com'}, reloadFeatureFlags: false) + +// Manually reload when ready +await Posthog().reloadFeatureFlags() +``` + ### Resetting property overrides @@ -338,6 +386,10 @@ PostHogSDK.shared.resetPersonPropertiesForFlags() PostHog.resetPersonPropertiesForFlags() ``` +```dart +await Posthog().resetPersonPropertiesForFlags() +``` + On mobile SDKs, this automatically triggers a feature flag reload. Pass `false` to reset without reloading. On web, flags are not automatically reloaded. Call `reloadFeatureFlags()` manually if needed. @@ -408,6 +460,20 @@ PostHog.resetGroupPropertiesForFlags("company") PostHog.resetGroupPropertiesForFlags() ``` +```dart +// Set group properties for flag evaluation +await Posthog().setGroupPropertiesForFlags('company', { + 'plan': 'enterprise', + 'employee_count': 500, +}) + +// Reset group properties for a specific type +await Posthog().resetGroupPropertiesForFlags(groupType: 'company') + +// Reset all group properties +await Posthog().resetGroupPropertiesForFlags() +``` + ### Use case: Targeting by browser or device @@ -465,8 +531,8 @@ Server-side SDKs handle property overrides differently. Instead of persistent se ```node const flags = await client.evaluateFlags('user-distinct-id', { personProperties: { - plan: 'enterprise', - company_size: 'large', + is_beta_user: true, + email: 'user@company.com', }, groups: { company: 'company-123', @@ -486,8 +552,8 @@ const flagValue = flags.getFlag('feature-flag-key') flags = posthog.evaluate_flags( "user-distinct-id", person_properties={ - "plan": "enterprise", - "company_size": "large", + "is_beta_user": True, + "email": "user@company.com", }, groups={ "company": "company-123", @@ -507,8 +573,8 @@ flag_value = flags.get_flag("feature-flag-key") $flags = PostHog::evaluateFlags( distinctId: 'user-distinct-id', personProperties: [ - 'plan' => 'enterprise', - 'company_size' => 'large', + 'is_beta_user' => true, + 'email' => 'user@company.com', ], groups: [ 'company' => 'company-123', @@ -528,8 +594,8 @@ $flagValue = $flags->getFlag('feature-flag-key'); flags = posthog.evaluate_flags( 'user-distinct-id', person_properties: { - plan: 'enterprise', - company_size: 'large', + is_beta_user: true, + email: 'user@company.com', }, groups: { company: 'company-123', @@ -549,8 +615,8 @@ flag_value = flags.get_flag('feature-flag-key') flags, err := client.EvaluateFlags(posthog.EvaluateFlagsPayload{ DistinctId: "user-distinct-id", PersonProperties: posthog.NewProperties(). - Set("plan", "enterprise"). - Set("company_size", "large"), + Set("is_beta_user", true). + Set("email", "user@company.com"), Groups: posthog.NewGroups(). Set("company", "company-123"), GroupProperties: map[string]posthog.Properties{ @@ -570,8 +636,8 @@ flagValue := flags.GetFlag("feature-flag-key") PostHogFeatureFlagEvaluations flags = posthog.evaluateFlags( "user-distinct-id", PostHogEvaluateFlagsOptions.builder() - .personProperty("plan", "enterprise") - .personProperty("company_size", "large") + .personProperty("is_beta_user", true) + .personProperty("email", "user@company.com") .group("company", "company-123") .groupProperty("company", "plan", "enterprise") .groupProperty("company", "employee_count", 500) diff --git a/contents/docs/libraries/flutter/index.mdx b/contents/docs/libraries/flutter/index.mdx index 2ae82f389d25..041b84093286 100644 --- a/contents/docs/libraries/flutter/index.mdx +++ b/contents/docs/libraries/flutter/index.mdx @@ -146,6 +146,23 @@ import FlutterFeatureFlagsCode from '../../integrate/feature-flags-code/_snippet +### Setting properties for flag evaluation + +If a flag targets person or group properties, you can send those properties inline with the next flag evaluation request instead of waiting for a `$set` event to be ingested. This avoids the race where a flag returns a stale value right after you set a property. + +```dart +// Person properties — included in the next flag evaluation request +await Posthog().setPersonPropertiesForFlags({ + 'storefront_country': 'US', + 'is_beta_user': true, +}) + +// Group properties +await Posthog().setGroupPropertiesForFlags('company', {'plan': 'enterprise'}) +``` + +By default these reload feature flags, and the returned `Future` completes once the reload finishes, so the next `getFeatureFlag` reflects the new properties. Pass `reloadFeatureFlags: false` to set several properties before reloading. Use `resetPersonPropertiesForFlags()` and `resetGroupPropertiesForFlags()` to clear them. See [property overrides for flag evaluation](/docs/feature-flags/property-overrides) for details. + ## Experiments (A/B tests) Since [experiments](/docs/experiments/start-here) use feature flags, the code for running an experiment is very similar to the feature flags code: