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',
}