update: handle events.

This commit is contained in:
Darshan
2025-05-10 17:20:12 +05:30
parent 3084d63de1
commit b328ead8cf
24 changed files with 108 additions and 125 deletions

View File

@@ -1,12 +1,11 @@
import { Analytics, type AnalyticsPlugin } from 'analytics';
import Plausible from 'plausible-tracker';
import posthogEvent from 'posthog-js';
import { get } from 'svelte/store';
import { page } from '$app/stores';
import { page } from '$app/state';
import { ENV } from '$lib/system';
import { browser } from '$app/environment';
import posthogEvent from 'posthog-js';
import Plausible from 'plausible-tracker';
import { Analytics, type AnalyticsPlugin } from 'analytics';
type Payload = {
payload: {
event: string;
@@ -55,30 +54,20 @@ const analytics = Analytics({
plugins: [plausible('appwrite.io')]
});
export type TrackEventArgs = {
plausible?: { name: string; data?: object };
posthog?: { name: string };
};
export type TrackEventArgs = { name: string; data?: object };
export const trackEvent = async (platforms: TrackEventArgs) => {
if (!isTrackingAllowed()) {
export const trackEvent = (eventArgs?: string | TrackEventArgs): void => {
if (!eventArgs || ENV.TEST) return;
const path = page.route.id ?? '';
const name = typeof eventArgs === 'string' ? eventArgs : eventArgs.name;
const data = typeof eventArgs === 'string' ? { path } : { ...eventArgs.data, path };
if (ENV.DEV || ENV.PREVIEW) {
console.log(`[Analytics] Event:`, name, data);
return;
}
const currentPage = get(page);
const path = currentPage.route.id ?? '';
if (ENV.DEV || ENV.PREVIEW) {
console.log(`[Analytics] Event`, platforms.plausible, platforms.posthog);
} else {
if (platforms.plausible) {
await analytics.track(platforms.plausible.name, { ...platforms.plausible.data, path });
}
if (platforms.posthog) {
posthogEvent.capture(platforms.posthog.name);
}
}
posthogEvent.capture(name, data);
analytics.track(name, data).then();
};
export const isTrackingAllowed = () => !ENV.TEST;

View File

@@ -1,8 +1,7 @@
<script lang="ts">
import { trackEvent } from '$lib/actions/analytics';
import { createDialog, melt } from '@melt-ui/svelte';
import { fade, scale } from 'svelte/transition';
import { Button, Icon } from '$lib/components/ui';
import { createDialog, melt } from '@melt-ui/svelte';
const {
elements: { portalled, trigger, content, overlay },
@@ -13,14 +12,9 @@
</script>
<Button
class="cursor-pointer shadow-[0_2px_40px_rgba(0,0,0,0.5)] transition-opacity hover:opacity-90 active:scale-95"
action={trigger}
onclick={() => {
trackEvent({
plausible: { name: 'Appwrite in 100 seconds' },
posthog: { name: 'intro-video-btn_hero_click' }
});
}}
event={'intro-video-btn_hero_click'}
class="cursor-pointer shadow-[0_2px_40px_rgba(0,0,0,0.5)] transition-opacity hover:opacity-90 active:scale-95"
>
Appwrite in 100 seconds

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import { createAccordion, melt } from '@melt-ui/svelte';
import { slide } from 'svelte/transition';
import { trackEvent } from '$lib/actions/analytics';
import { createAccordion, melt } from '@melt-ui/svelte';
export let noBorder = false;
@@ -111,7 +112,16 @@
<ul class="web-footer-nav-secondary-list text-sub-body">
{#each items as { href, label, target, rel }}
<li>
<a class="web-link" {href} {target} {rel}>{label}</a>
<a
class="web-link"
{href}
{target}
{rel}
onclick={() =>
trackEvent(
`footer-${label.toLowerCase().replace(' ', '_')}-click`
)}>{label}</a
>
</li>
{/each}
</ul>

View File

@@ -1,31 +1,21 @@
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import { trackEvent } from '$lib/actions/analytics';
import { browser } from '$app/environment';
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
import { Button } from '$lib/components/ui';
import { classNames } from '$lib/utils/classnames';
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
interface Props {
class?: string;
}
const { class: className }: Props = $props();
const isLoggedIn = browser && 'loggedIn' in document.body.dataset;
function getTrackingEventName() {
return browser ? (isLoggedIn ? 'Go to console' : 'Start building') : 'Start building';
}
</script>
<Button
class={classNames('web-u-inline-width-100-percent-mobile', className)}
href={getAppwriteDashboardUrl()}
onclick={() =>
trackEvent({
plausible: { name: `${getTrackingEventName()} in header` },
...(isLoggedIn ? {} : { posthog: { name: 'get-started-btn_nav_click' } })
})}
event={{ name: 'get-started-btn-nav-click' }}
class={classNames('web-u-inline-width-100-percent-mobile', className)}
>
<span class="hidden group-[&[data-logged-in]]/body:block" aria-hidden={!isLoggedIn}
>Go to Console</span

View File

@@ -41,12 +41,7 @@
href={link.href}
data-initialized={initialized ? '' : undefined}
data-badge={link.showBadge ? '' : undefined}
on:click={() => {
trackEvent({
plausible: { name: `${link.label} in header` },
posthog: { name: `${link.label.toLowerCase()}_nav_click` }
});
}}
onclick={() => trackEvent(`main-nav-${link.label.toLowerCase()}-nav-click`)}
>{link.label}
</a>
{/if}

View File

@@ -1,7 +1,6 @@
<script lang="ts">
import { trackEvent } from '$lib/actions/analytics';
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
import { Button, type Variant } from '$lib/components/ui';
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
const plans: Array<{
name: string;
@@ -21,7 +20,7 @@
buttonText: 'Get started',
buttonLink: getAppwriteDashboardUrl('/register'),
buttonVariant: 'secondary',
eventName: 'Get started Free plan'
eventName: 'footer-plans-free-click'
},
{
name: 'Pro',
@@ -33,7 +32,7 @@
buttonText: 'Start building',
buttonLink: getAppwriteDashboardUrl('/console?type=create&plan=tier-1'),
buttonVariant: 'primary',
eventName: 'Get started Pro plan'
eventName: 'footer-plans-pro-click'
},
{
name: 'Scale',
@@ -44,7 +43,7 @@
buttonText: 'Start building',
buttonLink: getAppwriteDashboardUrl('/console?type=create&plan=tier-2'),
buttonVariant: 'secondary',
eventName: 'Get started Scale plan'
eventName: 'footer-plans-scale-click'
},
{
name: 'Enterprise',
@@ -53,7 +52,7 @@
buttonText: 'Contact us',
buttonLink: '/contact-us/enterprise',
buttonVariant: 'secondary',
eventName: 'Get started Enterprise plan'
eventName: 'footer-plans-enterprise-click'
}
];
</script>
@@ -73,9 +72,9 @@
</h2>
<Button
variant="transparent"
href={getAppwriteDashboardUrl()}
class="self-center"
onclick={() => trackEvent({ plausible: { name: 'Get started in pre footer' } })}
href={getAppwriteDashboardUrl()}
event={{ name: 'footer-plans-get-started' }}
>
<span class="text">Get started</span>
</Button>
@@ -117,15 +116,9 @@
{plan.description}
</p>
<Button
event={plan.eventName}
variant={plan.buttonVariant}
href={plan.buttonLink}
class="w-full! flex-3 self-end md:w-fit"
onclick={() =>
trackEvent({
plausible: {
name: plan.eventName
}
})}
>
<span class="text" style:padding-inline="0.5rem">{plan.buttonText}</span
>

View File

@@ -1,9 +1,9 @@
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import { melt, createCollapsible } from '@melt-ui/svelte';
import { slide } from 'svelte/transition';
import { products, sublinks } from './ProductsSubmenu.svelte';
import { classNames } from '$lib/utils/classnames';
import { trackEvent } from '$lib/actions/analytics';
import { melt, createCollapsible } from '@melt-ui/svelte';
import { products, sublinks } from './ProductsSubmenu.svelte';
export let label: string;
@@ -34,13 +34,11 @@
{#each products as product}
<a
href={product.href}
onclick={() =>
trackEvent(
`products-mobile-submenu-${product.name.toLowerCase()}-click`
)}
class="group flex gap-3 rounded-xl p-2 text-white transition-colors outline-none focus:bg-white/8"
on:click={() =>
trackEvent({
plausible: {
name: `${product.name} in products submenu`
}
})}
>
<div
class="flex size-12 shrink-0 items-center justify-center rounded-lg border border-white/12 bg-white/6"

View File

@@ -64,7 +64,6 @@
</script>
<script lang="ts">
import { dev } from '$app/environment';
import { trackEvent } from '$lib/actions/analytics';
import { classNames } from '$lib/utils/classnames';
import { createDropdownMenu, melt } from '@melt-ui/svelte';
@@ -117,12 +116,8 @@
<a
href={product.href}
use:melt={$item}
on:click={() =>
trackEvent({
plausible: {
name: `${product.name} in products submenu`
}
})}
onclick={() =>
trackEvent(`products-submenu-${product.name.toLowerCase()}-click`)}
class="group flex gap-3 rounded-xl p-1 text-white transition-colors outline-none focus:bg-white/8"
>
<div

View File

@@ -75,7 +75,10 @@
<a
href={platform.href}
class="web-icon-button web-box-icon has-border-gradient"
on:click={() => trackEvent({ plausible: { name: `${platform.name} clicked` } })}
onclick={() =>
trackEvent(
`technologies-${platform.name.replace(' ', '-').toLowerCase()}-click`
)}
>
<img
src={platform.image}

View File

@@ -1,4 +1,6 @@
<script lang="ts" module>
import { type VariantProps, cva } from 'cva';
// TODO: replace _button.scss with Tailwind classes for long-term maintainability
const button = cva(['web-button'], {
variants: {
@@ -17,12 +19,12 @@
</script>
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import { type VariantProps, cva } from 'cva';
import { type VariantProps } from 'cva';
import type { Snippet } from 'svelte';
import type { Action } from 'svelte/action';
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
import { classNames } from '$lib/utils/classnames';
import { trackEvent, type TrackEventArgs } from '$lib/actions/analytics';
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
type ButtonOrAnchorProps =
| (HTMLButtonAttributes & { href?: undefined })
@@ -31,7 +33,7 @@
type Props = {
action?: Action;
children: Snippet;
events?: TrackEventArgs;
event?: string | TrackEventArgs;
} & VariantProps<typeof button> &
ButtonOrAnchorProps;
@@ -41,7 +43,7 @@
action = () => {},
children,
class: classes,
events,
event,
...rest
}: Props = $props();
@@ -49,11 +51,11 @@
</script>
{#if href}
<a use:action {href} class={buttonClasses} {...rest as HTMLAnchorAttributes}>
<a use:action {href} class={buttonClasses} onclick={() => event && trackEvent(event)} {...rest}>
{@render children()}
</a>
{:else}
<button use:action class={buttonClasses} {...rest as HTMLButtonAttributes}>
<button use:action class={buttonClasses} onclick={() => event && trackEvent(event)} {...rest}>
{@render children()}
</button>
{/if}

View File

@@ -227,11 +227,7 @@
target="_blank"
rel="noopener noreferrer"
class="web-u-inline-width-100-percent-mobile"
onclick={() =>
trackEvent({
plausible: { name: 'Star on GitHub in header' },
posthog: { name: 'github-stars_nav_click' }
})}
event={{ name: 'github-stars-nav-click' }}
>
<Icon name="star" aria-hidden="true" />
<span class="text">Star on GitHub</span>

View File

@@ -127,10 +127,7 @@
const eventName = `${pageName}_scroll-depth_${threshold * 100}prct_scroll`;
tracked.add(threshold);
trackEvent({
plausible: { name: eventName },
posthog: { name: eventName }
});
trackEvent(eventName);
}
});
}

View File

@@ -136,7 +136,7 @@
<a
href="/blog/post/init-may-2025"
class="web-hero-banner-button mb-4"
on:click={() => trackEvent({ plausible: { name: 'Banner button click' } })}
onclick={() => trackEvent('main-banner-button-click')}
>
<span class="web-icon-star shrink-0" aria-hidden="true"></span>
<span class="text-caption shrink-0 font-medium">New</span>
@@ -162,11 +162,7 @@
<Button
href={getAppwriteDashboardUrl()}
class="w-full lg:w-fit"
onclick={() =>
trackEvent({
plausible: { name: 'Get started in hero' },
posthog: { name: 'get-started-btn_hero_click' }
})}
onclick={() => trackEvent('get-started-btn-hero-click')}
>
Start building
</Button>
@@ -487,7 +483,7 @@
<Button
href="/docs/sdks"
variant="secondary"
onclick={() => trackEvent({ plausible: { name: 'Explore all SDKs' } })}
onclick={() => trackEvent('main-explore-all-sdks-click')}
>Explore all SDKs</Button
>
</section>

View File

@@ -57,6 +57,7 @@
import { SOCIAL_STATS } from '$lib/constants';
import { Button, Icon } from '$lib/components/ui';
import { trackEvent } from '$lib/actions/analytics';
import InlineTag from '$lib/components/ui/inline-tag.svelte';
let { data } = $props();
@@ -113,6 +114,9 @@
submitting = true;
error = undefined;
const response = await newsletter(name, email);
trackEvent('community-insights-subscribe-submit');
submitting = false;
if (response.status >= 400) {
error = response.status >= 500 ? 'Server Error.' : 'Error submitting form.';
@@ -464,6 +468,7 @@
target="_blank"
rel="noopener noreferrer"
class="mt-4 self-center"
event="community-built-with-appwrite-click"
>
<span>View all projects</span>
</Button>

View File

@@ -59,7 +59,7 @@
{description}
</p>
<div class="mbs-auto flex flex-wrap gap-2 pt-4">
<Button variant="secondary" disabled={hasPast}>
<Button variant="secondary" disabled={hasPast} event="community-events-click">
<span>{buttonText}</span>
</Button>
</div>

View File

@@ -11,6 +11,8 @@
</script>
<script lang="ts">
import { trackEvent } from '$lib/actions/analytics';
type $$Props = ProjectCardProps;
export let title: $$Props['title'];
@@ -25,6 +27,7 @@
{href}
target="_blank"
rel="noopener noreferrer"
onclick={() => trackEvent(`community-project-${title.toLowerCase().replace(' ', '_')}-click`)}
>
<div class="p-3">
<h3 class="text-body text-primary font-medium">{title}</h3>

View File

@@ -67,6 +67,7 @@
Designed for and by developers
</h2>
<Button
event="company-careers-click"
href="https://appwrite.careers"
class="web-u-inline-width-100-percent-mobile-break1 self-start"
target="_blank"

View File

@@ -8,6 +8,7 @@
import { PUBLIC_GROWTH_ENDPOINT } from '$env/static/public';
import { getReferrerAndUtmSource } from '$lib/utils/utm';
import { Button } from '$lib/components/ui';
import { trackEvent } from '$lib/actions/analytics';
let email = '';
let firstName = '';
@@ -36,6 +37,8 @@
})
});
trackEvent('contact-form-submit');
submitting = false;
if (response.status >= 400) {

View File

@@ -10,6 +10,7 @@
import LogoList from '$lib/components/LogoList.svelte';
import Scale from '$routes/(experiments)/new-homepage/(components)/scale.svelte';
import { Button } from '$lib/components/ui';
import { trackEvent } from '$lib/actions/analytics';
let email = '';
let firstName = '';
@@ -48,6 +49,8 @@
})
});
trackEvent('enterprise-contact-form-submit');
submitting = false;
if (response.status >= 400) {
error = response.status >= 500 ? 'Server Error.' : 'Error submitting form.';
@@ -68,7 +71,7 @@
<title>{title}</title>
<meta property="og:title" content={title} />
<meta name="twitter:title" content={title} />
<!-- Desscription -->
<!-- Description -->
<meta name="description" content={description} />
<meta property="og:description" content={description} />
<meta name="twitter:description" content={description} />

View File

@@ -9,6 +9,7 @@
import BG from './bg.png?enhanced';
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
import { Button } from '$lib/components/ui';
import { trackEvent } from '$lib/actions/analytics';
const title = 'Pricing' + TITLE_SUFFIX;
const description = 'Explore our straightforward pricing plans that scale with your project.';
@@ -97,8 +98,9 @@
</p>
<Button
variant="secondary"
href={getAppwriteDashboardUrl('/register')}
class="is-full-width mt-8"
href={getAppwriteDashboardUrl('/register')}
event={{ name: 'pricing-cards-free-click' }}
>
<span class="text-sub-body font-medium"
>Start building</span
@@ -169,6 +171,7 @@
class="is-full-width mt-11"
target="_blank"
rel="noopener noreferrer"
event={{ name: 'pricing-cards-pro-click' }}
>
<span class="text-sub-body font-medium"
>Start building</span
@@ -233,6 +236,7 @@
href={getAppwriteDashboardUrl(
'/console?type=create&plan=tier-2'
)}
event={{ name: 'pricing-cards-scale-click' }}
class="is-full-width mt-10"
target="_blank"
rel="noopener noreferrer"
@@ -288,6 +292,7 @@
href="/contact-us/enterprise"
class="is-full-width mt-10"
rel="noopener noreferrer"
event={{ name: 'pricing-cards-enterprise-click' }}
>
<!-- <span class="web-sub-body-500">Start trial</span> -->
<span class="web-sub-body-500">Contact us</span>
@@ -324,7 +329,11 @@
Large scale projects seeking greater performance, collaboration and
security.
</p>
<Button variant="secondary" href="/contact-us" class="mt-8"
<Button
class="mt-8"
variant="secondary"
href="/contact-us"
event={{ name: 'pricing-cards-alternate-enterprise-click' }}
>Contact us</Button
>
</div>
@@ -348,6 +357,7 @@
</section>
</div>
</div>
<ComparePlans />
<div class="dark relative overflow-hidden pt-10">

View File

@@ -606,8 +606,9 @@
<h4 class="text-sub-body text-primary font-medium">Free</h4>
<Button
variant="secondary"
href={getAppwriteDashboardUrl('/register')}
class="!w-full"
href={getAppwriteDashboardUrl('/register')}
event={{ name: 'pricing-compare-free-click' }}
>
<span class="text-sub-body font-medium">Start building</span>
</Button>
@@ -622,6 +623,7 @@
'/console?type=create&plan=tier-1'
)}
target="_blank"
event={{ name: 'pricing-compare-pro-click' }}
rel="noopener noreferrer"
>
<span class="text-sub-body font-medium">Start building</span>
@@ -637,6 +639,7 @@
href={getAppwriteDashboardUrl(
'/console?type=create&plan=tier-2'
)}
event={{ name: 'pricing-compare-scale-click' }}
target="_blank"
rel="noopener noreferrer"
>
@@ -651,6 +654,7 @@
variant="secondary"
class="!w-full"
href="/contact-us/enterprise"
event={{ name: 'pricing-compare-enterprise-click' }}
>
<span class="text-sub-body font-medium">Contact</span>
</Button>

View File

@@ -159,9 +159,8 @@ async function getLoggedInUser(request) {
<li>
<a
href={platform.href}
onclick={() => trackEvent(`auth-docs-ssr-${platform.name}-click`)}
class="platform flex size-14 items-center justify-center rounded-lg bg-white p-2"
on:click={() =>
trackEvent({ plausible: { name: `${platform.name} clicked` } })}
>
<img
src={platform.image}

View File

@@ -61,10 +61,7 @@
})
});
trackEvent({
plausible: { name: 'startups-form_submit' },
posthog: { name: 'startups-form_submit' }
});
trackEvent('startups-form-submit');
submitting = false;