From db27e7edc03e160258c36606ffdbbe4cc102527c Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:31:47 +1100 Subject: [PATCH] Turn analytics composable into a plugin (#3811) * Turn analytics composable into a plugin This commit keeps the composable to reduce code churn and to prove that existing tests of the analytics work, proving the change works as expected * Add deprecation and explanation notice to composable Co-authored-by: Zack Krida <6351754+zackkrida@users.noreply.github.com> --------- Co-authored-by: Zack Krida <6351754+zackkrida@users.noreply.github.com> --- frontend/nuxt.config.ts | 1 + frontend/src/composables/use-analytics.ts | 67 ++--------------------- frontend/src/plugins/analytics.ts | 45 +++++++++++++++ 3 files changed, 52 insertions(+), 61 deletions(-) create mode 100644 frontend/src/plugins/analytics.ts diff --git a/frontend/nuxt.config.ts b/frontend/nuxt.config.ts index ab0da432094..92298bef1a7 100644 --- a/frontend/nuxt.config.ts +++ b/frontend/nuxt.config.ts @@ -146,6 +146,7 @@ const config: NuxtConfig = { "~/plugins/api-token.server.ts", "~/plugins/polyfills.client.ts", "~/plugins/sentry.ts", + "~/plugins/analytics.ts", ], css: ["~/assets/fonts.css", "~/styles/tailwind.css", "~/styles/accent.css"], head, diff --git a/frontend/src/composables/use-analytics.ts b/frontend/src/composables/use-analytics.ts index 69db7afe7fd..2ba72072093 100644 --- a/frontend/src/composables/use-analytics.ts +++ b/frontend/src/composables/use-analytics.ts @@ -1,68 +1,13 @@ -import { computed, onMounted } from "vue" import { useContext } from "@nuxtjs/composition-api" -import type { Events, EventName } from "~/types/analytics" -import { useUiStore } from "~/stores/ui" -import { useFeatureFlagStore } from "~/stores/feature-flag" - -import { log } from "~/utils/console" - /** - * The `ctx` parameter must be supplied if using this composable outside the - * bounds of the composition API. + * This wrapper around the plugin, retained to reduce code churn. + * @see Refer to frontend/src/plugins/analytics.ts for plugin implementation + * + * @deprecated For new code, use `$sendCustomEvent` from Nuxt context */ export const useAnalytics = () => { - const { $plausible } = useContext() - const uiStore = useUiStore() - const featureFlagStore = useFeatureFlagStore() - - onMounted(() => { - featureFlagStore.syncAnalyticsWithLocalStorage() - }) - - /** - * the Plausible props that work identically on the server-side and the - * client-side; This excludes props that need `window`. - */ - const isomorphicProps = computed(() => ({ - breakpoint: uiStore.breakpoint, - })) - - /** - * the Plausible props that work only on the client-side; This only includes - * props that need `window`. - */ - const windowProps = computed(() => - window - ? { - width: window.innerWidth, - height: window.innerHeight, - } - : {} - ) - - /** - * Send a custom event to Plausible. Mandatory props are automatically merged - * with the event-specific props. - * - * @param name - the name of the event being recorded - * @param payload - the additional information to record about the event - */ - const sendCustomEvent = ( - name: T, - payload: Events[T] - ) => { - log(`Analytics event: ${name}`, payload) - $plausible.trackEvent(name, { - props: { - ...isomorphicProps.value, - ...windowProps.value, - ...payload, - }, - }) - } + const { $sendCustomEvent } = useContext() - return { - sendCustomEvent, - } + return { sendCustomEvent: $sendCustomEvent } } diff --git a/frontend/src/plugins/analytics.ts b/frontend/src/plugins/analytics.ts new file mode 100644 index 00000000000..bd509eb3bc6 --- /dev/null +++ b/frontend/src/plugins/analytics.ts @@ -0,0 +1,45 @@ +import type { Events, EventName } from "~/types/analytics" +import { useUiStore } from "~/stores/ui" +import { useFeatureFlagStore } from "~/stores/feature-flag" + +import { log } from "~/utils/console" + +import type { Plugin } from "@nuxt/types" + +type SendCustomEvent = ( + name: T, + payload: Events[T] +) => void + +declare module "@nuxt/types" { + interface Context { + $sendCustomEvent: SendCustomEvent + } +} + +export default (function analyticsPlugin(context, inject) { + if (process.server) { + // Inject a noop on the server, as vue-plausible does not support SSR + inject("sendCustomEvent", (() => {}) as SendCustomEvent) + return + } + + const uiStore = useUiStore(context.$pinia) + const featureFlagStore = useFeatureFlagStore(context.$pinia) + + featureFlagStore.syncAnalyticsWithLocalStorage() + + const sendCustomEvent: SendCustomEvent = (name, payload) => { + log(`Analytics event: ${name}`, payload) + context.$plausible.trackEvent(name, { + props: { + breakpoint: uiStore.breakpoint, + width: window.innerWidth, + height: window.innerHeight, + ...payload, + }, + }) + } + + inject("sendCustomEvent", sendCustomEvent) +} satisfies Plugin)