From 13d7a701e0869bd2c5581df14af617b219d62a97 Mon Sep 17 00:00:00 2001 From: Anders Asheim Hennum Date: Thu, 26 Feb 2026 16:59:46 +0100 Subject: [PATCH] docs: Add device targeting documentation for feature flags Document the new "Match by Device" option in feature flag release conditions. Device targeting ensures consistent flag values for anonymous users through the login flow by evaluating based on device ID rather than distinct ID. Co-Authored-By: Claude Opus 4.6 --- .../docs/feature-flags/best-practices.mdx | 6 ++-- contents/docs/feature-flags/canary-release.md | 2 +- .../feature-flags/creating-feature-flags.mdx | 8 +++++ .../docs/feature-flags/targeting-groups.md | 29 +++++++++++++++++-- contents/docs/feature-flags/tutorials.mdx | 2 +- src/navs/index.js | 2 +- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/contents/docs/feature-flags/best-practices.mdx b/contents/docs/feature-flags/best-practices.mdx index e8b08dc4457a..2148815b1a8a 100644 --- a/contents/docs/feature-flags/best-practices.mdx +++ b/contents/docs/feature-flags/best-practices.mdx @@ -26,12 +26,14 @@ function useBetaFeature() { } ``` -## 3. Identify users +## 3. Identify users (or target by device for anonymous users) -Because PostHog evaluates flags based on the user's distinct ID, having different IDs can cause the same user to receive different flag values across different sessions, devices, and platforms. By [identifying](/docs/getting-started/identify-users) them, you can ensure they consistent flag values. +Because PostHog evaluates flags based on the user's distinct ID, having different IDs can cause the same user to receive different flag values across different sessions, devices, and platforms. By [identifying](/docs/getting-started/identify-users) them, you can ensure consistent flag values. The same applies to identifying [groups](/docs/product-analytics/group-analytics) for group-level flags. +For flags targeting anonymous users — such as signup flows or landing page experiments — consider using [device targeting](/docs/feature-flags/targeting-groups#targeting-by-device) instead. This evaluates the flag based on the device ID, ensuring a consistent experience on the device even after the user logs in. + ## 4. Use server-side local evaluation for faster flags Evaluating feature flags requires making a request to PostHog for each flag. However, you can improve performance by evaluating flags locally. Instead of making a request for each flag, PostHog will periodically request and store feature flag definitions locally, enabling you to evaluate flags without making additional requests. diff --git a/contents/docs/feature-flags/canary-release.md b/contents/docs/feature-flags/canary-release.md index 64025aaea241..c744f541a5b2 100644 --- a/contents/docs/feature-flags/canary-release.md +++ b/contents/docs/feature-flags/canary-release.md @@ -70,7 +70,7 @@ Canary releases ensure higher quality features get shipped and fewer issues impa ## Further reading -- [Targeting feature flags on groups, pages, machines, and more](/docs/feature-flags/targeting-groups) +- [Targeting feature flags on devices, groups, pages, machines, and more](/docs/feature-flags/targeting-groups) - [How to bootstrap feature flags in React and Express](/tutorials/bootstrap-feature-flags-react) - [How to evaluate and update feature flags with the PostHog API](/tutorials/api-feature-flags) diff --git a/contents/docs/feature-flags/creating-feature-flags.mdx b/contents/docs/feature-flags/creating-feature-flags.mdx index 262b1fda5a88..2f347d481037 100644 --- a/contents/docs/feature-flags/creating-feature-flags.mdx +++ b/contents/docs/feature-flags/creating-feature-flags.mdx @@ -80,6 +80,12 @@ This specifies the conditions a user must meet to access the feature flag and re Condition sets are evaluated from **top to bottom**, and the **first** condition set that matches will be used. A condition matches when all property filters pass and the target falls within the rollout percentage. +By default, release conditions **match by user**, meaning the flag is evaluated based on the user's distinct ID. You can change this using the **Match by** dropdown: + +- **User** (default) – Evaluates based on the user's distinct ID. Best for in-app features targeting logged-in users. +- **Device** – Evaluates based on the device ID. Best for flags targeting anonymous users, as it ensures a consistent experience on the device even after the user logs in. See [targeting by device](/docs/feature-flags/targeting-groups#targeting-by-device) for more details. +- **Group** (requires [group analytics](/docs/product-analytics/group-analytics)) – Evaluates based on a group key (e.g., company, team, or organization). See [targeting groups](/docs/feature-flags/targeting-groups#targeting-groups-teams-or-organizations) for more details. + Percentage rollouts are available for all flags. More options depend on your PostHog setup: - If GeoIP is enabled, you can target based on geographic location. @@ -151,6 +157,8 @@ Feature flag values are calculated based on a user's properties. Since it's poss By enabling the option to persist feature flags across authentication, you ensure that the flag value remains the same. +> **Tip:** If your flag targets anonymous users and you just need the flag value to stay consistent through the login flow on the same device, consider using [device targeting](/docs/feature-flags/targeting-groups#targeting-by-device) instead. It achieves this without the performance tradeoffs below. + > **Note:** This feature requires `person_profiles: 'always'` and calling `posthog.identify` from the JavaScript Web SDK to function as expected. [Learn more about anonymous vs identified events here](/docs/data/anonymous-vs-identified-events). In our experience, the tradeoffs to enabling this are **not** worthwhile for the majority of our users. They include: diff --git a/contents/docs/feature-flags/targeting-groups.md b/contents/docs/feature-flags/targeting-groups.md index c93a1c4c4dcf..2e5f1b4a1fe2 100644 --- a/contents/docs/feature-flags/targeting-groups.md +++ b/contents/docs/feature-flags/targeting-groups.md @@ -1,13 +1,38 @@ --- -title: 'Targeting feature flags on groups, pages, machines, and more' +title: ‘Targeting feature flags on devices, groups, pages, machines, and more’ showTitle: true sidebar: Docs --- -To decide what value to return, PostHog’s feature flag service uses a flag key and an entity. Which entity to use it up to you, and these don't necessarily need to be _users_ – you can also target organizations, pages, machines, and more. +To decide what value to return, PostHog’s feature flag service uses a flag key and an entity. Which entity to use is up to you, and these don’t necessarily need to be _users_ – you can also target devices, organizations, pages, machines, and more. This tutorial shows you how to target these non-user entities in your use of feature flags. +## Targeting by device + +By default, feature flags match by **user**, meaning the flag is evaluated based on the user’s distinct ID. This works well for in-app features where users are logged in. + +For flags that target anonymous users — such as landing page experiments, onboarding flows, or signup forms — matching by **device** is often a better choice. When you match by device, PostHog uses the device ID (rather than the user’s distinct ID) to determine the flag value. This ensures a consistent experience on the device, even after the user logs in. + +To target by device, change the **Match by** value under **Release conditions** to **Device** when creating or editing your feature flag. + +### When to use device targeting + +- **Anonymous user experiences:** If a user sees a new signup flow before logging in, matching by device ensures they continue seeing the same variant after they create an account and log in. +- **Pre-authentication features:** Landing pages, pricing pages, or other features shown before a user is identified. +- **Experiments on anonymous traffic:** When running A/B tests on pages visited by both anonymous and logged-in users, device targeting prevents users from switching variants mid-experiment. + +### How it differs from user targeting + +| | Match by user | Match by device | +|---|---|---| +| **Evaluation basis** | User’s distinct ID | Device ID | +| **Best for** | Logged-in, identified users | Anonymous or pre-login experiences | +| **Consistent across login** | May change if distinct ID changes | Stays consistent on the same device | +| **Cross-device consistency** | Yes, if user is identified | No, each device is evaluated independently | + +> **Note:** Device targeting is a simpler alternative to [persisting flags across authentication steps](/docs/feature-flags/creating-feature-flags#persisting-feature-flags-across-authentication-steps-optional). If your flag only needs to be consistent on the same device through the login flow, device targeting achieves this without the performance tradeoffs of flag persistence. + ## Targeting groups, teams, or organizations If you enabled [group analytics](/docs/product-analytics/group-analytics) and set up group idenitifcation, targeting by groups, teams, or organizations is easy. When creating your feature flag, change the "Match by" value under "Release conditions" your group type name, add any conditions you want, and roll out the flag. diff --git a/contents/docs/feature-flags/tutorials.mdx b/contents/docs/feature-flags/tutorials.mdx index d65c4935d223..a3b729757078 100644 --- a/contents/docs/feature-flags/tutorials.mdx +++ b/contents/docs/feature-flags/tutorials.mdx @@ -5,7 +5,7 @@ showTitle: true --- Got a question which isn't answered below? Head to [the community forum](/questions) to let us know! -- [How to target flags with groups, pages, machines, and more](/docs/feature-flags/targeting-groups) +- [How to target flags with devices, groups, pages, machines, and more](/docs/feature-flags/targeting-groups) - [How to set up one-time feature flags](/tutorials/one-time-feature-flags) - [How to create sticky feature flags](/tutorials/sticky-feature-flags) - [How to do a canary release with feature flags](/docs/feature-flags/canary-release) diff --git a/src/navs/index.js b/src/navs/index.js index eada728b522f..fd901cda2548 100644 --- a/src/navs/index.js +++ b/src/navs/index.js @@ -3813,7 +3813,7 @@ export const docsMenu = { featured: true, }, { - name: 'Target flags with groups', + name: 'Target flags with devices & groups', url: '/docs/feature-flags/targeting-groups', icon: 'IconPeople', color: 'purple',