-
Notifications
You must be signed in to change notification settings - Fork 3
update posthog, add useFeatureFlagsLoaded #2720
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
Changes from all commits
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,53 @@ | ||
| import { INTERNAL_BOOTSTRAPPING_FLAG } from "@/common/feature_flags" | ||
| import { useFeatureFlagEnabled, usePostHog } from "posthog-js/react" | ||
| import { useEffect, useState } from "react" | ||
|
|
||
| /** | ||
| * Returns `true` if feature flags have been loaded via posthog API, else `false`. | ||
| * | ||
| * NOTES: | ||
| * 1. Avoid using this! Really!: | ||
| * - This can delay feature flag availability for users who have been to the | ||
| * site before. Their flags will be bootstrapped from localStorage, and should | ||
| * have the correct values immediately, before contacting the PostHog server. | ||
| * - We generally shouldn't care if a flag is "false" or | ||
| * "not loaded yet". | ||
| * | ||
| * USE CASE: One case where this distinction matters is when an entire page | ||
| * is behind a feature flag, and we don't want to 404 until the flags are | ||
| * loaded. | ||
| * 2. Unlike posthog's `onFeatureFlags` callback, this hook enables you to | ||
| * distinguish between bootstrapped flags and flags loaded from PostHog server. | ||
| * | ||
| * IMPLEMENTATION: | ||
| * Posthog does not make detecting "flags have loaded from server" easy. | ||
| * This approach relies on the fact that bootstrapped flags are completely | ||
| * discarded after flags are loaded from server, so `useFlagEnabled` will | ||
| * return `undefined` for any flag that was only bootstrapped locally. | ||
|
Contributor
Author
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. posthog's AI suggested this approach and it seems to work well... |
||
| */ | ||
| const useFeatureFlagsLoaded = () => { | ||
| const posthog = usePostHog() | ||
| const [hasBootstrapped, setHasBootstrapped] = useState(false) | ||
| useEffect(() => { | ||
| /** | ||
| * NOTE: this does not indicate flags have loaded from server, so they might | ||
| * be incomplete. It does at least indicate that localstorage/bootstrapped | ||
| * flags are ready | ||
| * | ||
| * If this event listener is added after posthog has fully loaded flags, | ||
| * the callback is still fired. | ||
| */ | ||
| return posthog.onFeatureFlags(() => { | ||
| setHasBootstrapped(true) | ||
| }) | ||
| }, [posthog]) | ||
| const bootstrapFlag = useFeatureFlagEnabled(INTERNAL_BOOTSTRAPPING_FLAG) | ||
| /** | ||
| * bootstrapFlag will be undefined: | ||
| * 1. BEFORE posthog has initialized (nothing bootstrapped yet) | ||
| * 2. AFTER posthog has loaded flags from its server. | ||
|
Contributor
Author
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. Posthog docs have always said, apparently that This actually isn't true in the version of posthog-js on |
||
| */ | ||
| return hasBootstrapped && bootstrapFlag === undefined | ||
| } | ||
|
|
||
| export { useFeatureFlagsLoaded } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,20 +2,12 @@ import React, { useEffect } from "react" | |
| import posthog from "posthog-js" | ||
| import { PostHogProvider, usePostHog } from "posthog-js/react" | ||
| import { useUserMe } from "api/hooks/user" | ||
| import { INTERNAL_BOOTSTRAPPING_FLAG } from "@/common/feature_flags" | ||
|
|
||
| const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY | ||
| const POSTHOG_API_HOST = process.env.NEXT_PUBLIC_POSTHOG_API_HOST | ||
| const FEATURE_FLAGS = process.env.FEATURE_FLAGS | ||
|
|
||
| if (POSTHOG_API_KEY) { | ||
|
Contributor
Author
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. For nextjs, Posthog docs recommend initializing either
The current top-level initialization caused hydration errors, too. Initializing inside the provider effect does not.
Contributor
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. Does this prevent all feature flagged content from being server rendered, even if we have environment defaults? I guess they need to be as content appearing is better than content disappearing.
Contributor
Author
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. It does. Though that also wasn't happening with the current placement of posthog init code. On RC currently:
I do think we could get server-side flagging of the bootstrapped values to work, though. |
||
| posthog.init(POSTHOG_API_KEY, { | ||
| api_host: POSTHOG_API_HOST, | ||
| bootstrap: { | ||
| featureFlags: FEATURE_FLAGS ? JSON.parse(FEATURE_FLAGS) : null, | ||
| }, | ||
| }) | ||
| } | ||
|
|
||
| const PosthogIdentifier = () => { | ||
| const { data: user } = useUserMe() | ||
| const posthog = usePostHog() | ||
|
|
@@ -45,6 +37,22 @@ const PosthogIdentifier = () => { | |
| const ConfiguredPostHogProvider: React.FC<{ children: React.ReactNode }> = ({ | ||
| children, | ||
| }) => { | ||
| useEffect(() => { | ||
| if (POSTHOG_API_KEY) { | ||
| posthog.init(POSTHOG_API_KEY, { | ||
| api_host: POSTHOG_API_HOST, | ||
| bootstrap: { | ||
| featureFlags: FEATURE_FLAGS | ||
| ? { | ||
| ...JSON.parse(FEATURE_FLAGS), | ||
| [INTERNAL_BOOTSTRAPPING_FLAG]: true, | ||
| } | ||
| : null, | ||
| }, | ||
| }) | ||
| } | ||
| }, []) | ||
|
|
||
| if (!POSTHOG_API_KEY) { | ||
| return children | ||
| } | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.
If you change these lines to
you would see values something like