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"