diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 3bea75f22d718..bf2bb2acb87cd 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -10,6 +10,7 @@ import { withMockDate } from './decorators/withMockDate' import { defaultMocks } from '~/mocks/handlers' import { withFeatureFlags } from './decorators/withFeatureFlags' import { withTheme } from './decorators/withTheme' +import { apiHostOrigin } from 'lib/utils/apiHost' const setupMsw = () => { // Make sure the msw worker is started @@ -35,7 +36,7 @@ setupMsw() const setupPosthogJs = () => { // Make sure we don't hit production posthog. We want to control requests to, // e.g. `/decide/` for feature flags - window.JS_POSTHOG_HOST = window.location.origin + window.JS_POSTHOG_HOST = apiHostOrigin() loadPostHogJS() } diff --git a/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--dark.png b/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--dark.png index a6b4b17cddcb5..8824662e53811 100644 Binary files a/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--dark.png and b/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--light.png b/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--light.png index 08b55ba654e93..efb0dd869a8f2 100644 Binary files a/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--light.png and b/frontend/__snapshots__/scenes-app-experiments--experiments-list-pay-gate--light.png differ diff --git a/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--dark.png b/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--dark.png index 533ff0867e10d..42103d895b3a7 100644 Binary files a/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--dark.png and b/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--light.png b/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--light.png index 5d487ebbcf014..2cf251a981417 100644 Binary files a/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--light.png and b/frontend/__snapshots__/scenes-app-experiments--view-experiment-pay-gate--light.png differ diff --git a/frontend/src/layout/navigation/TopBar/AccountPopover.tsx b/frontend/src/layout/navigation/TopBar/AccountPopover.tsx index f66ff1a99a8c3..b42cb02e0a690 100644 --- a/frontend/src/layout/navigation/TopBar/AccountPopover.tsx +++ b/frontend/src/layout/navigation/TopBar/AccountPopover.tsx @@ -1,6 +1,14 @@ import './AccountPopover.scss' -import { IconCheckCircle, IconFeatures, IconGear, IconLive, IconPlusSmall, IconServer } from '@posthog/icons' +import { + IconCheckCircle, + IconConfetti, + IconFeatures, + IconGear, + IconLive, + IconPlusSmall, + IconServer, +} from '@posthog/icons' import { LemonButtonPropsBase } from '@posthog/lemon-ui' import clsx from 'clsx' import { useActions, useValues } from 'kea' @@ -10,7 +18,6 @@ import { Lettermark } from 'lib/lemon-ui/Lettermark' import { ProfilePicture } from 'lib/lemon-ui/ProfilePicture' import { Tooltip } from 'lib/lemon-ui/Tooltip' import { eventUsageLogic } from 'lib/utils/eventUsageLogic' -import { billingLogic } from 'scenes/billing/billingLogic' import { inviteLogic } from 'scenes/settings/organization/inviteLogic' import { ThemeSwitcher } from 'scenes/settings/user/ThemeSwitcher' @@ -183,11 +190,10 @@ function SignOutButton(): JSX.Element { export function AccountPopoverOverlay(): JSX.Element { const { user, otherOrganizations } = useValues(userLogic) const { currentOrganization } = useValues(organizationLogic) - const { preflight } = useValues(preflightLogic) const { mobileLayout } = useValues(navigationLogic) - const { closeAccountPopover } = useActions(navigationLogic) - const { billing } = useValues(billingLogic) const { openSidePanel } = useActions(sidePanelStateLogic) + const { preflight, isCloudOrDev } = useValues(preflightLogic) + const { closeAccountPopover } = useActions(navigationLogic) return ( <> @@ -196,7 +202,7 @@ export function AccountPopoverOverlay(): JSX.Element { {currentOrganization && } - {preflight?.cloud || !!billing ? ( + {isCloudOrDev ? ( {user?.is_staff && } + {!isCloudOrDev && ( + + } + fullWidth + data-attr="top-menu-item-upgrade-to-cloud" + > + Try PostHog Cloud + + + )} diff --git a/frontend/src/lib/components/AuthorizedUrlList/authorizedUrlListLogic.ts b/frontend/src/lib/components/AuthorizedUrlList/authorizedUrlListLogic.ts index 652d357130452..d4412601b22da 100644 --- a/frontend/src/lib/components/AuthorizedUrlList/authorizedUrlListLogic.ts +++ b/frontend/src/lib/components/AuthorizedUrlList/authorizedUrlListLogic.ts @@ -18,6 +18,7 @@ import { encodeParams, urlToAction } from 'kea-router' import { subscriptions } from 'kea-subscriptions' import api from 'lib/api' import { isDomain, isURL } from 'lib/utils' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' import { urls } from 'scenes/urls' @@ -70,7 +71,7 @@ export function appEditorUrl(appUrl: string, actionId?: number | null, defaultIn // the toolbar, which isn't correct when used behind a reverse proxy as // we require e.g. SSO login to the app, which will not work when placed // behind a proxy unless we register each domain with the OAuth2 client. - apiURL: window.location.origin, + apiURL: apiHostOrigin(), appUrl, ...(actionId ? { actionId } : {}), } diff --git a/frontend/src/lib/components/JSSnippet.tsx b/frontend/src/lib/components/JSSnippet.tsx index 3d13f23c49c95..8fb5f32277d31 100644 --- a/frontend/src/lib/components/JSSnippet.tsx +++ b/frontend/src/lib/components/JSSnippet.tsx @@ -1,5 +1,6 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' export function JSSnippet(): JSX.Element { @@ -8,9 +9,7 @@ export function JSSnippet(): JSX.Element { return ( {``} ) } diff --git a/frontend/src/lib/components/PayGateMini/PayGateMini.tsx b/frontend/src/lib/components/PayGateMini/PayGateMini.tsx index 1fc4ac3e22fbb..e8a3330bcdd82 100644 --- a/frontend/src/lib/components/PayGateMini/PayGateMini.tsx +++ b/frontend/src/lib/components/PayGateMini/PayGateMini.tsx @@ -6,6 +6,7 @@ import { useValues } from 'kea' import { FEATURE_MINIMUM_PLAN, POSTHOG_CLOUD_STANDARD_PLAN } from 'lib/constants' import { IconEmojiPeople, IconLightBulb, IconLock, IconPremium } from 'lib/lemon-ui/icons' import { LemonButton } from 'lib/lemon-ui/LemonButton' +import { capitalizeFirstLetter } from 'lib/utils' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' import { userLogic } from 'scenes/userLogic' @@ -102,21 +103,22 @@ export function PayGateMini({ children, overrideShouldShowGate, }: PayGateMiniProps): JSX.Element | null { - const { preflight } = useValues(preflightLogic) + const { preflight, isCloudOrDev } = useValues(preflightLogic) const { hasAvailableFeature } = useValues(userLogic) const featureSummary = FEATURE_SUMMARIES[feature] const planRequired = FEATURE_MINIMUM_PLAN[feature] - let gateVariant: 'add-card' | 'contact-sales' | 'subscribe' | null = null + + let gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null = null if (!overrideShouldShowGate && !hasAvailableFeature(feature)) { - if (preflight?.cloud) { + if (isCloudOrDev) { if (planRequired === POSTHOG_CLOUD_STANDARD_PLAN) { gateVariant = 'add-card' } else { gateVariant = 'contact-sales' } } else { - gateVariant = 'subscribe' + gateVariant = 'move-to-cloud' } } @@ -129,7 +131,11 @@ export function PayGateMini({
{featureSummary.icon || }
{featureSummary.description}
- Subscribe to gain {featureSummary.umbrella}. + {gateVariant === 'move-to-cloud' ? ( + <>{capitalizeFirstLetter(featureSummary.umbrella)} is available on PostHog Cloud. + ) : ( + <>Subscribe to gain {featureSummary.umbrella}. + )} {featureSummary.docsHref && ( <> {' '} @@ -145,8 +151,8 @@ export function PayGateMini({ ? '/organization/billing' : gateVariant === 'contact-sales' ? `mailto:sales@posthog.com?subject=Inquiring about ${featureSummary.umbrella}` - : gateVariant === 'subscribe' - ? '/organization/billing' + : gateVariant === 'move-to-cloud' + ? 'https://us.posthog.com/signup?utm_medium=in-product&utm_campaign=move-to-cloud' : undefined } type="primary" @@ -156,7 +162,7 @@ export function PayGateMini({ ? 'Subscribe now' : gateVariant === 'contact-sales' ? 'Contact sales' - : 'Subscribe'} + : 'Move to PostHog Cloud'}
) : ( diff --git a/frontend/src/lib/components/PayGatePage/PayGatePage.tsx b/frontend/src/lib/components/PayGatePage/PayGatePage.tsx index 383cbe1cdfb43..d955979048c97 100644 --- a/frontend/src/lib/components/PayGatePage/PayGatePage.tsx +++ b/frontend/src/lib/components/PayGatePage/PayGatePage.tsx @@ -5,6 +5,8 @@ import { useValues } from 'kea' import { LemonButton } from 'lib/lemon-ui/LemonButton' import { identifierToHuman } from 'lib/utils' import { billingLogic } from 'scenes/billing/billingLogic' +import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' +import { urls } from 'scenes/urls' import { AvailableFeature } from '~/types' @@ -26,6 +28,7 @@ export function PayGatePage({ featureName, }: PayGatePageInterface): JSX.Element { const { upgradeLink } = useValues(billingLogic) + const { isCloudOrDev } = useValues(preflightLogic) featureName = featureName || identifierToHuman(featureKey, 'title') return ( @@ -33,12 +36,23 @@ export function PayGatePage({

{header}

{caption}
- {!hideUpgradeButton && ( - - Upgrade now to get {featureName} - - )} - {docsLink && ( + {!isCloudOrDev &&

This feature is available on PostHog Cloud.

} + {!hideUpgradeButton && + (isCloudOrDev ? ( + + Upgrade now to get {featureName} + + ) : ( + + Learn more about PostHog Cloud + + ))} + {docsLink && isCloudOrDev && ( any> = { [Scene.Onboarding]: () => import('./onboarding/Onboarding'), [Scene.OnboardingProductIntroduction]: () => import('./onboarding/OnboardingProductIntroduction'), [Scene.Settings]: () => import('./settings/SettingsScene'), + [Scene.MoveToPostHogCloud]: () => import('./moveToPostHogCloud/MoveToPostHogCloud'), } diff --git a/frontend/src/scenes/billing/Billing.tsx b/frontend/src/scenes/billing/Billing.tsx index b8f693021b551..23725a938e30a 100644 --- a/frontend/src/scenes/billing/Billing.tsx +++ b/frontend/src/scenes/billing/Billing.tsx @@ -4,6 +4,7 @@ import { LemonButton, LemonDivider, LemonInput, Link } from '@posthog/lemon-ui' import clsx from 'clsx' import { useActions, useValues } from 'kea' import { Field, Form } from 'kea-forms' +import { router } from 'kea-router' import { SurprisedHog } from 'lib/components/hedgehogs' import { PageHeader } from 'lib/components/PageHeader' import { supportLogic } from 'lib/components/Support/supportLogic' @@ -14,10 +15,10 @@ import { LemonBanner } from 'lib/lemon-ui/LemonBanner' import { LemonLabel } from 'lib/lemon-ui/LemonLabel/LemonLabel' import { SpinnerOverlay } from 'lib/lemon-ui/Spinner/Spinner' import { Tooltip } from 'lib/lemon-ui/Tooltip' -import { capitalizeFirstLetter } from 'lib/utils' import { useEffect } from 'react' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' import { SceneExport } from 'scenes/sceneTypes' +import { urls } from 'scenes/urls' import { BillingHero } from './BillingHero' import { billingLogic } from './billingLogic' @@ -45,10 +46,13 @@ export function Billing(): JSX.Element { isAnnualPlan, } = useValues(billingLogic) const { reportBillingV2Shown } = useActions(billingLogic) - const { preflight } = useValues(preflightLogic) - const cloudOrDev = preflight?.cloud || preflight?.is_debug + const { preflight, isCloudOrDev } = useValues(preflightLogic) const { openSupportForm } = useActions(supportLogic) + if (preflight && !isCloudOrDev) { + router.actions.push(urls.default()) + } + useEffect(() => { if (billing) { reportBillingV2Shown() @@ -155,7 +159,7 @@ export function Billing(): JSX.Element { You are currently on a free trial until {billing.free_trial_until.format('LL')} ) : null} - {!billing?.has_active_subscription && cloudOrDev && ( + {!billing?.has_active_subscription && ( <>
@@ -238,35 +242,6 @@ export function Billing(): JSX.Element {
)} - - {!cloudOrDev && (billing?.license?.plan || !billing?.has_active_subscription) && ( -
- {!cloudOrDev && billing?.license?.plan ? ( -
-
- {capitalizeFirstLetter(billing.license.plan)} license -
- - Please contact sales@posthog.com{' '} - if you would like to make any changes to your license. - -
- ) : null} - - {!cloudOrDev && !billing?.has_active_subscription ? ( -

- Self-hosted licenses are no longer available for purchase. Please contact{' '} - sales@posthog.com to discuss options. -

- ) : null} -
- )} {!isOnboarding && billing?.has_active_subscription && ( diff --git a/frontend/src/scenes/experiments/ExperimentsPayGate.tsx b/frontend/src/scenes/experiments/ExperimentsPayGate.tsx index 0a0ebe684e684..7335b3c3b068b 100644 --- a/frontend/src/scenes/experiments/ExperimentsPayGate.tsx +++ b/frontend/src/scenes/experiments/ExperimentsPayGate.tsx @@ -8,10 +8,10 @@ export function ExperimentsPayGate(): JSX.Element { featureKey={AvailableFeature.EXPERIMENTATION} header={ <> - Introducing Experimentation! + Test changes with statistical significance } - caption="Improve your product by A/B testing new features to discover what works best for your users." + caption="A/B tests, multivariate tests, and robust targeting & exclusion rules. Analyze usage with product analytics and session replay." docsLink="https://posthog.com/docs/user-guides/experimentation" /> ) diff --git a/frontend/src/scenes/feature-flags/FeatureFlagSnippets.tsx b/frontend/src/scenes/feature-flags/FeatureFlagSnippets.tsx index c8877d6ada8be..c4ad007bb45c5 100644 --- a/frontend/src/scenes/feature-flags/FeatureFlagSnippets.tsx +++ b/frontend/src/scenes/feature-flags/FeatureFlagSnippets.tsx @@ -1,5 +1,6 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' import { GroupType } from '~/types' @@ -444,7 +445,7 @@ export function APISnippet({ groupType }: FeatureFlagSnippet): JSX.Element { return ( <> - {`curl ${window.location.origin}/decide?v=3/ \\ + {`curl ${apiHostOrigin()}/decide?v=3/ \\ -X POST -H 'Content-Type: application/json' \\ -d '{ "api_key": "${currentTeam ? currentTeam.api_token : '[project_api_key]'}", diff --git a/frontend/src/scenes/moveToPostHogCloud/MoveToPostHogCloud.tsx b/frontend/src/scenes/moveToPostHogCloud/MoveToPostHogCloud.tsx new file mode 100644 index 0000000000000..c4531f26dee01 --- /dev/null +++ b/frontend/src/scenes/moveToPostHogCloud/MoveToPostHogCloud.tsx @@ -0,0 +1,152 @@ +import { + IconBolt, + IconDatabase, + IconFeatures, + IconFlag, + IconHeart, + IconLock, + IconPrivacy, + IconSupport, + IconTrending, + IconUpload, +} from '@posthog/icons' +import { LemonButton, Link } from '@posthog/lemon-ui' +import { ExperimentsHog } from 'lib/components/hedgehogs' +import { SceneExport } from 'scenes/sceneTypes' + +export const scene: SceneExport = { + component: MoveToPostHogCloud, +} + +type CloudFeature = { + name: string + description: string + icon: JSX.Element + link?: string +} + +const CLOUD_FEATURES: CloudFeature[] = [ + { + name: 'Hosted for you', + description: "No need to worry about servers, databases, or data ingestion. We've got it all covered.", + icon: , + }, + { + name: 'EU and US data centers', + description: 'Host your data in the EU or US, whichever works best for your customer base.', + icon: , + }, + { + name: 'Easy migration', + description: + "We've done this before. It's just a few clicks to get your data moving from self-hosted to Cloud.", + icon: , + link: 'https://posthog.com/docs/migrate/migrate-to-cloud', + }, + { + name: 'Auto-scaling', + description: + 'As your product grows, so does your data. PostHog Cloud scales for you, so you never have to worry about spikes or downtime.', + icon: , + }, + { + name: 'Highly available', + description: 'PostHog Cloud is highly available, so you can rest easy knowing your data is always accessible.', + icon: , + }, + { + name: 'Automatic upgrades', + description: + 'PostHog Cloud is always up to date with the latest features and security updates - no upgrades required.', + icon: , + }, + { + name: 'Automatic backups', + description: "Don't worry about backups - we've got it covered.", + icon: , + }, + { + name: 'Access to all features', + description: + 'Group analytics, data pipelines, A/B testing, and other premium features are only available on PostHog Cloud.', + icon: , + link: 'https://posthog.com/pricing', + }, + { + name: 'World-class support', + description: + 'PostHog Cloud customers get access to our world-class support team, not just the community forum.', + icon: , + link: 'https://posthog.com/handbook/growth/customer-support', + }, + { + name: 'SOC 2 compliant', + description: "We're SOC-2 compliant, so you can rest easy knowing your data is secure.", + icon: , + link: 'https://posthog.com/handbook/company/security', + }, + { + name: 'HIPAA compliant', + description: "Rest easy knowing your customers' data is secure.", + icon: , + }, +] + +export function MoveToPostHogCloud(): JSX.Element { + return ( +
+
+
+
+

PostHog Cloud

+

+ We handle the infra. You focus on your product. +

+

+ Hosting PostHog is no easy feat. It takes a lot of domain nowledge to get it right - + especially at scale. Let us handle the hosting, so you can focus on building your product. +

+
+ + Move to PostHog Cloud + +
+
+ +
+
+
+
+

Features

+
    + {CLOUD_FEATURES.map((feature, i) => { + return ( +
  • + {feature.icon} +

    {feature.name}

    +

    {feature.description}

    + {feature.link && ( +

    + Learn more +

    + )} +
  • + ) + })} +
+
+
+
+ ) +} diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/api.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/api.tsx index 263d14511865d..f8409dcc23b1e 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/api.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/api.tsx @@ -1,10 +1,11 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' function APISnippet(): JSX.Element { const { currentTeam } = useValues(teamLogic) - const url = window.location.origin + const url = apiHostOrigin() return ( diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/flutter.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/flutter.tsx index c5ec99eae6df6..a663a65327552 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/flutter.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/flutter.tsx @@ -1,5 +1,6 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' function FlutterInstallSnippet(): JSX.Element { @@ -8,7 +9,7 @@ function FlutterInstallSnippet(): JSX.Element { function FlutterAndroidSetupSnippet(): JSX.Element { const { currentTeam } = useValues(teamLogic) - const url = window.location.origin + const url = apiHostOrigin() return ( @@ -23,7 +24,7 @@ function FlutterAndroidSetupSnippet(): JSX.Element { function FlutterIOSSetupSnippet(): JSX.Element { const { currentTeam } = useValues(teamLogic) - const url = window.location.origin + const url = apiHostOrigin() return ( diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx index 425476a01d536..4b86871452ca0 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx @@ -1,5 +1,6 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' function IOSInstallCocoaPodsSnippet(): JSX.Element { @@ -28,7 +29,7 @@ import UIKit class AppDelegate: NSObject, UIApplicationDelegate { func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { let POSTHOG_API_KEY = "${currentTeam?.api_token}" - let POSTHOG_HOST = "${window.location.origin}" + let POSTHOG_HOST = "${apiHostOrigin()}" let config = PostHogConfig(apiKey: POSTHOG_API_KEY, host: POSTHOG_HOST) PostHogSDK.shared.setup(config) diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/next-js.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/next-js.tsx index 4e00958693031..2aa0271b2dee5 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/next-js.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/next-js.tsx @@ -1,6 +1,7 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' import { Link } from 'lib/lemon-ui/Link' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' import { JSInstallSnippet } from './js-web' @@ -10,10 +11,9 @@ function NextEnvVarsSnippet(): JSX.Element { return ( - {[ - `NEXT_PUBLIC_POSTHOG_KEY=${currentTeam?.api_token}`, - `NEXT_PUBLIC_POSTHOG_HOST=${window.location.origin}`, - ].join('\n')} + {[`NEXT_PUBLIC_POSTHOG_KEY=${currentTeam?.api_token}`, `NEXT_PUBLIC_POSTHOG_HOST=${apiHostOrigin()}`].join( + '\n' + )} ) } diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/php.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/php.tsx index 336e59a33f17f..f1204a95f82c2 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/php.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/php.tsx @@ -1,5 +1,6 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' function PHPConfigSnippet(): JSX.Element { @@ -24,7 +25,7 @@ function PHPSetupSnippet(): JSX.Element { return ( {`PostHog::init('${currentTeam?.api_token}', - array('host' => '${window.location.origin}') + array('host' => '${apiHostOrigin()}') );`} ) diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react-native.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react-native.tsx index 6b489e0088ad2..b54a7b481d1dd 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react-native.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react-native.tsx @@ -1,11 +1,12 @@ import { Link } from '@posthog/lemon-ui' import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' export function SDKInstallRNInstructions(): JSX.Element { const { currentTeam } = useValues(teamLogic) - const url = window.location.origin + const url = apiHostOrigin() return ( <> diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ruby.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ruby.tsx index f190fe8b03d04..bc89e9ce5aace 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ruby.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ruby.tsx @@ -1,5 +1,6 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' function RubyInstallSnippet(): JSX.Element { @@ -13,7 +14,7 @@ function RubySetupSnippet(): JSX.Element { {`posthog = PostHog::Client.new({ api_key: "${currentTeam?.api_token}", - host: "${window.location.origin}", + host: "${apiHostOrigin()}", on_error: Proc.new { |status, msg| print msg } })`} diff --git a/frontend/src/scenes/sceneLogic.ts b/frontend/src/scenes/sceneLogic.ts index 2546b06455fe2..3fdc78103e7d5 100644 --- a/frontend/src/scenes/sceneLogic.ts +++ b/frontend/src/scenes/sceneLogic.ts @@ -199,12 +199,15 @@ export const sceneLogic = kea([ router.actions.replace(urls.login()) return } - if (scene === Scene.Login && preflight?.demo) { // In the demo environment, there's only passwordless "login" via the signup scene router.actions.replace(urls.signup()) return } + if (scene === Scene.MoveToPostHogCloud && preflight?.cloud) { + router.actions.replace(urls.projectHomepage()) + return + } // Redirect to the scene's canonical pathname if needed const currentPathname = router.values.location.pathname diff --git a/frontend/src/scenes/sceneTypes.ts b/frontend/src/scenes/sceneTypes.ts index 8921f6f3072e0..b428fe340961f 100644 --- a/frontend/src/scenes/sceneTypes.ts +++ b/frontend/src/scenes/sceneTypes.ts @@ -77,6 +77,7 @@ export enum Scene { Onboarding = 'Onboarding', OnboardingProductIntroduction = 'OnboardingProductIntroduction', Settings = 'Settings', + MoveToPostHogCloud = 'MoveToPostHogCloud', } export type SceneProps = Record diff --git a/frontend/src/scenes/scenes.ts b/frontend/src/scenes/scenes.ts index 775e94282a8c8..01f81fff3d6ad 100644 --- a/frontend/src/scenes/scenes.ts +++ b/frontend/src/scenes/scenes.ts @@ -376,6 +376,10 @@ export const sceneConfigurations: Record = { projectBased: true, name: 'Settings', }, + [Scene.MoveToPostHogCloud]: { + name: 'Move to PostHog Cloud', + hideProjectNotice: true, + }, } const preserveParams = (url: string) => (_params: Params, searchParams: Params, hashParams: Params) => { @@ -554,4 +558,5 @@ export const routes: Record = { [urls.notebooks()]: Scene.Notebooks, [urls.canvas()]: Scene.Canvas, [urls.settings(':section' as any)]: Scene.Settings, + [urls.moveToPostHogCloud()]: Scene.MoveToPostHogCloud, } diff --git a/frontend/src/scenes/urls.ts b/frontend/src/scenes/urls.ts index b5589f98102d1..65bb87d716d85 100644 --- a/frontend/src/scenes/urls.ts +++ b/frontend/src/scenes/urls.ts @@ -210,4 +210,5 @@ export const urls = { notebooks: (): string => '/notebooks', notebook: (shortId: string): string => `/notebooks/${shortId}`, canvas: (): string => `/canvas`, + moveToPostHogCloud: (): string => '/move-to-cloud', }