Skip to content

Commit 9f27dd7

Browse files
authored
Merge pull request #10153 from gitbutlerapp/onboarding-posthog-events
Add custom PostHog events for onboarding flow
2 parents 737d7b3 + 0f29e35 commit 9f27dd7

File tree

7 files changed

+47
-8
lines changed

7 files changed

+47
-8
lines changed

apps/desktop/src/components/AnalyticsConfirmation.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import AnalyticsSettings from '$components/AnalyticsSettings.svelte';
33
import { initAnalyticsIfEnabled } from '$lib/analytics/analytics';
4-
import { POSTHOG_WRAPPER } from '$lib/analytics/posthog';
4+
import { OnboardingEvent, POSTHOG_WRAPPER } from '$lib/analytics/posthog';
55
import { APP_SETTINGS } from '$lib/config/appSettings';
66
import { inject } from '@gitbutler/core/context';
77
import { Button, TestId } from '@gitbutler/ui';
@@ -23,6 +23,7 @@
2323
onclick={() => {
2424
$analyticsConfirmed = true;
2525
initAnalyticsIfEnabled(appSettings, posthog);
26+
posthog.captureOnboarding(OnboardingEvent.ConfirmedAnalytics);
2627
}}
2728
>
2829
Continue

apps/desktop/src/components/CloneForm.svelte

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { goto } from '$app/navigation';
33
import InfoMessage, { type MessageStyle } from '$components/InfoMessage.svelte';
44
import Section from '$components/Section.svelte';
5-
import { POSTHOG_WRAPPER } from '$lib/analytics/posthog';
5+
import { OnboardingEvent, POSTHOG_WRAPPER } from '$lib/analytics/posthog';
66
import { BACKEND } from '$lib/backend';
77
import { GIT_SERVICE } from '$lib/git/gitService';
88
import { handleAddProjectOutcome } from '$lib/project/project';
@@ -87,17 +87,21 @@
8787
8888
await gitService.cloneRepo(repositoryUrl, targetDir);
8989
90-
posthog.capture('Repository Cloned', { protocol: remoteUrl.protocol });
90+
posthog.captureOnboarding(OnboardingEvent.ClonedProject);
9191
const outcome = await projectsService.addProject(targetDir);
9292
if (!outcome) {
93+
posthog.captureOnboarding(
94+
OnboardingEvent.ClonedProjectFailed,
95+
'Failed to add project after cloning'
96+
);
9397
throw new Error('Failed to add project after cloning.');
9498
}
9599
96100
handleAddProjectOutcome(outcome, (project) => goto(projectPath(project.id)));
97101
} catch (e) {
98102
Sentry.captureException(e);
99103
const errorMessage = getErrorMessage(e);
100-
posthog.capture('Repository Clone Failure', { error: errorMessage });
104+
posthog.captureOnboarding(OnboardingEvent.ClonedProjectFailed, e);
101105
errors.push({
102106
label: errorMessage
103107
});

apps/desktop/src/components/ProjectSetup.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import KeysForm from '$components/KeysForm.svelte';
55
import ProjectSetupTarget from '$components/ProjectSetupTarget.svelte';
66
import ReduxResult from '$components/ReduxResult.svelte';
7-
import { POSTHOG_WRAPPER } from '$lib/analytics/posthog';
7+
import { OnboardingEvent, POSTHOG_WRAPPER } from '$lib/analytics/posthog';
88
import newProjectSvg from '$lib/assets/illustrations/new-project.svg?raw';
99
import { BACKEND } from '$lib/backend';
1010
import { BASE_BRANCH_SERVICE } from '$lib/baseBranch/baseBranchService.svelte';
@@ -38,9 +38,10 @@
3838
branch: selectedBranch[0],
3939
pushRemote: selectedBranch[1]
4040
});
41+
posthog.captureOnboarding(OnboardingEvent.SetTargetBranch);
4142
goto(`/${projectId}/`, { invalidateAll: true });
42-
} finally {
43-
posthog.capture('Project Setup Complete');
43+
} catch (e: unknown) {
44+
posthog.captureOnboarding(OnboardingEvent.SetTargetBranchFailed, e);
4445
}
4546
}
4647

apps/desktop/src/components/Welcome.svelte

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import IconLink from '$components/IconLink.svelte';
44
import WelcomeAction from '$components/WelcomeAction.svelte';
55
import WelcomeSigninAction from '$components/WelcomeSigninAction.svelte';
6+
import { OnboardingEvent, POSTHOG_WRAPPER } from '$lib/analytics/posthog';
67
import cloneRepoSvg from '$lib/assets/welcome/clone-repo.svg?raw';
78
import newProjectSvg from '$lib/assets/welcome/new-local-project.svg?raw';
89
import { handleAddProjectOutcome } from '$lib/project/project';
@@ -11,6 +12,7 @@
1112
import { TestId } from '@gitbutler/ui';
1213
1314
const projectsService = inject(PROJECTS_SERVICE);
15+
const posthog = inject(POSTHOG_WRAPPER);
1416
1517
let newProjectLoading = $state(false);
1618
let directoryInputElement = $state<HTMLInputElement | undefined>();
@@ -21,9 +23,12 @@
2123
const testDirectoryPath = directoryInputElement?.value;
2224
const outcome = await projectsService.addProject(testDirectoryPath ?? '');
2325
26+
posthog.captureOnboarding(OnboardingEvent.AddLocalProject);
2427
if (outcome) {
2528
handleAddProjectOutcome(outcome);
2629
}
30+
} catch (e: unknown) {
31+
posthog.captureOnboarding(OnboardingEvent.AddLocalProjectFailed, e);
2732
} finally {
2833
newProjectLoading = false;
2934
}

apps/desktop/src/components/WelcomeSigninAction.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
loading={$loading}
2929
onclick={async () => {
3030
$aborted = false;
31+
// TODO: Track login calls
3132
await userService.login(aborted);
3233
}}
3334
rowReverse

apps/desktop/src/lib/analytics/posthog.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { parseQueryError } from '$lib/error/error';
12
import { InjectionToken } from '@gitbutler/core/context';
23
import { PostHog, posthog, type Properties } from 'posthog-js';
34
import type { EventContext } from '$lib/analytics/eventContext';
@@ -23,6 +24,18 @@ export class PostHogWrapper {
2324
this._instance?.capture(eventName, newProperties);
2425
}
2526

27+
captureOnboarding(event: OnboardingEvent, error?: unknown) {
28+
const context = this.eventContext.getAll();
29+
const parsedError = parseQueryError(error);
30+
const properties = {
31+
...context,
32+
error_title: parsedError.name,
33+
error_message: parsedError.message,
34+
error_code: parsedError.code
35+
};
36+
this._instance?.capture(event, properties);
37+
}
38+
2639
async init() {
2740
const appInfo = await this.backend.getAppInfo();
2841
this._instance = posthog.init(PUBLIC_POSTHOG_API_KEY, {
@@ -78,3 +91,15 @@ export class PostHogWrapper {
7891
}
7992
}
8093
}
94+
95+
export enum OnboardingEvent {
96+
ConfirmedAnalytics = 'onboarding_confirmed_analytics',
97+
AddLocalProject = 'onboarding_add_local_project',
98+
AddLocalProjectFailed = 'onboarding_add_local_project_failed',
99+
ClonedProject = 'onboarding_cloned_project',
100+
ClonedProjectFailed = 'onboarding_cloned_project_failed',
101+
SetTargetBranch = 'onboarding_set_target_branch',
102+
SetTargetBranchFailed = 'onboarding_set_target_branch_failed',
103+
SetProjectActive = 'onboarding_set_project_active',
104+
SetProjectActiveFailed = 'onboarding_set_project_active_failed'
105+
}

apps/desktop/src/routes/[projectId]/+layout.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import ProblemLoadingRepo from '$components/ProblemLoadingRepo.svelte';
1111
import ProjectSettingsMenuAction from '$components/ProjectSettingsMenuAction.svelte';
1212
import ReduxResult from '$components/ReduxResult.svelte';
13-
import { POSTHOG_WRAPPER } from '$lib/analytics/posthog';
13+
import { OnboardingEvent, POSTHOG_WRAPPER } from '$lib/analytics/posthog';
1414
import { BASE_BRANCH_SERVICE } from '$lib/baseBranch/baseBranchService.svelte';
1515
import { BRANCH_SERVICE } from '$lib/branches/branchService.svelte';
1616
import { SETTINGS_SERVICE } from '$lib/config/appSettingsV2';
@@ -261,6 +261,7 @@
261261
const dontShowAgainKey = `git-filters--dont-show-again--${projectId}`;
262262
try {
263263
const info = await projectsService.setActiveProject(projectId);
264+
posthog.captureOnboarding(OnboardingEvent.SetProjectActive);
264265
265266
if (!info) return;
266267
@@ -285,6 +286,7 @@
285286
});
286287
}
287288
} catch (error: unknown) {
289+
posthog.captureOnboarding(OnboardingEvent.SetProjectActiveFailed);
288290
showError('Failed to set the project active', error);
289291
}
290292
}

0 commit comments

Comments
 (0)