-
Notifications
You must be signed in to change notification settings - Fork 482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write up documentation on posthog-dotnet #10589
Changes from all commits
4f3c5e8
f02dc6e
46c26c9
78b2e12
c682366
fc9e314
0984538
d6ed75d
ff0f0df
4fd8557
930fd63
76d7ee0
968a0e4
71b7441
64d7adc
cd25ee7
a2b0924
8a1249f
2b8e127
a45dda0
806eab2
3dc579a
de25e3e
af47c22
422a063
703b97d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,55 @@ | ||||||||||
<DotNetInstall /> | ||||||||||
|
||||||||||
At the moment, ASP.NET Core is the only supported platform for the PostHog .NET SDK. | ||||||||||
|
||||||||||
```bash | ||||||||||
dotnet add package PostHog.AspNetCore | ||||||||||
``` | ||||||||||
|
||||||||||
In your `Program.cs` file, add the following code: | ||||||||||
|
||||||||||
```csharp | ||||||||||
using PostHog.AspNetCore; | ||||||||||
|
||||||||||
var builder = WebApplication.CreateBuilder(args); | ||||||||||
|
||||||||||
builder.AddPostHog(); | ||||||||||
``` | ||||||||||
|
||||||||||
Make sure to configure PostHog with your project API key, instance address, and optional personal API key. For example, in appsettings.json: | ||||||||||
|
||||||||||
```json | ||||||||||
{ | ||||||||||
"PostHog": { | ||||||||||
"ProjectApiKey": "phc_...", | ||||||||||
"Host": "https://us.i.posthog.com" | ||||||||||
Comment on lines
+24
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These will automatically fill with values if they exist
Suggested change
|
||||||||||
} | ||||||||||
} | ||||||||||
``` | ||||||||||
|
||||||||||
> **Note:** If the host is not specified, the default host `https://us.i.posthog.com` is used. | ||||||||||
|
||||||||||
Use a secrets manager to store your personal API key. For example, when developing locally you can use the `UserSecrets` feature of the `dotnet` CLI: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
```bash | ||||||||||
dotnet user-secrets init | ||||||||||
dotnet user-secrets set "PostHog:PersonalApiKey" "phc_..." | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
``` | ||||||||||
|
||||||||||
You can find your project API key and instance address in the [project settings](https://app.posthog.com/project/settings) page in PostHog. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
To see detailed logging, set the log level to `Debug` or `Trace` in `appsettings.json`: | ||||||||||
|
||||||||||
```json | ||||||||||
{ | ||||||||||
"DetailedErrors": true, | ||||||||||
"Logging": { | ||||||||||
"LogLevel": { | ||||||||||
"Default": "Information", | ||||||||||
"Microsoft.AspNetCore": "Warning", | ||||||||||
"PostHog": "Trace" | ||||||||||
} | ||||||||||
}, | ||||||||||
... | ||||||||||
} | ||||||||||
``` |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,13 @@ | ||||||
The `Capture()` method has an optional argument `sendFeatureFlags`, which is set to `false` by default. By setting this to `true`, feature flag information will automatically be sent with the event. | ||||||
|
||||||
Note that by doing this, PostHog will make an additional request to fetch feature flag information before capturing the event. So this method is only recommended if you don't mind the extra API call and delay. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
```csharp | ||||||
posthog.Capture( | ||||||
"distinct_id_of_your_user", | ||||||
"event_name", | ||||||
properties: null, | ||||||
groups: null, | ||||||
sendFeatureFlags: true | ||||||
); | ||||||
``` |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,119 @@ | ||||||
There are 2 steps to implement feature flags in .NET: | ||||||
|
||||||
### Step 1: Evaluate the feature flag value | ||||||
|
||||||
#### Boolean feature flags | ||||||
|
||||||
```csharp | ||||||
var isMyFlagEnabled = await posthog.IsFeatureEnabledAsync( | ||||||
"flag-key", | ||||||
"distinct_id_of_your_user" | ||||||
); | ||||||
if (isMyFlagEnabled.GetValueOrDefault()) | ||||||
{ | ||||||
// Feature is enabled | ||||||
} | ||||||
else | ||||||
{ | ||||||
// Feature is disabled | ||||||
} | ||||||
``` | ||||||
|
||||||
> **Note:** The `IsFeatureEnabledAsync` method returns a nullable boolean. If the flag is not found or evaluating it is inconclusive, it returns `null`. | ||||||
|
||||||
#### Multivariate feature flags | ||||||
|
||||||
```csharp | ||||||
var flag = await posthog.GetFeatureFlagAsync( | ||||||
"flag-key", | ||||||
"distinct_id_of_your_user" | ||||||
); | ||||||
|
||||||
// replace "variant-key" with the key of your variant | ||||||
if (flag is { VariantKey: "variant-key"} ) { | ||||||
// Do something differently for this user | ||||||
// Optional: fetch the payload | ||||||
var matchedPayload = flag.Payload; | ||||||
} | ||||||
``` | ||||||
|
||||||
The `GetFeatureFlagAsync` method returns a nullable `FeatureFlag` object. If the flag is not found or evaluating it is inconclusive, it returns `null`. However, there is an implicit conversion to bool to make comparisons easier. | ||||||
|
||||||
```csharp | ||||||
if (await posthog.GetFeatureFlagAsync( | ||||||
"flag-key", | ||||||
"distinct_id_of_your_user") | ||||||
) | ||||||
{ | ||||||
// Do something differently for this user | ||||||
} | ||||||
``` | ||||||
|
||||||
import IncludePropertyInEvents from "./include-feature-flag-property-in-backend-events.mdx" | ||||||
|
||||||
<IncludePropertyInEvents /> | ||||||
|
||||||
There are two methods you can use to include feature flag information in your events: | ||||||
|
||||||
#### Method 1: Include the `$feature/feature_flag_name` property | ||||||
|
||||||
In the event properties, include `$feature/feature_flag_name: variant_key`: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
```csharp | ||||||
posthog.Capture( | ||||||
"distinct_id_of_your_user", | ||||||
"event_name", | ||||||
properties: new() { | ||||||
// replace feature-flag-key with your flag key. | ||||||
// Replace 'variant-key' with the key of your variant | ||||||
["$feature/feature-flag-key"] = "variant-key" | ||||||
} | ||||||
); | ||||||
``` | ||||||
|
||||||
#### Method 2: Set `send_feature_flags` to `true` | ||||||
|
||||||
import DotNetSetSendFeatureFlagsTrue from "./feature-flags-code-dotnet-set-send-feature-flags-to-true.mdx" | ||||||
|
||||||
<DotNetSetSendFeatureFlagsTrue /> | ||||||
|
||||||
### Fetching all flags for a user | ||||||
|
||||||
You can fetch all flag values for a single user by calling `GetAllFeatureFlagsAsync()`. | ||||||
|
||||||
This is useful when you need to fetch multiple flag values and don't want to make multiple requests. | ||||||
|
||||||
```csharp | ||||||
var flags = await posthog.GetAllFeatureFlagsAsync( | ||||||
"distinct_id_of_your_user" | ||||||
); | ||||||
``` | ||||||
|
||||||
### Sending `$feature_flag_called` events | ||||||
|
||||||
Capturing `$feature_flag_called` events enable PostHog to know when a flag was accessed by a user and thus provide [analytics and insights](/docs/product-analytics/insights) on the flag. By default, we send a these event when: | ||||||
|
||||||
1. You call `posthog.GetFeatureFlagAsync()` or `posthog.IsFeatureEnabledAsync()`, AND | ||||||
2. It's a new user, or the value of the flag has changed. | ||||||
|
||||||
> *Note:* Tracking whether it's a new user or if a flag value has changed happens in a local cache. This means that if you reinitialize the PostHog client, the cache resets as well – causing `$feature_flag_called` events to be sent again when calling `GetFeatureFlagAsync` or `IsFeatureEnabledAsync`. PostHog is built to handle this, and so duplicate `$feature_flag_called` events won't affect your analytics. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
You can disable automatically the additional request to capture `$feature_flag_called` events. For example, when you don't need the analytics, or it's being called at such a high volume that sending events slows things down. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
To disable it, set the `sendFeatureFlagsEvent` option in your function call, like so: | ||||||
|
||||||
```csharp | ||||||
var isMyFlagEnabled = await posthog.IsFeatureEnabledAsync( | ||||||
"flag-key", | ||||||
"distinct_id_of_your_user", | ||||||
options: new FeatureFlagOptions | ||||||
{ | ||||||
SendFeatureFlagEvents = true | ||||||
} | ||||||
); | ||||||
// will not send `$feature_flag_called` events | ||||||
Comment on lines
+111
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be false? |
||||||
``` | ||||||
|
||||||
import DotNetOverrideServerProperties from './override-server-properties/dotnet.mdx' | ||||||
|
||||||
<DotNetOverrideServerProperties /> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import OverrideServerPropertiesIntro from './override-server-properties-intro.mdx' | ||
|
||
<OverrideServerPropertiesIntro /> | ||
|
||
```csharp | ||
var flag = await posthog.GetFeatureFlagAsync( | ||
"flag-key", | ||
"distinct_id_of_the_user", | ||
options: new FeatureFlagOptions | ||
{ | ||
PersonProperties = new() { ["property_name"] = "value" }, | ||
Groups = [ | ||
new Group("your_group_type", "your_group_id") | ||
{ | ||
["group_property_name"] = "your group value" | ||
}, | ||
new Group( | ||
"another_group_type", | ||
"another_group_id", | ||
new Dictionary<string, object?> | ||
{ | ||
["group_property_name"] = "another group value" | ||
} | ||
) | ||
] | ||
}); | ||
``` | ||
|
||
import OverrideGeoIPPropertiesSDK from './override-geoip-properties-SDKs.mdx' | ||
|
||
<OverrideGeoIPPropertiesSDK /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.