mirror of
https://github.com/LukeHagar/website.git
synced 2025-12-06 04:22:07 +00:00
update: handle events.
This commit is contained in:
@@ -1,12 +1,11 @@
|
|||||||
import { Analytics, type AnalyticsPlugin } from 'analytics';
|
import { page } from '$app/state';
|
||||||
import Plausible from 'plausible-tracker';
|
|
||||||
import posthogEvent from 'posthog-js';
|
|
||||||
import { get } from 'svelte/store';
|
|
||||||
import { page } from '$app/stores';
|
|
||||||
|
|
||||||
import { ENV } from '$lib/system';
|
import { ENV } from '$lib/system';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
|
|
||||||
|
import posthogEvent from 'posthog-js';
|
||||||
|
import Plausible from 'plausible-tracker';
|
||||||
|
import { Analytics, type AnalyticsPlugin } from 'analytics';
|
||||||
|
|
||||||
type Payload = {
|
type Payload = {
|
||||||
payload: {
|
payload: {
|
||||||
event: string;
|
event: string;
|
||||||
@@ -55,30 +54,20 @@ const analytics = Analytics({
|
|||||||
plugins: [plausible('appwrite.io')]
|
plugins: [plausible('appwrite.io')]
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TrackEventArgs = {
|
export type TrackEventArgs = { name: string; data?: object };
|
||||||
plausible?: { name: string; data?: object };
|
|
||||||
posthog?: { name: string };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const trackEvent = async (platforms: TrackEventArgs) => {
|
export const trackEvent = (eventArgs?: string | TrackEventArgs): void => {
|
||||||
if (!isTrackingAllowed()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentPage = get(page);
|
posthogEvent.capture(name, data);
|
||||||
const path = currentPage.route.id ?? '';
|
analytics.track(name, data).then();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isTrackingAllowed = () => !ENV.TEST;
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { trackEvent } from '$lib/actions/analytics';
|
|
||||||
import { createDialog, melt } from '@melt-ui/svelte';
|
|
||||||
import { fade, scale } from 'svelte/transition';
|
import { fade, scale } from 'svelte/transition';
|
||||||
import { Button, Icon } from '$lib/components/ui';
|
import { Button, Icon } from '$lib/components/ui';
|
||||||
|
import { createDialog, melt } from '@melt-ui/svelte';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
elements: { portalled, trigger, content, overlay },
|
elements: { portalled, trigger, content, overlay },
|
||||||
@@ -13,14 +12,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
class="cursor-pointer shadow-[0_2px_40px_rgba(0,0,0,0.5)] transition-opacity hover:opacity-90 active:scale-95"
|
|
||||||
action={trigger}
|
action={trigger}
|
||||||
onclick={() => {
|
event={'intro-video-btn_hero_click'}
|
||||||
trackEvent({
|
class="cursor-pointer shadow-[0_2px_40px_rgba(0,0,0,0.5)] transition-opacity hover:opacity-90 active:scale-95"
|
||||||
plausible: { name: 'Appwrite in 100 seconds' },
|
|
||||||
posthog: { name: 'intro-video-btn_hero_click' }
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Appwrite in 100 seconds
|
Appwrite in 100 seconds
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createAccordion, melt } from '@melt-ui/svelte';
|
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
|
import { createAccordion, melt } from '@melt-ui/svelte';
|
||||||
|
|
||||||
export let noBorder = false;
|
export let noBorder = false;
|
||||||
|
|
||||||
@@ -111,7 +112,16 @@
|
|||||||
<ul class="web-footer-nav-secondary-list text-sub-body">
|
<ul class="web-footer-nav-secondary-list text-sub-body">
|
||||||
{#each items as { href, label, target, rel }}
|
{#each items as { href, label, target, rel }}
|
||||||
<li>
|
<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>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,31 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { classNames } from '$lib/utils/classnames';
|
|
||||||
import { trackEvent } from '$lib/actions/analytics';
|
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
|
|
||||||
import { Button } from '$lib/components/ui';
|
import { Button } from '$lib/components/ui';
|
||||||
|
import { classNames } from '$lib/utils/classnames';
|
||||||
|
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
class?: string;
|
class?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { class: className }: Props = $props();
|
const { class: className }: Props = $props();
|
||||||
|
|
||||||
const isLoggedIn = browser && 'loggedIn' in document.body.dataset;
|
const isLoggedIn = browser && 'loggedIn' in document.body.dataset;
|
||||||
|
|
||||||
function getTrackingEventName() {
|
|
||||||
return browser ? (isLoggedIn ? 'Go to console' : 'Start building') : 'Start building';
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
class={classNames('web-u-inline-width-100-percent-mobile', className)}
|
|
||||||
href={getAppwriteDashboardUrl()}
|
href={getAppwriteDashboardUrl()}
|
||||||
onclick={() =>
|
event={{ name: 'get-started-btn-nav-click' }}
|
||||||
trackEvent({
|
class={classNames('web-u-inline-width-100-percent-mobile', className)}
|
||||||
plausible: { name: `${getTrackingEventName()} in header` },
|
|
||||||
...(isLoggedIn ? {} : { posthog: { name: 'get-started-btn_nav_click' } })
|
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
<span class="hidden group-[&[data-logged-in]]/body:block" aria-hidden={!isLoggedIn}
|
<span class="hidden group-[&[data-logged-in]]/body:block" aria-hidden={!isLoggedIn}
|
||||||
>Go to Console</span
|
>Go to Console</span
|
||||||
|
|||||||
@@ -41,12 +41,7 @@
|
|||||||
href={link.href}
|
href={link.href}
|
||||||
data-initialized={initialized ? '' : undefined}
|
data-initialized={initialized ? '' : undefined}
|
||||||
data-badge={link.showBadge ? '' : undefined}
|
data-badge={link.showBadge ? '' : undefined}
|
||||||
on:click={() => {
|
onclick={() => trackEvent(`main-nav-${link.label.toLowerCase()}-nav-click`)}
|
||||||
trackEvent({
|
|
||||||
plausible: { name: `${link.label} in header` },
|
|
||||||
posthog: { name: `${link.label.toLowerCase()}_nav_click` }
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>{link.label}
|
>{link.label}
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { trackEvent } from '$lib/actions/analytics';
|
|
||||||
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
|
|
||||||
import { Button, type Variant } from '$lib/components/ui';
|
import { Button, type Variant } from '$lib/components/ui';
|
||||||
|
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
|
||||||
|
|
||||||
const plans: Array<{
|
const plans: Array<{
|
||||||
name: string;
|
name: string;
|
||||||
@@ -21,7 +20,7 @@
|
|||||||
buttonText: 'Get started',
|
buttonText: 'Get started',
|
||||||
buttonLink: getAppwriteDashboardUrl('/register'),
|
buttonLink: getAppwriteDashboardUrl('/register'),
|
||||||
buttonVariant: 'secondary',
|
buttonVariant: 'secondary',
|
||||||
eventName: 'Get started Free plan'
|
eventName: 'footer-plans-free-click'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Pro',
|
name: 'Pro',
|
||||||
@@ -33,7 +32,7 @@
|
|||||||
buttonText: 'Start building',
|
buttonText: 'Start building',
|
||||||
buttonLink: getAppwriteDashboardUrl('/console?type=create&plan=tier-1'),
|
buttonLink: getAppwriteDashboardUrl('/console?type=create&plan=tier-1'),
|
||||||
buttonVariant: 'primary',
|
buttonVariant: 'primary',
|
||||||
eventName: 'Get started Pro plan'
|
eventName: 'footer-plans-pro-click'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Scale',
|
name: 'Scale',
|
||||||
@@ -44,7 +43,7 @@
|
|||||||
buttonText: 'Start building',
|
buttonText: 'Start building',
|
||||||
buttonLink: getAppwriteDashboardUrl('/console?type=create&plan=tier-2'),
|
buttonLink: getAppwriteDashboardUrl('/console?type=create&plan=tier-2'),
|
||||||
buttonVariant: 'secondary',
|
buttonVariant: 'secondary',
|
||||||
eventName: 'Get started Scale plan'
|
eventName: 'footer-plans-scale-click'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Enterprise',
|
name: 'Enterprise',
|
||||||
@@ -53,7 +52,7 @@
|
|||||||
buttonText: 'Contact us',
|
buttonText: 'Contact us',
|
||||||
buttonLink: '/contact-us/enterprise',
|
buttonLink: '/contact-us/enterprise',
|
||||||
buttonVariant: 'secondary',
|
buttonVariant: 'secondary',
|
||||||
eventName: 'Get started Enterprise plan'
|
eventName: 'footer-plans-enterprise-click'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
@@ -73,9 +72,9 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<Button
|
<Button
|
||||||
variant="transparent"
|
variant="transparent"
|
||||||
href={getAppwriteDashboardUrl()}
|
|
||||||
class="self-center"
|
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>
|
<span class="text">Get started</span>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -117,15 +116,9 @@
|
|||||||
{plan.description}
|
{plan.description}
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
|
event={plan.eventName}
|
||||||
variant={plan.buttonVariant}
|
variant={plan.buttonVariant}
|
||||||
href={plan.buttonLink}
|
|
||||||
class="w-full! flex-3 self-end md:w-fit"
|
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
|
<span class="text" style:padding-inline="0.5rem">{plan.buttonText}</span
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { classNames } from '$lib/utils/classnames';
|
|
||||||
import { melt, createCollapsible } from '@melt-ui/svelte';
|
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { products, sublinks } from './ProductsSubmenu.svelte';
|
import { classNames } from '$lib/utils/classnames';
|
||||||
import { trackEvent } from '$lib/actions/analytics';
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
|
import { melt, createCollapsible } from '@melt-ui/svelte';
|
||||||
|
import { products, sublinks } from './ProductsSubmenu.svelte';
|
||||||
|
|
||||||
export let label: string;
|
export let label: string;
|
||||||
|
|
||||||
@@ -34,13 +34,11 @@
|
|||||||
{#each products as product}
|
{#each products as product}
|
||||||
<a
|
<a
|
||||||
href={product.href}
|
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"
|
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
|
<div
|
||||||
class="flex size-12 shrink-0 items-center justify-center rounded-lg border border-white/12 bg-white/6"
|
class="flex size-12 shrink-0 items-center justify-center rounded-lg border border-white/12 bg-white/6"
|
||||||
|
|||||||
@@ -64,7 +64,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { dev } from '$app/environment';
|
|
||||||
import { trackEvent } from '$lib/actions/analytics';
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
import { classNames } from '$lib/utils/classnames';
|
import { classNames } from '$lib/utils/classnames';
|
||||||
import { createDropdownMenu, melt } from '@melt-ui/svelte';
|
import { createDropdownMenu, melt } from '@melt-ui/svelte';
|
||||||
@@ -117,12 +116,8 @@
|
|||||||
<a
|
<a
|
||||||
href={product.href}
|
href={product.href}
|
||||||
use:melt={$item}
|
use:melt={$item}
|
||||||
on:click={() =>
|
onclick={() =>
|
||||||
trackEvent({
|
trackEvent(`products-submenu-${product.name.toLowerCase()}-click`)}
|
||||||
plausible: {
|
|
||||||
name: `${product.name} in products submenu`
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
class="group flex gap-3 rounded-xl p-1 text-white transition-colors outline-none focus:bg-white/8"
|
class="group flex gap-3 rounded-xl p-1 text-white transition-colors outline-none focus:bg-white/8"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -75,7 +75,10 @@
|
|||||||
<a
|
<a
|
||||||
href={platform.href}
|
href={platform.href}
|
||||||
class="web-icon-button web-box-icon has-border-gradient"
|
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
|
<img
|
||||||
src={platform.image}
|
src={platform.image}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
|
import { type VariantProps, cva } from 'cva';
|
||||||
|
|
||||||
// TODO: replace _button.scss with Tailwind classes for long-term maintainability
|
// TODO: replace _button.scss with Tailwind classes for long-term maintainability
|
||||||
const button = cva(['web-button'], {
|
const button = cva(['web-button'], {
|
||||||
variants: {
|
variants: {
|
||||||
@@ -17,12 +19,12 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { classNames } from '$lib/utils/classnames';
|
import { type VariantProps } from 'cva';
|
||||||
import { type VariantProps, cva } from 'cva';
|
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import type { Action } from 'svelte/action';
|
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 { trackEvent, type TrackEventArgs } from '$lib/actions/analytics';
|
||||||
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
type ButtonOrAnchorProps =
|
type ButtonOrAnchorProps =
|
||||||
| (HTMLButtonAttributes & { href?: undefined })
|
| (HTMLButtonAttributes & { href?: undefined })
|
||||||
@@ -31,7 +33,7 @@
|
|||||||
type Props = {
|
type Props = {
|
||||||
action?: Action;
|
action?: Action;
|
||||||
children: Snippet;
|
children: Snippet;
|
||||||
events?: TrackEventArgs;
|
event?: string | TrackEventArgs;
|
||||||
} & VariantProps<typeof button> &
|
} & VariantProps<typeof button> &
|
||||||
ButtonOrAnchorProps;
|
ButtonOrAnchorProps;
|
||||||
|
|
||||||
@@ -41,7 +43,7 @@
|
|||||||
action = () => {},
|
action = () => {},
|
||||||
children,
|
children,
|
||||||
class: classes,
|
class: classes,
|
||||||
events,
|
event,
|
||||||
...rest
|
...rest
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
@@ -49,11 +51,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if href}
|
{#if href}
|
||||||
<a use:action {href} class={buttonClasses} {...rest as HTMLAnchorAttributes}>
|
<a use:action {href} class={buttonClasses} onclick={() => event && trackEvent(event)} {...rest}>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
</a>
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
<button use:action class={buttonClasses} {...rest as HTMLButtonAttributes}>
|
<button use:action class={buttonClasses} onclick={() => event && trackEvent(event)} {...rest}>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -227,11 +227,7 @@
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="web-u-inline-width-100-percent-mobile"
|
class="web-u-inline-width-100-percent-mobile"
|
||||||
onclick={() =>
|
event={{ name: 'github-stars-nav-click' }}
|
||||||
trackEvent({
|
|
||||||
plausible: { name: 'Star on GitHub in header' },
|
|
||||||
posthog: { name: 'github-stars_nav_click' }
|
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
<Icon name="star" aria-hidden="true" />
|
<Icon name="star" aria-hidden="true" />
|
||||||
<span class="text">Star on GitHub</span>
|
<span class="text">Star on GitHub</span>
|
||||||
|
|||||||
@@ -127,10 +127,7 @@
|
|||||||
|
|
||||||
const eventName = `${pageName}_scroll-depth_${threshold * 100}prct_scroll`;
|
const eventName = `${pageName}_scroll-depth_${threshold * 100}prct_scroll`;
|
||||||
tracked.add(threshold);
|
tracked.add(threshold);
|
||||||
trackEvent({
|
trackEvent(eventName);
|
||||||
plausible: { name: eventName },
|
|
||||||
posthog: { name: eventName }
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@
|
|||||||
<a
|
<a
|
||||||
href="/blog/post/init-may-2025"
|
href="/blog/post/init-may-2025"
|
||||||
class="web-hero-banner-button mb-4"
|
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="web-icon-star shrink-0" aria-hidden="true"></span>
|
||||||
<span class="text-caption shrink-0 font-medium">New</span>
|
<span class="text-caption shrink-0 font-medium">New</span>
|
||||||
@@ -162,11 +162,7 @@
|
|||||||
<Button
|
<Button
|
||||||
href={getAppwriteDashboardUrl()}
|
href={getAppwriteDashboardUrl()}
|
||||||
class="w-full lg:w-fit"
|
class="w-full lg:w-fit"
|
||||||
onclick={() =>
|
onclick={() => trackEvent('get-started-btn-hero-click')}
|
||||||
trackEvent({
|
|
||||||
plausible: { name: 'Get started in hero' },
|
|
||||||
posthog: { name: 'get-started-btn_hero_click' }
|
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
Start building
|
Start building
|
||||||
</Button>
|
</Button>
|
||||||
@@ -487,7 +483,7 @@
|
|||||||
<Button
|
<Button
|
||||||
href="/docs/sdks"
|
href="/docs/sdks"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onclick={() => trackEvent({ plausible: { name: 'Explore all SDKs' } })}
|
onclick={() => trackEvent('main-explore-all-sdks-click')}
|
||||||
>Explore all SDKs</Button
|
>Explore all SDKs</Button
|
||||||
>
|
>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
|
|
||||||
import { SOCIAL_STATS } from '$lib/constants';
|
import { SOCIAL_STATS } from '$lib/constants';
|
||||||
import { Button, Icon } from '$lib/components/ui';
|
import { Button, Icon } from '$lib/components/ui';
|
||||||
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
import InlineTag from '$lib/components/ui/inline-tag.svelte';
|
import InlineTag from '$lib/components/ui/inline-tag.svelte';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
@@ -113,6 +114,9 @@
|
|||||||
submitting = true;
|
submitting = true;
|
||||||
error = undefined;
|
error = undefined;
|
||||||
const response = await newsletter(name, email);
|
const response = await newsletter(name, email);
|
||||||
|
|
||||||
|
trackEvent('community-insights-subscribe-submit');
|
||||||
|
|
||||||
submitting = false;
|
submitting = false;
|
||||||
if (response.status >= 400) {
|
if (response.status >= 400) {
|
||||||
error = response.status >= 500 ? 'Server Error.' : 'Error submitting form.';
|
error = response.status >= 500 ? 'Server Error.' : 'Error submitting form.';
|
||||||
@@ -464,6 +468,7 @@
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="mt-4 self-center"
|
class="mt-4 self-center"
|
||||||
|
event="community-built-with-appwrite-click"
|
||||||
>
|
>
|
||||||
<span>View all projects</span>
|
<span>View all projects</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
{description}
|
{description}
|
||||||
</p>
|
</p>
|
||||||
<div class="mbs-auto flex flex-wrap gap-2 pt-4">
|
<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>
|
<span>{buttonText}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
|
|
||||||
type $$Props = ProjectCardProps;
|
type $$Props = ProjectCardProps;
|
||||||
|
|
||||||
export let title: $$Props['title'];
|
export let title: $$Props['title'];
|
||||||
@@ -25,6 +27,7 @@
|
|||||||
{href}
|
{href}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
onclick={() => trackEvent(`community-project-${title.toLowerCase().replace(' ', '_')}-click`)}
|
||||||
>
|
>
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<h3 class="text-body text-primary font-medium">{title}</h3>
|
<h3 class="text-body text-primary font-medium">{title}</h3>
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
Designed for and by developers
|
Designed for and by developers
|
||||||
</h2>
|
</h2>
|
||||||
<Button
|
<Button
|
||||||
|
event="company-careers-click"
|
||||||
href="https://appwrite.careers"
|
href="https://appwrite.careers"
|
||||||
class="web-u-inline-width-100-percent-mobile-break1 self-start"
|
class="web-u-inline-width-100-percent-mobile-break1 self-start"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import { PUBLIC_GROWTH_ENDPOINT } from '$env/static/public';
|
import { PUBLIC_GROWTH_ENDPOINT } from '$env/static/public';
|
||||||
import { getReferrerAndUtmSource } from '$lib/utils/utm';
|
import { getReferrerAndUtmSource } from '$lib/utils/utm';
|
||||||
import { Button } from '$lib/components/ui';
|
import { Button } from '$lib/components/ui';
|
||||||
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
|
|
||||||
let email = '';
|
let email = '';
|
||||||
let firstName = '';
|
let firstName = '';
|
||||||
@@ -36,6 +37,8 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
trackEvent('contact-form-submit');
|
||||||
|
|
||||||
submitting = false;
|
submitting = false;
|
||||||
|
|
||||||
if (response.status >= 400) {
|
if (response.status >= 400) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
import LogoList from '$lib/components/LogoList.svelte';
|
import LogoList from '$lib/components/LogoList.svelte';
|
||||||
import Scale from '$routes/(experiments)/new-homepage/(components)/scale.svelte';
|
import Scale from '$routes/(experiments)/new-homepage/(components)/scale.svelte';
|
||||||
import { Button } from '$lib/components/ui';
|
import { Button } from '$lib/components/ui';
|
||||||
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
|
|
||||||
let email = '';
|
let email = '';
|
||||||
let firstName = '';
|
let firstName = '';
|
||||||
@@ -48,6 +49,8 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
trackEvent('enterprise-contact-form-submit');
|
||||||
|
|
||||||
submitting = false;
|
submitting = false;
|
||||||
if (response.status >= 400) {
|
if (response.status >= 400) {
|
||||||
error = response.status >= 500 ? 'Server Error.' : 'Error submitting form.';
|
error = response.status >= 500 ? 'Server Error.' : 'Error submitting form.';
|
||||||
@@ -68,7 +71,7 @@
|
|||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<meta property="og:title" content={title} />
|
<meta property="og:title" content={title} />
|
||||||
<meta name="twitter:title" content={title} />
|
<meta name="twitter:title" content={title} />
|
||||||
<!-- Desscription -->
|
<!-- Description -->
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
<meta property="og:description" content={description} />
|
<meta property="og:description" content={description} />
|
||||||
<meta name="twitter:description" content={description} />
|
<meta name="twitter:description" content={description} />
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
import BG from './bg.png?enhanced';
|
import BG from './bg.png?enhanced';
|
||||||
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
|
import { getAppwriteDashboardUrl } from '$lib/utils/dashboard';
|
||||||
import { Button } from '$lib/components/ui';
|
import { Button } from '$lib/components/ui';
|
||||||
|
import { trackEvent } from '$lib/actions/analytics';
|
||||||
|
|
||||||
const title = 'Pricing' + TITLE_SUFFIX;
|
const title = 'Pricing' + TITLE_SUFFIX;
|
||||||
const description = 'Explore our straightforward pricing plans that scale with your project.';
|
const description = 'Explore our straightforward pricing plans that scale with your project.';
|
||||||
@@ -97,8 +98,9 @@
|
|||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
href={getAppwriteDashboardUrl('/register')}
|
|
||||||
class="is-full-width mt-8"
|
class="is-full-width mt-8"
|
||||||
|
href={getAppwriteDashboardUrl('/register')}
|
||||||
|
event={{ name: 'pricing-cards-free-click' }}
|
||||||
>
|
>
|
||||||
<span class="text-sub-body font-medium"
|
<span class="text-sub-body font-medium"
|
||||||
>Start building</span
|
>Start building</span
|
||||||
@@ -169,6 +171,7 @@
|
|||||||
class="is-full-width mt-11"
|
class="is-full-width mt-11"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
event={{ name: 'pricing-cards-pro-click' }}
|
||||||
>
|
>
|
||||||
<span class="text-sub-body font-medium"
|
<span class="text-sub-body font-medium"
|
||||||
>Start building</span
|
>Start building</span
|
||||||
@@ -233,6 +236,7 @@
|
|||||||
href={getAppwriteDashboardUrl(
|
href={getAppwriteDashboardUrl(
|
||||||
'/console?type=create&plan=tier-2'
|
'/console?type=create&plan=tier-2'
|
||||||
)}
|
)}
|
||||||
|
event={{ name: 'pricing-cards-scale-click' }}
|
||||||
class="is-full-width mt-10"
|
class="is-full-width mt-10"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
@@ -288,6 +292,7 @@
|
|||||||
href="/contact-us/enterprise"
|
href="/contact-us/enterprise"
|
||||||
class="is-full-width mt-10"
|
class="is-full-width mt-10"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
event={{ name: 'pricing-cards-enterprise-click' }}
|
||||||
>
|
>
|
||||||
<!-- <span class="web-sub-body-500">Start trial</span> -->
|
<!-- <span class="web-sub-body-500">Start trial</span> -->
|
||||||
<span class="web-sub-body-500">Contact us</span>
|
<span class="web-sub-body-500">Contact us</span>
|
||||||
@@ -324,7 +329,11 @@
|
|||||||
Large scale projects seeking greater performance, collaboration and
|
Large scale projects seeking greater performance, collaboration and
|
||||||
security.
|
security.
|
||||||
</p>
|
</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
|
>Contact us</Button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -348,6 +357,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ComparePlans />
|
<ComparePlans />
|
||||||
|
|
||||||
<div class="dark relative overflow-hidden pt-10">
|
<div class="dark relative overflow-hidden pt-10">
|
||||||
|
|||||||
@@ -606,8 +606,9 @@
|
|||||||
<h4 class="text-sub-body text-primary font-medium">Free</h4>
|
<h4 class="text-sub-body text-primary font-medium">Free</h4>
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
href={getAppwriteDashboardUrl('/register')}
|
|
||||||
class="!w-full"
|
class="!w-full"
|
||||||
|
href={getAppwriteDashboardUrl('/register')}
|
||||||
|
event={{ name: 'pricing-compare-free-click' }}
|
||||||
>
|
>
|
||||||
<span class="text-sub-body font-medium">Start building</span>
|
<span class="text-sub-body font-medium">Start building</span>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -622,6 +623,7 @@
|
|||||||
'/console?type=create&plan=tier-1'
|
'/console?type=create&plan=tier-1'
|
||||||
)}
|
)}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
event={{ name: 'pricing-compare-pro-click' }}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
<span class="text-sub-body font-medium">Start building</span>
|
<span class="text-sub-body font-medium">Start building</span>
|
||||||
@@ -637,6 +639,7 @@
|
|||||||
href={getAppwriteDashboardUrl(
|
href={getAppwriteDashboardUrl(
|
||||||
'/console?type=create&plan=tier-2'
|
'/console?type=create&plan=tier-2'
|
||||||
)}
|
)}
|
||||||
|
event={{ name: 'pricing-compare-scale-click' }}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
@@ -651,6 +654,7 @@
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
class="!w-full"
|
class="!w-full"
|
||||||
href="/contact-us/enterprise"
|
href="/contact-us/enterprise"
|
||||||
|
event={{ name: 'pricing-compare-enterprise-click' }}
|
||||||
>
|
>
|
||||||
<span class="text-sub-body font-medium">Contact</span>
|
<span class="text-sub-body font-medium">Contact</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -159,9 +159,8 @@ async function getLoggedInUser(request) {
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href={platform.href}
|
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"
|
class="platform flex size-14 items-center justify-center rounded-lg bg-white p-2"
|
||||||
on:click={() =>
|
|
||||||
trackEvent({ plausible: { name: `${platform.name} clicked` } })}
|
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={platform.image}
|
src={platform.image}
|
||||||
|
|||||||
@@ -61,10 +61,7 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
trackEvent({
|
trackEvent('startups-form-submit');
|
||||||
plausible: { name: 'startups-form_submit' },
|
|
||||||
posthog: { name: 'startups-form_submit' }
|
|
||||||
});
|
|
||||||
|
|
||||||
submitting = false;
|
submitting = false;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user