From 8976087124580a9b314f73200a01df9080cbccbb Mon Sep 17 00:00:00 2001 From: Rafael Audibert <32079912+rafaeelaudibert@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:01:06 -0300 Subject: [PATCH] docs: Add feature flags support to Elixir (#10588) Co-authored-by: Ian Vanagas <34755028+ivanagas@users.noreply.github.com> --- .../blog/how-to-measure-product-engagement.md | 6 ++- .../experiments/adding-experiment-code.mdx | 11 ++++- contents/docs/experiments/installation.mdx | 7 ++-- .../adding-feature-flag-code.mdx | 5 +-- contents/docs/feature-flags/installation.mdx | 10 ++--- .../_snippets/feature-flags-code-elixir.mdx | 42 +++++++++++++++++++ contents/docs/libraries/elixir/index.mdx | 6 ++- src/components/LibraryFeatures/index.tsx | 16 ++++--- src/navs/index.js | 3 ++ vercel.json | 5 ++- 10 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 contents/docs/integrate/feature-flags-code/_snippets/feature-flags-code-elixir.mdx diff --git a/contents/blog/how-to-measure-product-engagement.md b/contents/blog/how-to-measure-product-engagement.md index 77ab20d7b4f8..8e86a924447b 100644 --- a/contents/blog/how-to-measure-product-engagement.md +++ b/contents/blog/how-to-measure-product-engagement.md @@ -24,7 +24,11 @@ In this article we’ll take a look at why strong customer engagement metrics ar - [What is product engagement?](#what-is-product-engagement) - [What are product engagement metrics?](#what-are-product-engagement-metrics) + - [Common engagement metrics](#common-engagement-metrics) - [What is the best way to measure product engagement?](#what-is-the-best-way-to-measure-product-engagement) + - [Active users](#active-users) + - [Stickiness](#stickiness) + - [Adoption](#adoption) - [What tools are good for tracking product engagement?](#what-tools-are-good-for-tracking-product-engagement) - [Further reading](#further-reading) @@ -88,7 +92,7 @@ An easier way to track this is to use a tool such as PostHog, which has a dedica Adoption represents the number of users using key features in your product. Each new feature presents an opportunity for additional customer value. Low adoption implies that you’re offering something which users don’t need, or that there’s something wrong with the feature itself. High adoption means users are flocking to a new feature. -If users are paying for features they don’t use then it lowers the perceived value, so it’s essential to keep an eye on what isn’t working and rollback where necessary. That’s why PostHog offers tools like [feature flags](https://posthog.com/docs/user-guides/feature-flags), which help you to incrementally roll out new features and key an eye on adoption progress. If something isn’t working, you can roll it back instantly. +If users are paying for features they don’t use then it lowers the perceived value, so it’s essential to keep an eye on what isn’t working and rollback where necessary. That’s why PostHog offers tools like [feature flags](https://posthog.com/docs/feature-flags/tutorials), which help you to incrementally roll out new features and key an eye on adoption progress. If something isn’t working, you can roll it back instantly. [Flagging the use of specific features as a key event](https://posthog.com/docs/user-guides/events) per user type will also help you to track adoption.whether you’re successfully reaching the users they were intended for. diff --git a/contents/docs/experiments/adding-experiment-code.mdx b/contents/docs/experiments/adding-experiment-code.mdx index b492dfc10a1e..9dd418cb6c5c 100644 --- a/contents/docs/experiments/adding-experiment-code.mdx +++ b/contents/docs/experiments/adding-experiment-code.mdx @@ -140,9 +140,18 @@ if variant == "variant-name" { // Do something } ``` + +```elixir +{:ok, feature_flag} = PostHog.feature_flag("experiment-feature-flag-key", "user_distinct_id") + +if feature_flag.enabled == "variant-name" do + # Do something +end +``` + -> Since feature flags are not supported yet in our Java, Rust, and Elixir SDKs, to run an experiment using these SDKs see our docs on [how to run experiments without feature flags](/docs/experiments/running-experiments-without-feature-flags). This also applies to running experiments using our API. +> Since feature flags are not supported yet in our Java and Rust SDKs, to run an experiment using these SDKs see our docs on [how to run experiments without feature flags](/docs/experiments/running-experiments-without-feature-flags). This also applies to running experiments using our API. ## Step 2 (server-side only): Add the feature flag to your events diff --git a/contents/docs/experiments/installation.mdx b/contents/docs/experiments/installation.mdx index 31e88d1d7c6e..817714be71d8 100644 --- a/contents/docs/experiments/installation.mdx +++ b/contents/docs/experiments/installation.mdx @@ -29,9 +29,10 @@ import GoInstall from '../integrate/_snippets/install-go.mdx' import ReactNativeInstall from '../integrate/_snippets/install-react-native.mdx' import AndroidInstall from '../integrate/_snippets/install-android.mdx' import IOSInstall from '../integrate/_snippets/install-ios.mdx' +import ElixirInstall from '../integrate/_snippets/install-elixir.mdx' - + Web React @@ -90,9 +91,7 @@ import IOSInstall from '../integrate/_snippets/install-ios.mdx' -
- Since feature flags are not supported yet in our Elixir SDK, see our docs on how to run experiments without feature flags. -
+
diff --git a/contents/docs/feature-flags/adding-feature-flag-code.mdx b/contents/docs/feature-flags/adding-feature-flag-code.mdx index 88dc95ad9f4e..ae6f4f73c18b 100644 --- a/contents/docs/feature-flags/adding-feature-flag-code.mdx +++ b/contents/docs/feature-flags/adding-feature-flag-code.mdx @@ -24,6 +24,7 @@ import ReactNativeFeatureFlagsCode from '../integrate/feature-flags-code/_snippe import AndroidFeatureFlagsCode from '../integrate/feature-flags-code/_snippets/feature-flags-code-android.mdx' import IOSFeatureFlagsCode from '../integrate/feature-flags-code/_snippets/feature-flags-code-ios.mdx' import FlutterFeatureFlagsCode from '../integrate/feature-flags-code/_snippets/feature-flags-code-flutter.mdx' +import ElixirFeatureFlagsCode from '../integrate/feature-flags-code/_snippets/feature-flags-code-elixir.mdx' @@ -89,9 +90,7 @@ import FlutterFeatureFlagsCode from '../integrate/feature-flags-code/_snippets/f
-
- Feature flags are not supported yet in our Elixir SDK. However, you can integrate them into your project by using the PostHog API. -
+
diff --git a/contents/docs/feature-flags/installation.mdx b/contents/docs/feature-flags/installation.mdx index c74bff406039..396389bf5db3 100644 --- a/contents/docs/feature-flags/installation.mdx +++ b/contents/docs/feature-flags/installation.mdx @@ -33,7 +33,7 @@ import FlutterInstall from '../integrate/_snippets/install-flutter.mdx' import ElixirInstall from '../integrate/_snippets/install-elixir.mdx' - + Web React @@ -47,8 +47,8 @@ import ElixirInstall from '../integrate/_snippets/install-elixir.mdx' iOS Java Rust - Elixir Flutter + Elixir API @@ -93,12 +93,10 @@ import ElixirInstall from '../integrate/_snippets/install-elixir.mdx' -
- Feature flags are not supported yet in our Elixir SDK. However, you can integrate them into your project by using the PostHog API. -
+
- + diff --git a/contents/docs/integrate/feature-flags-code/_snippets/feature-flags-code-elixir.mdx b/contents/docs/integrate/feature-flags-code/_snippets/feature-flags-code-elixir.mdx new file mode 100644 index 000000000000..1d18a74319c9 --- /dev/null +++ b/contents/docs/integrate/feature-flags-code/_snippets/feature-flags-code-elixir.mdx @@ -0,0 +1,42 @@ +Elixir supports a subset of what our [feature flag API](/docs/api/decide) provides. + +#### Boolean feature flags + +```elixir +is_my_flag_enabled = Posthog.feature_flag_enabled?("flag-key", "distinct_id_of_your_user") + +if is_my_flag_enabled + # Do something differently for this user + # Optional: fetch the payload + {:ok, feature_flag} = Posthog.feature_flag("flag-key", "distinct_id_of_your_user") +end +``` + +#### Multivariate feature flags + +```elixir +{:ok, feature_flag} = Posthog.feature_flag("flag-key", "distinct_id_of_your_user") +# %Posthog.FeatureFlag{ name: "flag-key", value: %{"variant-1" => "value-1", "variant-2" => "value-2"}, enabled: "variant-2" } + +if feature_flag.enabled == 'variant-2' # replace 'variant-2' with the key of your variant + # Do something differently for this user +end +``` + +#### Fetching all feature flags + +```elixir +Posthog.feature_flags("distinct_id_of_your_user") + +{:ok, + %{ + "featureFlagPayloads" => %{ + "feature-1" => 1, + "feature-2" => %{"variant-1" => "value-1", "variant-2" => "value-2"} + }, + "featureFlags" => %{"feature-1" => true, "feature-2" => "variant-2"} + }} + +``` + +More documentation can be found in the [repository](https://github.com/nkezhaya/posthog). \ No newline at end of file diff --git a/contents/docs/libraries/elixir/index.mdx b/contents/docs/libraries/elixir/index.mdx index 379602610aaf..50c82656d047 100644 --- a/contents/docs/libraries/elixir/index.mdx +++ b/contents/docs/libraries/elixir/index.mdx @@ -11,7 +11,7 @@ icon: >- features: eventCapture: true userIdentification: true - featureFlags: false + featureFlags: true groupAnalytics: true surveys: false llmObservability: false @@ -38,7 +38,9 @@ import FeatureFlagsLibsIntro from "../_snippets/feature-flags-libs-intro.mdx" -Feature flags are not supported yet in our Elixir SDK. However, you can integrate them into your project by using the [PostHog API](/docs/feature-flags/adding-feature-flag-code?tab=api). +import ElixirFeatureFlagsCode from '../../integrate/feature-flags-code/_snippets/feature-flags-code-elixir.mdx' + + ## Thanks diff --git a/src/components/LibraryFeatures/index.tsx b/src/components/LibraryFeatures/index.tsx index 964548469093..8a1806f85319 100644 --- a/src/components/LibraryFeatures/index.tsx +++ b/src/components/LibraryFeatures/index.tsx @@ -9,16 +9,20 @@ const features = [ { key: 'autoCapture', name: 'Autocapture', - url: 'https://posthog.com/docs/data/autocapture', + url: 'https://posthog.com/docs/product-analytics/autocapture', }, { key: 'userIdentification', name: 'User identification', - url: 'https://posthog.com/docs/integrate/identifying-users', + url: 'https://posthog.com/docs/product-analytics/identify', + }, + { key: 'sessionRecording', name: 'Session replay', url: 'https://posthog.com/docs/session-replay' }, + { key: 'featureFlags', name: 'Feature flags', url: 'https://posthog.com/docs/feature-flags' }, + { + key: 'groupAnalytics', + name: 'Group analytics', + url: 'https://posthog.com/docs/product-analytics/group-analytics', }, - { key: 'sessionRecording', name: 'Session replay', url: 'https://posthog.com/docs/user-guides/recordings' }, - { key: 'featureFlags', name: 'Feature flags', url: 'https://posthog.com/docs/user-guides/feature-flags' }, - { key: 'groupAnalytics', name: 'Group analytics', url: 'https://posthog.com/docs/user-guides/group-analytics' }, { key: 'surveys', name: 'Surveys', url: 'https://posthog.com/docs/surveys' }, { key: 'llmObservability', @@ -29,7 +33,7 @@ const features = [ ] as const export type LibraryFeaturesProps = { - availability?: Record + availability?: Record<(typeof features)[number]['key'], boolean> } export const LibraryFeatures = ({ availability }: LibraryFeaturesProps) => { diff --git a/src/navs/index.js b/src/navs/index.js index 5ce89d7996b5..667f681b2bf3 100644 --- a/src/navs/index.js +++ b/src/navs/index.js @@ -1300,6 +1300,9 @@ export const docsMenu = { { name: 'Elixir', url: '/docs/libraries/elixir', + badge: { + title: '3rd party', + }, }, { name: 'Flutter', diff --git a/vercel.json b/vercel.json index 6faa4056a312..52e561754707 100644 --- a/vercel.json +++ b/vercel.json @@ -128,7 +128,6 @@ { "source": "/docs/features/cohorts", "destination": "/docs/user-guides/cohorts" }, { "source": "/docs/features/dashboards", "destination": "/docs/user-guides/dashboards" }, { "source": "/docs/features/events", "destination": "/docs/user-guides/events" }, - { "source": "/docs/features/feature-flags", "destination": "/docs/user-guides/feature-flags" }, { "source": "/docs/features/funnels", "destination": "/docs/user-guides/funnels" }, { "source": "/docs/features/organizations", "destination": "/docs/user-guides/organizations" }, { "source": "/docs/features/paths", "destination": "/docs/user-guides/paths" }, @@ -676,7 +675,9 @@ { "source": "/docs/experiments/under-the-hood", "destination": "/docs/experiments/experiment-significance" }, { "source": "/docs/experiments/significance", "destination": "/docs/experiments/experiment-significance" }, { "source": "/docs/session-replay/manual", "destination": "/docs/session-replay/installation" }, - { "source": "/docs/user-guides/feature-flags", "destination": "/docs/feature-flags/manual" }, + { "source": "/docs/features/feature-flags", "destination": "/docs/feature-flags" }, + { "source": "/docs/user-guides/feature-flags", "destination": "/docs/feature-flags" }, + { "source": "/docs/feature-flags/manual", "destination": "/docs/feature-flags" }, { "source": "/manual/group-analytics", "destination": "/docs/product-analytics/group-analytics" }, { "source": "/docs/product-analytics/hogql", "destination": "/docs/hogql" }, { "source": "/docs/hogql/guide", "destination": "/docs/product-analytics/sql" },