From f9865a158eca5f23dfa23176cb418c8a75019ed8 Mon Sep 17 00:00:00 2001 From: Zach Waterfield Date: Tue, 19 Mar 2024 10:03:24 -0600 Subject: [PATCH] feat: add reverse proxy step to onboarding for feature flags (#20906) * Add reverse proxy step to onboarding for feature flags * Make the invite step standout less * Add feature flag for reverse proxy on feature flag onboarding * Remove uneeded continueAction --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- frontend/src/lib/constants.tsx | 1 + frontend/src/scenes/onboarding/Onboarding.tsx | 8 +- .../onboarding/OnboardingReverseProxy.tsx | 87 +++++++++++++++++++ .../src/scenes/onboarding/OnboardingStep.tsx | 4 +- .../src/scenes/onboarding/onboardingLogic.tsx | 11 +++ 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 frontend/src/scenes/onboarding/OnboardingReverseProxy.tsx diff --git a/frontend/src/lib/constants.tsx b/frontend/src/lib/constants.tsx index 522d393f0f9a6..9d667db41b2ed 100644 --- a/frontend/src/lib/constants.tsx +++ b/frontend/src/lib/constants.tsx @@ -210,6 +210,7 @@ export const FEATURE_FLAGS = { REPLAY_ERROR_CLUSTERING: 'session-replay-error-clustering', // owner: #team-replay AUDIT_LOGS_ACCESS: 'audit-logs-access', // owner: #team-growth SUBSCRIBE_FROM_PAYGATE: 'subscribe-from-paygate', // owner: #team-growth + REVERSE_PROXY_ONBOARDING: 'reverse-proxy-onboarding', // owner: @zlwaterfield } as const export type FeatureFlagKey = (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS] diff --git a/frontend/src/scenes/onboarding/Onboarding.tsx b/frontend/src/scenes/onboarding/Onboarding.tsx index 569760e106bf6..52efdd5d47f0a 100644 --- a/frontend/src/scenes/onboarding/Onboarding.tsx +++ b/frontend/src/scenes/onboarding/Onboarding.tsx @@ -13,6 +13,7 @@ import { onboardingLogic, OnboardingStepKey } from './onboardingLogic' import { OnboardingProductConfiguration } from './OnboardingProductConfiguration' import { ProductConfigOption } from './onboardingProductConfigurationLogic' import { OnboardingProductIntroduction } from './OnboardingProductIntroduction' +import { OnboardingReverseProxy } from './OnboardingReverseProxy' import { FeatureFlagsSDKInstructions } from './sdks/feature-flags/FeatureFlagsSDKInstructions' import { ProductAnalyticsSDKInstructions } from './sdks/product-analytics/ProductAnalyticsSDKInstructions' import { SDKs } from './sdks/SDKs' @@ -28,7 +29,8 @@ export const scene: SceneExport = { * Wrapper for custom onboarding content. This automatically includes billing, other products, and invite steps. */ const OnboardingWrapper = ({ children }: { children: React.ReactNode }): JSX.Element => { - const { currentOnboardingStep, shouldShowBillingStep, product, includeIntro } = useValues(onboardingLogic) + const { currentOnboardingStep, shouldShowBillingStep, shouldShowReverseProxyStep, product, includeIntro } = + useValues(onboardingLogic) const { setAllOnboardingSteps } = useActions(onboardingLogic) const [allSteps, setAllSteps] = useState([]) @@ -58,6 +60,10 @@ const OnboardingWrapper = ({ children }: { children: React.ReactNode }): JSX.Ele const IntroStep = steps = [IntroStep, ...steps] } + if (shouldShowReverseProxyStep) { + const ReverseProxyStep = + steps = [...steps, ReverseProxyStep] + } if (shouldShowBillingStep) { const BillingStep = steps = [...steps, BillingStep] diff --git a/frontend/src/scenes/onboarding/OnboardingReverseProxy.tsx b/frontend/src/scenes/onboarding/OnboardingReverseProxy.tsx new file mode 100644 index 0000000000000..362ce6c34a2ce --- /dev/null +++ b/frontend/src/scenes/onboarding/OnboardingReverseProxy.tsx @@ -0,0 +1,87 @@ +import { LemonDivider, Link } from '@posthog/lemon-ui' + +import { InviteMembersButton } from '~/layout/navigation/TopBar/AccountPopover' + +import { OnboardingStepKey } from './onboardingLogic' +import { OnboardingStep } from './OnboardingStep' + +const proxyDocs = [ + { + title: 'AWS CloudFront', + link: 'https://posthog.com/docs/advanced/proxy/cloudfront', + }, + { + title: 'Caddy', + link: 'https://posthog.com/docs/advanced/proxy/caddy', + }, + { + title: 'Cloudflare', + link: 'https://posthog.com/docs/advanced/proxy/cloudflare', + }, + { + title: 'Kubernetes Ingress Controller', + link: 'https://posthog.com/docs/advanced/proxy/kubernetes-ingress-controller', + }, + { + title: 'Netlify', + link: 'https://posthog.com/docs/advanced/proxy/netlify', + }, + { + title: 'Next.js rewrites', + link: 'https://posthog.com/docs/advanced/proxy/nextjs', + }, + { + title: 'Next.js middleware', + link: 'https://posthog.com/docs/advanced/proxy/nextjs-middleware', + }, + { + title: 'Vercel', + link: 'https://posthog.com/docs/advanced/proxy/vercel', + }, + { + title: 'Nuxt', + link: 'https://posthog.com/docs/advanced/proxy/nuxt', + }, +] + +export const OnboardingReverseProxy = ({ stepKey }: { stepKey: OnboardingStepKey }): JSX.Element => { + return ( + +
+

A reverse proxy allows you to send events to PostHog Cloud using your own domain.

+

+ This means that events are sent from your own domain and are less likely to be intercepted by + tracking blockers. You'll be able to capture more usage data without having to self-host PostHog. +

+

+ Setting up a reverse proxy means setting up a service to redirect requests from a subdomain you + choose (like e.yourdomain.com) to PostHog. It is best + practice to use a subdomain that does not include posthog, analytics, tracking, or other similar + words. +

+

Documentation

+

Here are some popular reverse proxy options:

+
    + {proxyDocs.map(({ title, link }) => ( +
  • + + {title} + +
  • + ))} +
+ +

Need help with this step?

+

Invite a team member to help you get set up.

+
+ +
+
+
+ ) +} diff --git a/frontend/src/scenes/onboarding/OnboardingStep.tsx b/frontend/src/scenes/onboarding/OnboardingStep.tsx index ddb081b343919..5e54171335aed 100644 --- a/frontend/src/scenes/onboarding/OnboardingStep.tsx +++ b/frontend/src/scenes/onboarding/OnboardingStep.tsx @@ -16,6 +16,7 @@ export const OnboardingStep = ({ showHelpButton = false, onSkip, continueAction, + continueText, continueOverride, hideHeader, }: { @@ -27,6 +28,7 @@ export const OnboardingStep = ({ showHelpButton?: boolean onSkip?: () => void continueAction?: () => void + continueText?: string continueOverride?: JSX.Element hideHeader?: boolean }): JSX.Element => { @@ -114,7 +116,7 @@ export const OnboardingStep = ({ }} sideIcon={hasNextStep ? : null} > - {!hasNextStep ? 'Finish' : 'Next'} + {continueText ? continueText : !hasNextStep ? 'Finish' : 'Next'} )} diff --git a/frontend/src/scenes/onboarding/onboardingLogic.tsx b/frontend/src/scenes/onboarding/onboardingLogic.tsx index 8857c73b7fe42..feff28d1b4579 100644 --- a/frontend/src/scenes/onboarding/onboardingLogic.tsx +++ b/frontend/src/scenes/onboarding/onboardingLogic.tsx @@ -23,6 +23,7 @@ export enum OnboardingStepKey { PLANS = 'plans', VERIFY = 'verify', PRODUCT_CONFIGURATION = 'configure', + REVERSE_PROXY = 'proxy', INVITE_TEAMMATES = 'invite_teammates', } @@ -208,6 +209,16 @@ export const onboardingLogic = kea([ return !product?.subscribed || !hasAllAddons || subscribedDuringOnboarding }, ], + shouldShowReverseProxyStep: [ + (s) => [s.product, s.featureFlags], + (product: BillingProductV2Type | null, featureFlags: FeatureFlagsSet) => { + const productsWithReverseProxy = [] + if (featureFlags[FEATURE_FLAGS.REVERSE_PROXY_ONBOARDING] === 'test') { + productsWithReverseProxy.push(ProductKey.FEATURE_FLAGS) + } + return productsWithReverseProxy.includes(product?.type as ProductKey) + }, + ], isStepKeyInvalid: [ (s) => [s.stepKey, s.allOnboardingSteps, s.currentOnboardingStep], (stepKey: string, allOnboardingSteps: AllOnboardingSteps, currentOnboardingStep: React.ReactNode | null) =>