Skip to content

Commit 280cf16

Browse files
feat(posthog): integrate PostHog for analytics tracking in the application
The application now includes PostHog for tracking user interactions. This integration captures events such as quiz completions and shares, enhancing our ability to analyze user behavior. The addition of PostHog client setup allows for better monitoring and insights into user engagement, which is crucial for improving the overall user experience.
1 parent 939c1a2 commit 280cf16

File tree

7 files changed

+149
-3
lines changed

7 files changed

+149
-3
lines changed

package-lock.json

Lines changed: 78 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
},
3737
"dependencies": {
3838
"@types/js-yaml": "^4.0.9",
39-
"js-yaml": "^4.1.0"
39+
"js-yaml": "^4.1.0",
40+
"posthog-js": "^1.260.2",
41+
"posthog-node": "^5.7.0"
4042
}
4143
}

src/lib/components/Results.svelte

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,28 @@
33
import { generateShareUrl, getShareText, shareLinks, copyToClipboard } from '$lib/utils/sharing';
44
import { quizStore } from '$lib/stores/quiz';
55
import { mbtiDescriptions, type MBTIType } from '$lib/data/mbti-descriptions';
6+
import { onMount } from 'svelte';
7+
import { browser } from '$app/environment';
8+
import posthog from 'posthog-js';
69
710
export let language: Language;
811
export let onRestart: () => void;
912
1013
let copied = false;
1114
15+
// Track when results page is reached
16+
onMount(() => {
17+
if (browser) {
18+
posthog.capture('quiz_completed', {
19+
language: language.name,
20+
language_id: language.id,
21+
mbti_type: $quizStore.mbtiType,
22+
mbti_questions_answered: $quizStore.mbtiAnswers.length,
23+
language_questions_answered: $quizStore.languageAnswers.length
24+
});
25+
}
26+
});
27+
1228
$: shareUrl = generateShareUrl({
1329
languageId: language.id,
1430
mbtiType: $quizStore.mbtiType
@@ -20,12 +36,26 @@
2036
if (success) {
2137
copied = true;
2238
setTimeout(() => (copied = false), 2000);
39+
if (browser) {
40+
posthog.capture('share_clicked', {
41+
platform: 'copy_link',
42+
language: language.name,
43+
mbti_type: $quizStore.mbtiType
44+
});
45+
}
2346
}
2447
}
2548
2649
function handleShare(platform: keyof typeof shareLinks) {
2750
const url = shareLinks[platform](shareUrl, shareText);
2851
window.open(url, '_blank', 'width=600,height=400');
52+
if (browser) {
53+
posthog.capture('share_clicked', {
54+
platform,
55+
language: language.name,
56+
mbti_type: $quizStore.mbtiType
57+
});
58+
}
2959
}
3060
</script>
3161

src/lib/server/posthog.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import posthog, { PostHog } from 'posthog-node';
2+
import { PUBLIC_POSTHOG_KEY, PUBLIC_POSTHOG_HOST } from '$env/static/public';
3+
4+
let _client: PostHog | null = null;
5+
6+
export function getPostHogClient() {
7+
if (!_client) {
8+
_client = new posthog.PostHog(PUBLIC_POSTHOG_KEY, {
9+
host: PUBLIC_POSTHOG_HOST
10+
});
11+
}
12+
return _client;
13+
}

src/routes/+layout.svelte

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
<script lang="ts">
22
import favicon from '$lib/assets/favicon.svg';
33
import '../app.css';
4+
import { browser } from '$app/environment';
5+
import { beforeNavigate, afterNavigate } from '$app/navigation';
6+
import posthog from 'posthog-js';
47
58
let { children } = $props();
9+
10+
if (browser) {
11+
beforeNavigate(() => posthog.capture('$pageleave'));
12+
afterNavigate(() => posthog.capture('$pageview'));
13+
}
614
</script>
715

816
<svelte:head>

src/routes/+layout.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
1+
import posthog from 'posthog-js';
2+
import { browser } from '$app/environment';
3+
import { PUBLIC_POSTHOG_KEY, PUBLIC_POSTHOG_HOST } from '$env/static/public';
4+
15
export const prerender = true;
26
export const ssr = false;
7+
8+
export const load = async () => {
9+
if (browser) {
10+
posthog.init(PUBLIC_POSTHOG_KEY, {
11+
api_host: PUBLIC_POSTHOG_HOST,
12+
capture_pageview: false,
13+
capture_pageleave: false,
14+
capture_exceptions: true // This enables capturing exceptions using Error Tracking
15+
});
16+
}
17+
};

svelte.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ const config = {
1616
strict: true
1717
}),
1818
paths: {
19-
base: process.env.NODE_ENV === 'production' ? '/programming-personality' : ''
19+
base: process.env.NODE_ENV === 'production' ? '/programming-personality' : '',
20+
relative: false // Required for PostHog session replay to work correctly
2021
}
2122
}
2223
};

0 commit comments

Comments
 (0)