Skip to content

Commit

Permalink
Turn analytics composable into a plugin (#3811)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
sarayourfriend and zackkrida authored Feb 28, 2024
1 parent d242940 commit db27e7e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 61 deletions.
1 change: 1 addition & 0 deletions frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
67 changes: 6 additions & 61 deletions frontend/src/composables/use-analytics.ts
Original file line number Diff line number Diff line change
@@ -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 = <T extends EventName>(
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 }
}
45 changes: 45 additions & 0 deletions frontend/src/plugins/analytics.ts
Original file line number Diff line number Diff line change
@@ -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 = <T extends EventName>(
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)

0 comments on commit db27e7e

Please sign in to comment.