diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts index cbc9a025..042c6287 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -16,6 +16,7 @@ const config = { ['de-de', 'German'], ], LANGUAGE_CODE: 'en-us', + POSTHOG_KEY: {}, SENTRY_DSN: null, }; diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index 658588e5..7ae5efa6 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -31,6 +31,7 @@ "lodash": "4.17.21", "luxon": "3.5.0", "next": "15.1.3", + "posthog-js": "1.204.0", "react": "*", "react-aria-components": "1.5.0", "react-dom": "*", diff --git a/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx b/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx index 57033110..8d021b14 100644 --- a/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx +++ b/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx @@ -3,7 +3,7 @@ import { PropsWithChildren, useEffect } from 'react'; import { Box } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; -import { configureCrispSession } from '@/services'; +import { PostHogProvider, configureCrispSession } from '@/services'; import { useSentryStore } from '@/stores/useSentryStore'; import { useConfig } from './api/useConfig'; @@ -45,5 +45,5 @@ export const ConfigProvider = ({ children }: PropsWithChildren) => { ); } - return children; + return {children}; }; diff --git a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx index 5cb6d3a9..7f26e9a8 100644 --- a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx +++ b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx @@ -2,6 +2,7 @@ import { useQuery } from '@tanstack/react-query'; import { APIError, errorCauses, fetchAPI } from '@/api'; import { Theme } from '@/cunningham/'; +import { PostHogConf } from '@/services'; interface ConfigResponse { LANGUAGES: [string, string][]; @@ -11,6 +12,7 @@ interface ConfigResponse { CRISP_WEBSITE_ID?: string; FRONTEND_THEME?: Theme; MEDIA_BASE_URL?: string; + POSTHOG_KEY?: PostHogConf; SENTRY_DSN?: string; } diff --git a/src/frontend/apps/impress/src/services/Posthog.tsx b/src/frontend/apps/impress/src/services/Posthog.tsx new file mode 100644 index 00000000..a8b83719 --- /dev/null +++ b/src/frontend/apps/impress/src/services/Posthog.tsx @@ -0,0 +1,46 @@ +import { Router } from 'next/router'; +import posthog from 'posthog-js'; +import { PostHogProvider as PHProvider } from 'posthog-js/react'; +import { PropsWithChildren, useEffect } from 'react'; + +export interface PostHogConf { + id: string; + host: string; +} + +interface PostHogProviderProps { + conf?: PostHogConf; +} + +export function PostHogProvider({ + children, + conf, +}: PropsWithChildren) { + useEffect(() => { + if (!conf?.id || !conf?.host || posthog.__loaded) { + return; + } + + posthog.init(conf.id, { + api_host: conf.host, + person_profiles: 'always', + loaded: (posthog) => { + if (process.env.NODE_ENV === 'development') { + posthog.debug(); + } + }, + capture_pageview: false, + capture_pageleave: true, + }); + + const handleRouteChange = () => posthog?.capture('$pageview'); + + Router.events.on('routeChangeComplete', handleRouteChange); + + return () => { + Router.events.off('routeChangeComplete', handleRouteChange); + }; + }, [conf?.host, conf?.id]); + + return {children}; +} diff --git a/src/frontend/apps/impress/src/services/index.ts b/src/frontend/apps/impress/src/services/index.ts index 08bbf631..967ebd48 100644 --- a/src/frontend/apps/impress/src/services/index.ts +++ b/src/frontend/apps/impress/src/services/index.ts @@ -1 +1,2 @@ export * from './Crisp'; +export * from './Posthog'; diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index 14bdb369..8b5d18b3 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -6286,7 +6286,7 @@ core-js-compat@^3.38.0, core-js-compat@^3.38.1: dependencies: browserslist "^4.24.2" -core-js@^3.0.0: +core-js@^3.0.0, core-js@^3.38.1: version "3.39.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83" integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g== @@ -7536,6 +7536,11 @@ fetch-mock@9.11.0: querystring "^0.2.0" whatwg-url "^6.5.0" +fflate@^0.4.8: + version "0.4.8" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae" + integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA== + figlet@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.7.0.tgz#46903a04603fd19c3e380358418bb2703587a72e" @@ -10921,6 +10926,21 @@ postgres-range@^1.1.1: resolved "https://registry.yarnpkg.com/postgres-range/-/postgres-range-1.1.4.tgz#a59c5f9520909bcec5e63e8cf913a92e4c952863" integrity sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w== +posthog-js@1.204.0: + version "1.204.0" + resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.204.0.tgz#73843af471fcc484ca1e8e1bcc927887cf81b4ba" + integrity sha512-wVt948wKPPztCZ3OeDq8y0dtaPbhbY8vFuEVBUNHOn7PohbTXr7HZ4CNhH8fXgFkx5COEzz/20wWJmEsSU5oCA== + dependencies: + core-js "^3.38.1" + fflate "^0.4.8" + preact "^10.19.3" + web-vitals "^4.2.0" + +preact@^10.19.3: + version "10.25.4" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.25.4.tgz#c1d00bee9d7b9dcd06a2311d9951973b506ae8ac" + integrity sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -13622,6 +13642,11 @@ web-namespaces@^2.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== +web-vitals@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-4.2.4.tgz#1d20bc8590a37769bd0902b289550936069184b7" + integrity sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"