diff --git a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-node-with-group-multivariate-flag-local-evaluation.png b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-node-with-group-multivariate-flag-local-evaluation.png index 9c86ac0b79891..5d5e7f2df7919 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-node-with-group-multivariate-flag-local-evaluation.png and b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-node-with-group-multivariate-flag-local-evaluation.png differ diff --git a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-overview.png b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-overview.png index c05094ac415cf..93b63311a152e 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-overview.png and b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-overview.png differ diff --git a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-python-with-local-evaluation.png b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-python-with-local-evaluation.png index 02d3bff5c2fcb..a132ecc449fb0 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-python-with-local-evaluation.png and b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-python-with-local-evaluation.png differ diff --git a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-react-native-with-bootstrap.png b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-react-native-with-bootstrap.png index 05bd83d8af7f0..7ef3045bcea27 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-react-native-with-bootstrap.png and b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-react-native-with-bootstrap.png differ diff --git a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-ruby-with-group-flag-local-evaluation.png b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-ruby-with-group-flag-local-evaluation.png index 2e20a5fab9eaf..c50a2b618be4e 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-ruby-with-group-flag-local-evaluation.png and b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructions-ruby-with-group-flag-local-evaluation.png differ diff --git a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructionsi-os-with-multivariate-flag.png b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructionsi-os-with-multivariate-flag.png index f1408645d5743..6bab8977291f3 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructionsi-os-with-multivariate-flag.png and b/frontend/__snapshots__/scenes-app-feature-flags-code-examples--code-instructionsi-os-with-multivariate-flag.png differ diff --git a/frontend/src/scenes/feature-flags/FeatureFlagCodeInstructions.stories.tsx b/frontend/src/scenes/feature-flags/FeatureFlagCodeInstructions.stories.tsx index 5ac711aabde81..48605e78b7123 100644 --- a/frontend/src/scenes/feature-flags/FeatureFlagCodeInstructions.stories.tsx +++ b/frontend/src/scenes/feature-flags/FeatureFlagCodeInstructions.stories.tsx @@ -2,7 +2,7 @@ import { Meta } from '@storybook/react' import { CodeInstructions, CodeInstructionsProps } from './FeatureFlagInstructions' import { OPTIONS } from './FeatureFlagCodeOptions' -import { FeatureFlagType } from '~/types' +import { FeatureFlagType, SDKKey } from '~/types' import { useStorybookMocks } from '~/mocks/browser' import { useAvailableFeatures } from '~/mocks/features' import { AvailableFeature } from '~/types' @@ -79,7 +79,7 @@ const meta: Meta = { component: CodeInstructions, args: { options: OPTIONS, - selectedLanguage: 'JavaScript', + selectedLanguage: SDKKey.JS_WEB, featureFlag: REGULAR_FEATURE_FLAG, showLocalEval: false, showBootstrap: false, @@ -99,11 +99,11 @@ export const CodeInstructionsOverview = (props: CodeInstructionsProps): JSX.Elem } export const CodeInstructionsReactNativeWithBootstrap = (): JSX.Element => { - return + return } export const CodeInstructionsPythonWithLocalEvaluation = (): JSX.Element => { - return + return } export const CodeInstructionsRubyWithGroupFlagLocalEvaluation = (): JSX.Element => { @@ -119,7 +119,7 @@ export const CodeInstructionsRubyWithGroupFlagLocalEvaluation = (): JSX.Element }) return ( { - return + return } export const CodeInstructionsNodeWithGroupMultivariateFlagLocalEvaluation = (): JSX.Element => { @@ -144,7 +144,7 @@ export const CodeInstructionsNodeWithGroupMultivariateFlagLocalEvaluation = (): }) return ( JSX.Element type: LibraryType + key: SDKKey } export enum LibraryType { @@ -39,72 +41,83 @@ export const OPTIONS: InstructionOption[] = [ documentationLink: `${DOC_BASE_URL}integrations/js-integration${UTM_TAGS}`, Snippet: JSSnippet, type: LibraryType.Client, + key: SDKKey.JS_WEB, }, { value: 'Android', documentationLink: `${DOC_BASE_URL}integrate/client/android${UTM_TAGS}`, Snippet: AndroidSnippet, type: LibraryType.Client, + key: SDKKey.ANDROID, }, { value: 'iOS', documentationLink: `${DOC_BASE_URL}integrate/client/ios${UTM_TAGS}`, Snippet: iOSSnippet, type: LibraryType.Client, + key: SDKKey.IOS, }, { value: 'React Native', documentationLink: `${DOC_BASE_URL}integrate/client/react-native${UTM_TAGS}`, Snippet: ReactNativeSnippet, type: LibraryType.Client, + key: SDKKey.REACT_NATIVE, }, { value: 'React', documentationLink: `${DOC_BASE_URL}libraries/react${UTM_TAGS}`, Snippet: ReactSnippet, type: LibraryType.Client, + key: SDKKey.REACT, }, { value: 'Node.js', documentationLink: `${DOC_BASE_URL}integrations/node-integration${UTM_TAGS}`, Snippet: NodeJSSnippet, type: LibraryType.Server, + key: SDKKey.NODE_JS, }, { value: 'Python', documentationLink: `${DOC_BASE_URL}integrations/python-integration${UTM_TAGS}`, Snippet: PythonSnippet, type: LibraryType.Server, + key: SDKKey.PYTHON, }, { value: 'Ruby', documentationLink: `${DOC_BASE_URL}integrations/ruby-integration${UTM_TAGS}`, Snippet: RubySnippet, type: LibraryType.Server, + key: SDKKey.RUBY, }, { value: 'API', documentationLink: `${DOC_BASE_URL}api/post-only-endpoints#example-request--response-decide-v3`, Snippet: APISnippet, type: LibraryType.Server, + key: SDKKey.API, }, { value: 'PHP', documentationLink: `${DOC_BASE_URL}integrations/php-integration${UTM_TAGS}`, Snippet: PHPSnippet, type: LibraryType.Server, + key: SDKKey.PHP, }, { value: 'Go', documentationLink: `${DOC_BASE_URL}integrations/go-integration${UTM_TAGS}`, Snippet: GolangSnippet, type: LibraryType.Server, + key: SDKKey.GO, }, ] -export const LOCAL_EVALUATION_LIBRARIES: string[] = ['Node.js', 'Python', 'Ruby', 'PHP', 'Go'] +export const LOCAL_EVALUATION_LIBRARIES: string[] = [SDKKey.NODE_JS, SDKKey.PYTHON, SDKKey.RUBY, SDKKey.PHP, SDKKey.GO] -export const PAYLOAD_LIBRARIES: string[] = ['JavaScript', 'Node.js', 'Python', 'Ruby', 'React'] +export const PAYLOAD_LIBRARIES: string[] = [SDKKey.JS_WEB, SDKKey.NODE_JS, SDKKey.PYTHON, SDKKey.RUBY, SDKKey.REACT] export const BOOTSTRAPPING_OPTIONS: InstructionOption[] = [ { @@ -112,11 +125,13 @@ export const BOOTSTRAPPING_OPTIONS: InstructionOption[] = [ documentationLink: `${DOC_BASE_URL}integrations/js-integration${UTM_TAGS}${BOOTSTRAPPING_ANCHOR}`, Snippet: JSBootstrappingSnippet, type: LibraryType.Client, + key: SDKKey.JS_WEB, }, { value: 'React Native', documentationLink: `${DOC_BASE_URL}integrate/client/react-native${UTM_TAGS}${BOOTSTRAPPING_ANCHOR}`, Snippet: JSBootstrappingSnippet, type: LibraryType.Client, + key: SDKKey.REACT_NATIVE, }, ] diff --git a/frontend/src/scenes/feature-flags/FeatureFlagInstructions.tsx b/frontend/src/scenes/feature-flags/FeatureFlagInstructions.tsx index fa8e8334f5a7d..2c32d7f615bf3 100644 --- a/frontend/src/scenes/feature-flags/FeatureFlagInstructions.tsx +++ b/frontend/src/scenes/feature-flags/FeatureFlagInstructions.tsx @@ -38,6 +38,8 @@ export interface CodeInstructionsProps { dataAttr?: string showLocalEval?: boolean showBootstrap?: boolean + showAdvancedOptions?: boolean + showFooter?: boolean } export function CodeInstructions({ @@ -47,6 +49,8 @@ export function CodeInstructions({ dataAttr = '', showLocalEval = false, showBootstrap = false, + showAdvancedOptions = true, + showFooter = true, }: CodeInstructionsProps): JSX.Element { const [defaultSelectedOption] = options const [selectedOption, setSelectedOption] = useState(defaultSelectedOption) @@ -84,7 +88,7 @@ export function CodeInstructions({ } const selectOption = (selectedValue: string): void => { - const option = options.find((option) => option.value === selectedValue) + const option = options.find((option) => option.key === selectedValue) if (option) { setSelectedOption(option) @@ -101,7 +105,7 @@ export function CodeInstructions({ setShowLocalEvalCode(false) } - const bootstrapOption = BOOTSTRAPPING_OPTIONS.find((bootstrapOption) => bootstrapOption.value === selectedValue) + const bootstrapOption = BOOTSTRAPPING_OPTIONS.find((bootstrapOption) => bootstrapOption.key === selectedValue) if (bootstrapOption) { setBootstrapOption(bootstrapOption) } else { @@ -113,7 +117,7 @@ export function CodeInstructions({ selectOption(selectedLanguage) } else { // When flag definition changes, de-select any options that can't be selected anymore - selectOption(selectedOption.value) + selectOption(selectedOption.key) } if ( @@ -144,105 +148,107 @@ export function CodeInstructions({ return (
-
-
- option.type == LibraryType.Client).map( - (option) => ({ - value: option.value, - label: option.value, - 'data-attr': `feature-flag-instructions-select-option-${option.value}`, - }) - ), - }, - { - title: 'Server libraries', - options: OPTIONS.filter((option) => option.type == LibraryType.Server).map( - (option) => ({ - value: option.value, - label: option.value, - 'data-attr': `feature-flag-instructions-select-option-${option.value}`, - }) - ), - }, - ]} - onChange={(val) => { - if (val) { - selectOption(val) - reportFlagsCodeExampleLanguage(val) - } - }} - value={selectedOption.value} - /> -
- ` ${payloadOption}` - )}`} - > -
- { - setShowPayloadCode(!showPayloadCode) - reportFlagsCodeExampleInteraction('payloads') + {showAdvancedOptions && ( +
+
+ option.type == LibraryType.Client).map( + (option) => ({ + value: option.key, + label: option.value, + 'data-attr': `feature-flag-instructions-select-option-${option.key}`, + }) + ), + }, + { + title: 'Server libraries', + options: OPTIONS.filter((option) => option.type == LibraryType.Server).map( + (option) => ({ + value: option.key, + label: option.value, + 'data-attr': `feature-flag-instructions-select-option-${option.key}`, + }) + ), + }, + ]} + onChange={(val) => { + if (val) { + selectOption(val) + reportFlagsCodeExampleLanguage(val) + } }} - data-attr="flags-code-example-payloads-option" - checked={showPayloadCode} - disabled={!PAYLOAD_LIBRARIES.includes(selectedOption.value)} + value={selectedOption.key} /> -
- - <> ` ${payloadOption}` + )}`} >
{ - setShowBootstrapCode(!showBootstrapCode) - reportFlagsCodeExampleInteraction('bootstrap') + setShowPayloadCode(!showPayloadCode) + reportFlagsCodeExampleInteraction('payloads') }} - disabled={ - !BOOTSTRAPPING_OPTIONS.map((bo) => bo.value).includes(selectedOption.value) || - !!featureFlag?.ensure_experience_continuity - } + data-attr="flags-code-example-payloads-option" + checked={showPayloadCode} + disabled={!PAYLOAD_LIBRARIES.includes(selectedOption.key)} />
- +
+ { + setShowBootstrapCode(!showBootstrapCode) + reportFlagsCodeExampleInteraction('bootstrap') + }} + disabled={ + !BOOTSTRAPPING_OPTIONS.map((bo) => bo.key).includes(selectedOption.key) || + !!featureFlag?.ensure_experience_continuity + } + /> + +
+
+ -
- { - setShowLocalEvalCode(!showLocalEvalCode) - reportFlagsCodeExampleInteraction('local evaluation') - }} - disabled={ - !LOCAL_EVALUATION_LIBRARIES.includes(selectedOption.value) || - !!featureFlag?.ensure_experience_continuity - } - /> - -
-
- -
+ > +
+ { + setShowLocalEvalCode(!showLocalEvalCode) + reportFlagsCodeExampleInteraction('local evaluation') + }} + disabled={ + !LOCAL_EVALUATION_LIBRARIES.includes(selectedOption.key) || + !!featureFlag?.ensure_experience_continuity + } + /> + +
+ + +
+ )}
{showLocalEvalCode && ( <> @@ -277,7 +283,7 @@ export function CodeInstructions({ )} - + {showFooter && }
diff --git a/frontend/src/scenes/onboarding/Onboarding.tsx b/frontend/src/scenes/onboarding/Onboarding.tsx index 3cf1c4989e4c1..c3520d90bea01 100644 --- a/frontend/src/scenes/onboarding/Onboarding.tsx +++ b/frontend/src/scenes/onboarding/Onboarding.tsx @@ -96,7 +96,11 @@ const SessionReplayOnboarding = (): JSX.Element => { const FeatureFlagsOnboarding = (): JSX.Element => { return ( - + ) } diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/FeatureFlagsSDKInstructions.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/FeatureFlagsSDKInstructions.tsx index 6374992792b3e..729a335fa3004 100644 --- a/frontend/src/scenes/onboarding/sdks/feature-flags/FeatureFlagsSDKInstructions.tsx +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/FeatureFlagsSDKInstructions.tsx @@ -1,8 +1,31 @@ import { SDKInstructionsMap, SDKKey } from '~/types' -import { JSWebInstructions, NextJSInstructions, ReactInstructions } from '.' +import { + FeatureFlagsJSWebInstructions, + FeatureFlagsNextJSInstructions, + FeatureFlagsAPIInstructions, + FeatureFlagsAndroidInstructions, + FeatureFlagsGoInstructions, + FeatureFlagsIOSInstructions, + FeatureFlagsNodeInstructions, + FeatureFlagsPHPInstructions, + FeatureFlagsPythonInstructions, + FeatureFlagsRNInstructions, + FeatureFlagsRubyInstructions, + FeatureFlagsReactInstructions, +} from '.' export const FeatureFlagsSDKInstructions: SDKInstructionsMap = { - [SDKKey.JS_WEB]: JSWebInstructions, - [SDKKey.NEXT_JS]: NextJSInstructions, - [SDKKey.REACT]: ReactInstructions, + [SDKKey.JS_WEB]: FeatureFlagsJSWebInstructions, + [SDKKey.REACT]: FeatureFlagsReactInstructions, + [SDKKey.NEXT_JS]: FeatureFlagsNextJSInstructions, + [SDKKey.IOS]: FeatureFlagsIOSInstructions, + [SDKKey.REACT_NATIVE]: FeatureFlagsRNInstructions, + [SDKKey.ANDROID]: FeatureFlagsAndroidInstructions, + [SDKKey.NODE_JS]: FeatureFlagsNodeInstructions, + [SDKKey.PYTHON]: FeatureFlagsPythonInstructions, + [SDKKey.RUBY]: FeatureFlagsRubyInstructions, + [SDKKey.PHP]: FeatureFlagsPHPInstructions, + [SDKKey.GO]: FeatureFlagsGoInstructions, + [SDKKey.API]: FeatureFlagsAPIInstructions, + // add flutter, rust, gatsby, nuxt, vue, svelte, and others here } diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/android.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/android.tsx new file mode 100644 index 0000000000000..0c9a64d274a8d --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/android.tsx @@ -0,0 +1,12 @@ +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKKey } from '~/types' +import { SDKInstallAndroidInstructions } from '../sdk-install-instructions' + +export function FeatureFlagsAndroidInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/api.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/api.tsx new file mode 100644 index 0000000000000..5402e66f53b48 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/api.tsx @@ -0,0 +1,10 @@ +import { SDKKey } from '~/types' +import { FlagImplementationSnippet } from './flagImplementationSnippet' + +export function FeatureFlagsAPIInstructions(): JSX.Element { + return ( + <> + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/flagImplementationSnippet.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/flagImplementationSnippet.tsx new file mode 100644 index 0000000000000..ded0cf3f69bc4 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/flagImplementationSnippet.tsx @@ -0,0 +1,17 @@ +import { OPTIONS } from 'scenes/feature-flags/FeatureFlagCodeOptions' +import { CodeInstructions } from 'scenes/feature-flags/FeatureFlagInstructions' +import { SDKKey } from '~/types' + +export const FlagImplementationSnippet = ({ sdkKey }: { sdkKey: SDKKey }): JSX.Element => { + return ( + <> +

Basic implementation

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/go.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/go.tsx new file mode 100644 index 0000000000000..cdb750a2396f8 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/go.tsx @@ -0,0 +1,12 @@ +import { SDKKey } from '~/types' +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKInstallGoInstructions } from '../sdk-install-instructions' + +export function FeatureFlagsGoInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/index.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/index.tsx index 27d9e5388d04d..11e1743082019 100644 --- a/frontend/src/scenes/onboarding/sdks/feature-flags/index.tsx +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/index.tsx @@ -1,3 +1,12 @@ +export * from './android' +export * from './go' +export * from './nodejs' +export * from './ios' +export * from './php' +export * from './python' +export * from './react-native' +export * from './ruby' +export * from './api' export * from './js-web' -export * from './next-js' export * from './react' +export * from './next-js' diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx new file mode 100644 index 0000000000000..250c98fd4d3fd --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx @@ -0,0 +1,12 @@ +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKKey } from '~/types' +import { SDKInstallIOSInstructions } from '../sdk-install-instructions' + +export function FeatureFlagsIOSInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/js-web.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/js-web.tsx index 8ef2865c3b834..78a2fa373faa6 100644 --- a/frontend/src/scenes/onboarding/sdks/feature-flags/js-web.tsx +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/js-web.tsx @@ -1,42 +1,14 @@ -import { JSSnippet } from 'lib/components/JSSnippet' import { LemonDivider } from 'lib/lemon-ui/LemonDivider' -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' -import { JSInstallSnippet, SessionReplayFinalSteps } from '../shared-snippets' +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKKey } from '~/types' +import { SDKInstallJSWebInstructions } from '../sdk-install-instructions' -function JSSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {[ - "import posthog from 'posthog-js'", - '', - `posthog.init('${currentTeam?.api_token}', { api_host: '${window.location.origin}' })`, - ].join('\n')} - - ) -} - -export function JSWebInstructions(): JSX.Element { +export function FeatureFlagsJSWebInstructions(): JSX.Element { return ( <> -

Option 1. Code snippet

-

- Just add this snippet to your website within the <head> tag and we'll automatically - capture page views, sessions and all relevant interactions within your website. -

- - -

Option 2. Javascript Library

-

Install the package

- -

Initialize

- + -

Final steps

- + ) } diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/next-js.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/next-js.tsx index cda978ee12166..7b1b37f16b2a1 100644 --- a/frontend/src/scenes/onboarding/sdks/feature-flags/next-js.tsx +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/next-js.tsx @@ -1,98 +1,20 @@ -import { Link } from 'lib/lemon-ui/Link' -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' -import { JSInstallSnippet, SessionReplayFinalSteps } from '../shared-snippets' +import { SDKKey } from '~/types' +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKInstallNextJSInstructions } from '../sdk-install-instructions/next-js' +import { NodeInstallSnippet, NodeSetupSnippet } from '../sdk-install-instructions' -function NextEnvVarsSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {[ - `NEXT_PUBLIC_POSTHOG_KEY=${currentTeam?.api_token}`, - `NEXT_PUBLIC_POSTHOG_HOST=${window.location.origin}`, - ].join('\n')} - - ) -} - -function NextPagesRouterCodeSnippet(): JSX.Element { - return ( - - {`// pages/_app.js -... -import posthog from 'posthog-js' // Import PostHog - -if (typeof window !== 'undefined') { // checks that we are client-side - posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { - api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com', - loaded: (posthog) => { - if (process.env.NODE_ENV === 'development') posthog.debug() // debug mode in development - }, - }) -} - -export default function App({ Component, pageProps }) { - const router = useRouter() - ...`} - - ) -} - -function NextAppRouterCodeSnippet(): JSX.Element { - return ( - - {`// app/providers.js -'use client' -... -import posthog from 'posthog-js' - -if (typeof window !== 'undefined') { - posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { - api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, - }) -} -...`} - - ) -} - -export function NextJSInstructions(): JSX.Element { +export function FeatureFlagsNextJSInstructions(): JSX.Element { return ( <> -

Install posthog-js using your package manager

- -

Add environment variables

-

- Add your environment variables to your .env.local file and to your hosting provider (e.g. Vercel, - Netlify, AWS). You can find your project API key in your project settings. -

-

- These values need to start with NEXT_PUBLIC_ to be accessible on the - client-side. -

- - -

Initialize

-

With App router

-

- If your Next.js app to uses the app router, you can - integrate PostHog by creating a providers file in your app folder. This is because the posthog-js - library needs to be initialized on the client-side using the Next.js{' '} - - 'use client' directive - - . -

- -

With Pages router

-

- If your Next.js app uses the pages router, you can - integrate PostHog at the root of your app (pages/_app.js). -

- - + +

Client-side rendering

+ +

Server-side rendering

+

Install

+ +

Configure

+ + ) } diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/nodejs.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/nodejs.tsx new file mode 100644 index 0000000000000..576e6cd9091d2 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/nodejs.tsx @@ -0,0 +1,12 @@ +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKKey } from '~/types' +import { SDKInstallNodeInstructions } from '../sdk-install-instructions' + +export function FeatureFlagsNodeInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/php.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/php.tsx new file mode 100644 index 0000000000000..68a97ef96d9c4 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/php.tsx @@ -0,0 +1,12 @@ +import { SDKKey } from '~/types' +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKInstallPHPInstructions } from '../sdk-install-instructions' + +export function FeatureFlagsPHPInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/python.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/python.tsx new file mode 100644 index 0000000000000..55962b40f52ee --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/python.tsx @@ -0,0 +1,12 @@ +import { SDKKey } from '~/types' +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKInstallPythonInstructions } from '../sdk-install-instructions' + +export function FeatureFlagsPythonInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/react-native.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/react-native.tsx new file mode 100644 index 0000000000000..f045c817abcb8 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/react-native.tsx @@ -0,0 +1,12 @@ +import { SDKInstallRNInstructions } from '../sdk-install-instructions' +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKKey } from '~/types' + +export function FeatureFlagsRNInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/react.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/react.tsx index 86fdfc0f527c7..35ff77019b763 100644 --- a/frontend/src/scenes/onboarding/sdks/feature-flags/react.tsx +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/react.tsx @@ -1,64 +1,12 @@ -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' -import { JSInstallSnippet, SessionReplayFinalSteps } from '../shared-snippets' +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKKey } from '~/types' +import { SDKInstallReactInstructions } from '../sdk-install-instructions/react' -function ReactEnvVarsSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {[ - `REACT_APP_POSTHOG_PUBLIC_KEY=${currentTeam?.api_token}`, - `REACT_APP_PUBLIC_POSTHOG_HOST=${window.location.origin}`, - ].join('\n')} - - ) -} - -function ReactSetupSnippet(): JSX.Element { - return ( - - {`// src/index.js -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import App from './App'; - -import { PostHogProvider} from 'posthog-js/react' - -const options = { - api_host: process.env.REACT_APP_PUBLIC_POSTHOG_HOST, -} - -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - - - - - -);`} - - ) -} - -export function ReactInstructions(): JSX.Element { +export function FeatureFlagsReactInstructions(): JSX.Element { return ( <> -

Install the package

- -

Add environment variables

- -

Initialize

-

- Integrate PostHog at the root of your app (src/index.js for the default{' '} - create-react-app). -

- - + + ) } diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/ruby.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/ruby.tsx new file mode 100644 index 0000000000000..388d934ede926 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/ruby.tsx @@ -0,0 +1,12 @@ +import { FlagImplementationSnippet } from './flagImplementationSnippet' +import { SDKKey } from '~/types' +import { SDKInstallRubyInstructions } from '../sdk-install-instructions' + +export function FeatureFlagsRubyInstructions(): JSX.Element { + return ( + <> + + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/android.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/android.tsx index 9b69ee13ab740..71435dd4fdee1 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/android.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/android.tsx @@ -1,43 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function AndroidInstallSnippet(): JSX.Element { - return ( - - {`dependencies { - implementation 'com.posthog.android:posthog:1.+' -}`} - - ) -} - -function AndroidSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`public class SampleApp extends Application { - private static final String POSTHOG_API_KEY = "${currentTeam?.api_token}"; - private static final String POSTHOG_HOST = "${window.location.origin}"; - - @Override - public void onCreate() { - // Create a PostHog client with the given context, API key and host - PostHog posthog = new PostHog.Builder(this, POSTHOG_API_KEY, POSTHOG_HOST) - .captureApplicationLifecycleEvents() // Record certain application events automatically! - .recordScreenViews() // Record screen views automatically! - .build(); - - // Set the initialized instance as a globally accessible instance - PostHog.setSingletonInstance(posthog); - - // Now any time you call PostHog.with, the custom instance will be returned - PostHog posthog = PostHog.with(this); - }`} - - ) -} +import { SDKInstallAndroidInstructions } from '../sdk-install-instructions' function AndroidCaptureSnippet(): JSX.Element { return PostHog.with(this).capture("test-event"); @@ -46,10 +8,7 @@ function AndroidCaptureSnippet(): JSX.Element { export function ProductAnalyticsAndroidInstructions(): JSX.Element { return ( <> -

Install

- -

Configure

- +

Send an Event

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/elixir.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/elixir.tsx index 9878919b282cc..04c9f0d60c71b 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/elixir.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/elixir.tsx @@ -1,33 +1,9 @@ -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function ElixirInstallSnippet(): JSX.Element { - return ( - - {'def deps do\n [\n {:posthog, "~> 0.1"}\n ]\nend'} - - ) -} - -function ElixirSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - const url = window.location.origin - - return ( - - {'config :posthog,\n api_url: "' + url + '",\n api_key: "' + currentTeam?.api_token + '"'} - - ) -} +import { SDKInstallElixirInstructions } from '../sdk-install-instructions' export function ProductAnalyticsElixirInstructions(): JSX.Element { return ( <> -

Install

- -

Configure

- + ) } diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/flutter.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/flutter.tsx index 06c31e0b2ca83..01c793bfc8d74 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/flutter.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/flutter.tsx @@ -1,10 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function FlutterInstallSnippet(): JSX.Element { - return {'posthog_flutter: # insert version number'} -} +import { SDKInstallFlutterInstructions } from '../sdk-install-instructions' function FlutterCaptureSnippet(): JSX.Element { return ( @@ -16,47 +11,10 @@ function FlutterCaptureSnippet(): JSX.Element { ) } -function FlutterAndroidSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - const url = window.location.origin - - return ( - - {'\n\t\n\t\t[...]\n\t\n\t\n\t\n\t\n\t\n'} - - ) -} - -function FlutterIOSSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - const url = window.location.origin - - return ( - - {'\n\t[...]\n\tcom.posthog.posthog.API_KEY\n\t' + - currentTeam?.api_token + - '\n\tcom.posthog.posthog.POSTHOG_HOST\n\t' + - url + - '\n\tcom.posthog.posthog.TRACK_APPLICATION_LIFECYCLE_EVENTS\n\t\n\t[...]\n'} - - ) -} - export function ProductAnalyticsFlutterInstructions(): JSX.Element { return ( <> -

Install

- -

Android Setup

-

{'Add these values in AndroidManifest.xml'}

- -

iOS Setup

-

{'Add these values in Info.plist'}

- +

Send an Event

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/go.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/go.tsx index 726f5f1d80eba..7d7d14f0cd818 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/go.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/go.tsx @@ -1,27 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function GoInstallSnippet(): JSX.Element { - return {'go get "github.com/posthog/posthog-go"'} -} - -function GoSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`package main -import ( - "github.com/posthog/posthog-go" -) -func main() { - client, _ := posthog.NewWithConfig("${currentTeam?.api_token}", posthog.Config{Endpoint: "${window.location.origin}"}) - defer client.Close() -}`} - - ) -} +import { SDKInstallGoInstructions } from '../sdk-install-instructions' function GoCaptureSnippet(): JSX.Element { return ( @@ -34,10 +12,7 @@ function GoCaptureSnippet(): JSX.Element { export function ProductAnalyticsGoInstructions(): JSX.Element { return ( <> -

Install

- -

Configure

- +

Send an Event

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx index e337f685bad31..79ae931729710 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx @@ -1,34 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function IOSInstallSnippet(): JSX.Element { - return ( - - {'pod "PostHog", "~> 1.0" # Cocoapods \n# OR \ngithub "posthog/posthog-ios" # Carthage'} - - ) -} - -function IOS_OBJ_C_SetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`#import \n#import \n\nPHGPostHogConfiguration *configuration = [PHGPostHogConfiguration configurationWithApiKey:@"${currentTeam?.api_token}" host:@"${window.location.origin}"];\n\nconfiguration.captureApplicationLifecycleEvents = YES; // Record certain application events automatically!\nconfiguration.recordScreenViews = YES; // Record screen views automatically!\n\n[PHGPostHog setupWithConfiguration:configuration];`} - - ) -} - -function IOS_SWIFT_SetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`import PostHog\n\nlet configuration = PHGPostHogConfiguration(apiKey: "${currentTeam?.api_token}", host: "${window.location.origin}")\n\nconfiguration.captureApplicationLifecycleEvents = true; // Record certain application events automatically!\nconfiguration.recordScreenViews = true; // Record screen views automatically!\n\nPHGPostHog.setup(with: configuration)\nlet posthog = PHGPostHog.shared()`} - - ) -} +import { SDKInstallIOSInstructions } from '../sdk-install-instructions' function IOS_OBJ_C_CaptureSnippet(): JSX.Element { return ( @@ -45,12 +16,7 @@ function IOS_SWIFT_CaptureSnippet(): JSX.Element { export function ProductAnalyticsIOSInstructions(): JSX.Element { return ( <> -

Install

- -

Configure Swift

- -

Or configure Objective-C

- +

Send an event with swift

Send an event with Objective-C

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/js-web.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/js-web.tsx index ee13b1cee920e..fc2eb0f53c67d 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/js-web.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/js-web.tsx @@ -1,31 +1,6 @@ -import { Link } from 'lib/lemon-ui/Link' -import { JSSnippet } from 'lib/components/JSSnippet' -import { LemonDivider } from 'lib/lemon-ui/LemonDivider' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function JSInstallSnippet(): JSX.Element { - return ( - - {['npm install posthog-js', '# OR', 'yarn add posthog-js', '# OR', 'pnpm add posthog-js'].join('\n')} - - ) -} - -function JSSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {[ - "import posthog from 'posthog-js'", - '', - `posthog.init('${currentTeam?.api_token}', { api_host: '${window.location.origin}' })`, - ].join('\n')} - - ) -} +import { SDKInstallJSWebInstructions } from '../sdk-install-instructions' +import { LemonDivider } from '@posthog/lemon-ui' function JSEventSnippet(): JSX.Element { return ( @@ -36,67 +11,8 @@ function JSEventSnippet(): JSX.Element { export function JSWebInstructions(): JSX.Element { return ( <> -
-

Option 1. Code snippet

-
- Recommended -
-
-

- Just add this snippet to your website and we'll automatically capture page views, sessions and all - relevant interactions within your website.{' '} - - Learn more - - . -

-

Install the snippet

-

- Insert this snippet in your website within the <head> tag. -

-

Send events

-

Visit your site and click around to generate some initial events.

+ -
-

Option 2. Javascript Library

-
-

- Use this option if you want more granular control of how PostHog runs in your website and the events you - capture. Recommended for teams with more stable products and more defined analytics requirements.{' '} - - Learn more - - . -

-

Install the package

- -

- Configure & initialize (see more{' '} - - configuration options - - ) -

-

Send your first event

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/nodejs.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/nodejs.tsx index 24872d5b9c1a3..6a6050ca44f49 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/nodejs.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/nodejs.tsx @@ -1,33 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function NodeInstallSnippet(): JSX.Element { - return ( - - {`npm install posthog-node -# OR -yarn add posthog-node -# OR -pnpm add posthog-node`} - - ) -} - -function NodeSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`import { PostHog } from 'posthog-node' - -const client = new PostHog( - '${currentTeam?.api_token}', - { host: '${window.location.origin}' } -)`} - - ) -} +import { SDKInstallNodeInstructions } from '../sdk-install-instructions' function NodeCaptureSnippet(): JSX.Element { return ( @@ -47,10 +19,7 @@ client.flush()`} export function ProductAnalyticsNodeInstructions(): JSX.Element { return ( <> -

Install

- -

Configure

- +

Send an Event

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/php.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/php.tsx index 2f218e31d1510..2704a4c285e2b 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/php.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/php.tsx @@ -1,34 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function PHPConfigSnippet(): JSX.Element { - return ( - - {`{ - "require": { - "posthog/posthog-php": "1.0.*" - } -}`} - - ) -} - -function PHPInstallSnippet(): JSX.Element { - return {'php composer.phar install'} -} - -function PHPSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`PostHog::init('${currentTeam?.api_token}', - array('host' => '${window.location.origin}') -);`} - - ) -} +import { SDKInstallPHPInstructions } from '../sdk-install-instructions' function PHPCaptureSnippet(): JSX.Element { return ( @@ -41,12 +12,7 @@ function PHPCaptureSnippet(): JSX.Element { export function ProductAnalyticsPHPInstructions(): JSX.Element { return ( <> -

Dependency Setup

- -

Install

- -

Configure

- +

Send an Event

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/python.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/python.tsx index 4892dee3ac6e8..486326bf34669 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/python.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/python.tsx @@ -1,24 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function PythonInstallSnippet(): JSX.Element { - return {'pip install posthog'} -} - -function PythonSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`from posthog import Posthog - -posthog = Posthog(project_api_key='${currentTeam?.api_token}', host='${window.location.origin}') - - `} - - ) -} +import { SDKInstallPythonInstructions } from '../sdk-install-instructions' function PythonCaptureSnippet(): JSX.Element { return {"posthog.capture('test-id', 'test-event')"} @@ -27,10 +8,7 @@ function PythonCaptureSnippet(): JSX.Element { export function ProductAnalyticsPythonInstructions(): JSX.Element { return ( <> -

Install

- -

Configure

- +

Send an Event

diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/react-native.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/react-native.tsx index 3c80a3d512caf..0492b8c210960 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/react-native.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/react-native.tsx @@ -1,52 +1,10 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' -import { Link } from '@posthog/lemon-ui' +import { SDKInstallRNInstructions } from '../sdk-install-instructions' export function ProductAnalyticsRNInstructions(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - const url = window.location.origin - return ( <> -

Install

- - {`# Expo apps -expo install posthog-react-native expo-file-system expo-application expo-device expo-localization - -# Standard React Native apps -yarn add posthog-react-native @react-native-async-storage/async-storage react-native-device-info -# or -npm i -s posthog-react-native @react-native-async-storage/async-storage react-native-device-info - -# for iOS -cd ios -pod install`} - -

Configure

-

- PostHog is most easily used via the PostHogProvider component but if you need to - instantiate it directly,{' '} - - check out the docs - {' '} - which explain how to do this correctly. -

- - {`// App.(js|ts) -import { PostHogProvider } from 'posthog-react-native' -... - -export function MyApp() { - return ( - - - - ) -}`} - +

Send an Event

{`// With hooks import { usePostHog } from 'posthog-react-native' diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/ruby.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/ruby.tsx index 0d9ee8dbd6da2..905897614ebcd 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/ruby.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/ruby.tsx @@ -1,24 +1,5 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' - -function RubyInstallSnippet(): JSX.Element { - return {'gem "posthog-ruby"'} -} - -function RubySetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {`posthog = PostHog::Client.new({ - api_key: "${currentTeam?.api_token}", - host: "${window.location.origin}", - on_error: Proc.new { |status, msg| print msg } -})`} - - ) -} +import { SDKInstallRubyInstructions } from '../sdk-install-instructions' function RubyCaptureSnippet(): JSX.Element { return ( @@ -31,10 +12,7 @@ function RubyCaptureSnippet(): JSX.Element { export function ProductAnalyticsRubyInstructions(): JSX.Element { return ( <> -

Install

- -

Configure

- +

Send an Event

diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/android.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/android.tsx new file mode 100644 index 0000000000000..01a4b7d11d934 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/android.tsx @@ -0,0 +1,51 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function AndroidInstallSnippet(): JSX.Element { + return ( + + {`dependencies { + implementation 'com.posthog.android:posthog:1.+' +}`} + + ) +} + +function AndroidSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`public class SampleApp extends Application { + private static final String POSTHOG_API_KEY = "${currentTeam?.api_token}"; + private static final String POSTHOG_HOST = "${window.location.origin}"; + + @Override + public void onCreate() { + // Create a PostHog client with the given context, API key and host + PostHog posthog = new PostHog.Builder(this, POSTHOG_API_KEY, POSTHOG_HOST) + .captureApplicationLifecycleEvents() // Record certain application events automatically! + .recordScreenViews() // Record screen views automatically! + .build(); + + // Set the initialized instance as a globally accessible instance + PostHog.setSingletonInstance(posthog); + + // Now any time you call PostHog.with, the custom instance will be returned + PostHog posthog = PostHog.with(this); + }`} + + ) +} + +export function SDKInstallAndroidInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Configure

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/elixir.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/elixir.tsx new file mode 100644 index 0000000000000..2378c5ef93d0b --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/elixir.tsx @@ -0,0 +1,33 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function ElixirInstallSnippet(): JSX.Element { + return ( + + {'def deps do\n [\n {:posthog, "~> 0.1"}\n ]\nend'} + + ) +} + +function ElixirSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + const url = window.location.origin + + return ( + + {'config :posthog,\n api_url: "' + url + '",\n api_key: "' + currentTeam?.api_token + '"'} + + ) +} + +export function SDKInstallElixirInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Configure

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/flutter.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/flutter.tsx new file mode 100644 index 0000000000000..e37b2b1038388 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/flutter.tsx @@ -0,0 +1,52 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function FlutterInstallSnippet(): JSX.Element { + return {'posthog_flutter: # insert version number'} +} + +function FlutterAndroidSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + const url = window.location.origin + + return ( + + {'\n\t\n\t\t[...]\n\t\n\t\n\t\n\t\n\t\n'} + + ) +} + +function FlutterIOSSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + const url = window.location.origin + + return ( + + {'\n\t[...]\n\tcom.posthog.posthog.API_KEY\n\t' + + currentTeam?.api_token + + '\n\tcom.posthog.posthog.POSTHOG_HOST\n\t' + + url + + '\n\tcom.posthog.posthog.TRACK_APPLICATION_LIFECYCLE_EVENTS\n\t\n\t[...]\n'} + + ) +} + +export function SDKInstallFlutterInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Android Setup

+

{'Add these values in AndroidManifest.xml'}

+ +

iOS Setup

+

{'Add these values in Info.plist'}

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/go.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/go.tsx new file mode 100644 index 0000000000000..87bf25b337c40 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/go.tsx @@ -0,0 +1,35 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function GoInstallSnippet(): JSX.Element { + return {'go get "github.com/posthog/posthog-go"'} +} + +function GoSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`package main +import ( + "github.com/posthog/posthog-go" +) +func main() { + client, _ := posthog.NewWithConfig("${currentTeam?.api_token}", posthog.Config{Endpoint: "${window.location.origin}"}) + defer client.Close() +}`} + + ) +} + +export function SDKInstallGoInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Configure

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/index.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/index.tsx new file mode 100644 index 0000000000000..cc0382dd22581 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/index.tsx @@ -0,0 +1,11 @@ +export * from './android' +export * from './go' +export * from './nodejs' +export * from './ios' +export * from './php' +export * from './python' +export * from './react-native' +export * from './ruby' +export * from './elixir' +export * from './flutter' +export * from './js-web' diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx new file mode 100644 index 0000000000000..314f4c0305343 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx @@ -0,0 +1,44 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function IOSInstallSnippet(): JSX.Element { + return ( + + {'pod "PostHog", "~> 1.1" # Cocoapods \n# OR \ngithub "posthog/posthog-ios" # Carthage'} + + ) +} + +function IOS_OBJ_C_SetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`#import \n#import \n\nPHGPostHogConfiguration *configuration = [PHGPostHogConfiguration configurationWithApiKey:@"${currentTeam?.api_token}" host:@"${window.location.origin}"];\n\nconfiguration.captureApplicationLifecycleEvents = YES; // Record certain application events automatically!\nconfiguration.recordScreenViews = YES; // Record screen views automatically!\n\n[PHGPostHog setupWithConfiguration:configuration];`} + + ) +} + +function IOS_SWIFT_SetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`import PostHog\n\nlet configuration = PHGPostHogConfiguration(apiKey: "${currentTeam?.api_token}", host: "${window.location.origin}")\n\nconfiguration.captureApplicationLifecycleEvents = true; // Record certain application events automatically!\nconfiguration.recordScreenViews = true; // Record screen views automatically!\n\nPHGPostHog.setup(with: configuration)\nlet posthog = PHGPostHog.shared()`} + + ) +} + +export function SDKInstallIOSInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Configure Swift

+ +

Or configure Objective-C

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/js-web.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/js-web.tsx new file mode 100644 index 0000000000000..88b5e8acc8adc --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/js-web.tsx @@ -0,0 +1,46 @@ +import { JSSnippet } from 'lib/components/JSSnippet' +import { LemonDivider } from 'lib/lemon-ui/LemonDivider' +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +export function JSInstallSnippet(): JSX.Element { + return ( + + {['npm install posthog-js', '# OR', 'yarn add posthog-js', '# OR', 'pnpm add posthog-js'].join('\n')} + + ) +} + +export function JSSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {[ + "import posthog from 'posthog-js'", + '', + `posthog.init('${currentTeam?.api_token}', { api_host: '${window.location.origin}' })`, + ].join('\n')} + + ) +} + +export function SDKInstallJSWebInstructions(): JSX.Element { + return ( + <> +

Option 1. Code snippet

+

+ Just add this snippet to your website within the <head> tag and you'll be ready to + start using PostHog.{' '} +

+ + +

Option 2. Javascript Library

+

Install the package

+ +

Initialize

+ + + ) +} 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 new file mode 100644 index 0000000000000..a66c40f7c0b7c --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/next-js.tsx @@ -0,0 +1,97 @@ +import { Link } from 'lib/lemon-ui/Link' +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' +import { JSInstallSnippet } from './js-web' + +function NextEnvVarsSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {[ + `NEXT_PUBLIC_POSTHOG_KEY=${currentTeam?.api_token}`, + `NEXT_PUBLIC_POSTHOG_HOST=${window.location.origin}`, + ].join('\n')} + + ) +} + +function NextPagesRouterCodeSnippet(): JSX.Element { + return ( + + {`// pages/_app.js +... +import posthog from 'posthog-js' // Import PostHog + +if (typeof window !== 'undefined') { // checks that we are client-side + posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { + api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com', + loaded: (posthog) => { + if (process.env.NODE_ENV === 'development') posthog.debug() // debug mode in development + }, + }) +} + +export default function App({ Component, pageProps }) { + const router = useRouter() + ...`} + + ) +} + +function NextAppRouterCodeSnippet(): JSX.Element { + return ( + + {`// app/providers.js +'use client' +... +import posthog from 'posthog-js' + +if (typeof window !== 'undefined') { + posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { + api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, + }) +} +...`} + + ) +} + +export function SDKInstallNextJSInstructions(): JSX.Element { + return ( + <> +

Install posthog-js using your package manager

+ +

Add environment variables

+

+ Add your environment variables to your .env.local file and to your hosting provider (e.g. Vercel, + Netlify, AWS). You can find your project API key in your project settings. +

+

+ These values need to start with NEXT_PUBLIC_ to be accessible on the + client-side. +

+ + +

Initialize

+

With App router

+

+ If your Next.js app to uses the app router, you can + integrate PostHog by creating a providers file in your app folder. This is because the posthog-js + library needs to be initialized on the client-side using the Next.js{' '} + + 'use client' directive + + . +

+ +

With Pages router

+

+ If your Next.js app uses the pages router, you can + integrate PostHog at the root of your app (pages/_app.js). +

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/nodejs.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/nodejs.tsx new file mode 100644 index 0000000000000..bab12bd12c45e --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/nodejs.tsx @@ -0,0 +1,41 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +export function NodeInstallSnippet(): JSX.Element { + return ( + + {`npm install posthog-node +# OR +yarn add posthog-node +# OR +pnpm add posthog-node`} + + ) +} + +export function NodeSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`import { PostHog } from 'posthog-node' + +const client = new PostHog( + '${currentTeam?.api_token}', + { host: '${window.location.origin}' } +)`} + + ) +} + +export function SDKInstallNodeInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Configure

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/php.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/php.tsx new file mode 100644 index 0000000000000..136dee636404a --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/php.tsx @@ -0,0 +1,44 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function PHPConfigSnippet(): JSX.Element { + return ( + + {`{ + "require": { + "posthog/posthog-php": "1.0.*" + } +}`} + + ) +} + +function PHPInstallSnippet(): JSX.Element { + return {'php composer.phar install'} +} + +function PHPSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`PostHog::init('${currentTeam?.api_token}', + array('host' => '${window.location.origin}') +);`} + + ) +} + +export function SDKInstallPHPInstructions(): JSX.Element { + return ( + <> +

Dependency Setup

+ +

Install

+ +

Configure

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/python.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/python.tsx new file mode 100644 index 0000000000000..54ece50952ec3 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/python.tsx @@ -0,0 +1,32 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function PythonInstallSnippet(): JSX.Element { + return {'pip install posthog'} +} + +function PythonSetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`from posthog import Posthog + +posthog = Posthog(project_api_key='${currentTeam?.api_token}', host='${window.location.origin}') + + `} + + ) +} + +export function SDKInstallPythonInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Configure

+ + + ) +} 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 new file mode 100644 index 0000000000000..298cb434f6751 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react-native.tsx @@ -0,0 +1,52 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' +import { Link } from '@posthog/lemon-ui' + +export function SDKInstallRNInstructions(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + const url = window.location.origin + + return ( + <> +

Install

+ + {`# Expo apps +expo install posthog-react-native expo-file-system expo-application expo-device expo-localization + +# Standard React Native apps +yarn add posthog-react-native @react-native-async-storage/async-storage react-native-device-info +# or +npm i -s posthog-react-native @react-native-async-storage/async-storage react-native-device-info + +# for iOS +cd ios +pod install`} + +

Configure

+

+ PostHog is most easily used via the PostHogProvider component but if you need to + instantiate it directly,{' '} + + check out the docs + {' '} + which explain how to do this correctly. +

+ + {`// App.(js|ts) +import { PostHogProvider } from 'posthog-react-native' +... + +export function MyApp() { + return ( + + + + ) +}`} + + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react.tsx new file mode 100644 index 0000000000000..0f19b890c3e90 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/react.tsx @@ -0,0 +1,63 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' +import { JSInstallSnippet } from './js-web' + +function ReactEnvVarsSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {[ + `REACT_APP_POSTHOG_PUBLIC_KEY=${currentTeam?.api_token}`, + `REACT_APP_PUBLIC_POSTHOG_HOST=${window.location.origin}`, + ].join('\n')} + + ) +} + +function ReactSetupSnippet(): JSX.Element { + return ( + + {`// src/index.js +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; + +import { PostHogProvider} from 'posthog-js/react' + +const options = { + api_host: process.env.REACT_APP_PUBLIC_POSTHOG_HOST, +} + +const root = ReactDOM.createRoot(document.getElementById('root')); +root.render( + + + + + +);`} + + ) +} + +export function SDKInstallReactInstructions(): JSX.Element { + return ( + <> +

Install the package

+ +

Add environment variables

+ +

Initialize

+

+ Integrate PostHog at the root of your app (src/index.js for the default{' '} + create-react-app). +

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ruby.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ruby.tsx new file mode 100644 index 0000000000000..bd5521f351983 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ruby.tsx @@ -0,0 +1,32 @@ +import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { useValues } from 'kea' +import { teamLogic } from 'scenes/teamLogic' + +function RubyInstallSnippet(): JSX.Element { + return {'gem "posthog-ruby"'} +} + +function RubySetupSnippet(): JSX.Element { + const { currentTeam } = useValues(teamLogic) + + return ( + + {`posthog = PostHog::Client.new({ + api_key: "${currentTeam?.api_token}", + host: "${window.location.origin}", + on_error: Proc.new { |status, msg| print msg } +})`} + + ) +} + +export function SDKInstallRubyInstructions(): JSX.Element { + return ( + <> +

Install

+ +

Configure

+ + + ) +} diff --git a/frontend/src/scenes/onboarding/sdks/session-replay/js-web.tsx b/frontend/src/scenes/onboarding/sdks/session-replay/js-web.tsx index 8ef2865c3b834..fc799bbd8a65a 100644 --- a/frontend/src/scenes/onboarding/sdks/session-replay/js-web.tsx +++ b/frontend/src/scenes/onboarding/sdks/session-replay/js-web.tsx @@ -1,39 +1,11 @@ -import { JSSnippet } from 'lib/components/JSSnippet' import { LemonDivider } from 'lib/lemon-ui/LemonDivider' -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' -import { JSInstallSnippet, SessionReplayFinalSteps } from '../shared-snippets' - -function JSSetupSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {[ - "import posthog from 'posthog-js'", - '', - `posthog.init('${currentTeam?.api_token}', { api_host: '${window.location.origin}' })`, - ].join('\n')} - - ) -} +import { SessionReplayFinalSteps } from '../shared-snippets' +import { SDKInstallJSWebInstructions } from '../sdk-install-instructions' export function JSWebInstructions(): JSX.Element { return ( <> -

Option 1. Code snippet

-

- Just add this snippet to your website within the <head> tag and we'll automatically - capture page views, sessions and all relevant interactions within your website. -

- - -

Option 2. Javascript Library

-

Install the package

- -

Initialize

- +

Final steps

diff --git a/frontend/src/scenes/onboarding/sdks/session-replay/next-js.tsx b/frontend/src/scenes/onboarding/sdks/session-replay/next-js.tsx index cda978ee12166..dadd37388cb0a 100644 --- a/frontend/src/scenes/onboarding/sdks/session-replay/next-js.tsx +++ b/frontend/src/scenes/onboarding/sdks/session-replay/next-js.tsx @@ -1,97 +1,10 @@ -import { Link } from 'lib/lemon-ui/Link' -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' -import { JSInstallSnippet, SessionReplayFinalSteps } from '../shared-snippets' - -function NextEnvVarsSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {[ - `NEXT_PUBLIC_POSTHOG_KEY=${currentTeam?.api_token}`, - `NEXT_PUBLIC_POSTHOG_HOST=${window.location.origin}`, - ].join('\n')} - - ) -} - -function NextPagesRouterCodeSnippet(): JSX.Element { - return ( - - {`// pages/_app.js -... -import posthog from 'posthog-js' // Import PostHog - -if (typeof window !== 'undefined') { // checks that we are client-side - posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { - api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com', - loaded: (posthog) => { - if (process.env.NODE_ENV === 'development') posthog.debug() // debug mode in development - }, - }) -} - -export default function App({ Component, pageProps }) { - const router = useRouter() - ...`} - - ) -} - -function NextAppRouterCodeSnippet(): JSX.Element { - return ( - - {`// app/providers.js -'use client' -... -import posthog from 'posthog-js' - -if (typeof window !== 'undefined') { - posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { - api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, - }) -} -...`} - - ) -} +import { SessionReplayFinalSteps } from '../shared-snippets' +import { SDKInstallNextJSInstructions } from '../sdk-install-instructions/next-js' export function NextJSInstructions(): JSX.Element { return ( <> -

Install posthog-js using your package manager

- -

Add environment variables

-

- Add your environment variables to your .env.local file and to your hosting provider (e.g. Vercel, - Netlify, AWS). You can find your project API key in your project settings. -

-

- These values need to start with NEXT_PUBLIC_ to be accessible on the - client-side. -

- - -

Initialize

-

With App router

-

- If your Next.js app to uses the app router, you can - integrate PostHog by creating a providers file in your app folder. This is because the posthog-js - library needs to be initialized on the client-side using the Next.js{' '} - - 'use client' directive - - . -

- -

With Pages router

-

- If your Next.js app uses the pages router, you can - integrate PostHog at the root of your app (pages/_app.js). -

- + ) diff --git a/frontend/src/scenes/onboarding/sdks/session-replay/react.tsx b/frontend/src/scenes/onboarding/sdks/session-replay/react.tsx index 86fdfc0f527c7..361884112a15b 100644 --- a/frontend/src/scenes/onboarding/sdks/session-replay/react.tsx +++ b/frontend/src/scenes/onboarding/sdks/session-replay/react.tsx @@ -1,63 +1,10 @@ -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' -import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' -import { JSInstallSnippet, SessionReplayFinalSteps } from '../shared-snippets' - -function ReactEnvVarsSnippet(): JSX.Element { - const { currentTeam } = useValues(teamLogic) - - return ( - - {[ - `REACT_APP_POSTHOG_PUBLIC_KEY=${currentTeam?.api_token}`, - `REACT_APP_PUBLIC_POSTHOG_HOST=${window.location.origin}`, - ].join('\n')} - - ) -} - -function ReactSetupSnippet(): JSX.Element { - return ( - - {`// src/index.js -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import App from './App'; - -import { PostHogProvider} from 'posthog-js/react' - -const options = { - api_host: process.env.REACT_APP_PUBLIC_POSTHOG_HOST, -} - -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - - - - - -);`} - - ) -} +import { SessionReplayFinalSteps } from '../shared-snippets' +import { SDKInstallReactInstructions } from '../sdk-install-instructions/react' export function ReactInstructions(): JSX.Element { return ( <> -

Install the package

- -

Add environment variables

- -

Initialize

-

- Integrate PostHog at the root of your app (src/index.js for the default{' '} - create-react-app). -

- + ) diff --git a/frontend/src/scenes/onboarding/sdks/shared-snippets.tsx b/frontend/src/scenes/onboarding/sdks/shared-snippets.tsx index f8c2fe58417c1..215f9a07693d2 100644 --- a/frontend/src/scenes/onboarding/sdks/shared-snippets.tsx +++ b/frontend/src/scenes/onboarding/sdks/shared-snippets.tsx @@ -1,14 +1,5 @@ -import { CodeSnippet, Language } from 'lib/components/CodeSnippet' import { Link } from 'lib/lemon-ui/Link' -export function JSInstallSnippet(): JSX.Element { - return ( - - {['npm install posthog-js', '# OR', 'yarn add posthog-js', '# OR', 'pnpm add posthog-js'].join('\n')} - - ) -} - export function SessionReplayFinalSteps(): JSX.Element { return ( <>