From 1d73378e5fe7c2380c6533cfab27fcd62fedbbe3 Mon Sep 17 00:00:00 2001 From: taskylizard <75871323+taskylizard@users.noreply.github.com> Date: Fri, 16 Aug 2024 18:07:09 +0000 Subject: [PATCH] wip --- api/routes/outbound.post.ts | 18 ++++ .../.vitepress/theme/composables/plausible.ts | 92 +++++++++++++++++++ docs/.vitepress/theme/index.ts | 7 ++ package.json | 2 + pnpm-lock.yaml | 31 +++++++ 5 files changed, 150 insertions(+) create mode 100644 api/routes/outbound.post.ts create mode 100644 docs/.vitepress/theme/composables/plausible.ts diff --git a/api/routes/outbound.post.ts b/api/routes/outbound.post.ts new file mode 100644 index 000000000..221c17d52 --- /dev/null +++ b/api/routes/outbound.post.ts @@ -0,0 +1,18 @@ +export default defineEventHandler(async (event) => { + const env = useRuntimeConfig(event) + const data = await event.web.request.json() + + console.info(data) + const forwardHeaders = new Headers(data.headers) + forwardHeaders.delete('cookie') + + const upstreamResp = await fetch(`${env.ANALYTICS_DOMAIN}/api/event`, { + method: 'POST', + body: JSON.stringify(data), + headers: forwardHeaders + }) + + console.info(upstreamResp) + + return new Response(null, { status: upstreamResp.status }) +}) diff --git a/docs/.vitepress/theme/composables/plausible.ts b/docs/.vitepress/theme/composables/plausible.ts new file mode 100644 index 000000000..15244c8fc --- /dev/null +++ b/docs/.vitepress/theme/composables/plausible.ts @@ -0,0 +1,92 @@ +import { + createPlausibleTracker, + type Plausible, + type PlausibleOptions +} from '@barbapapazes/plausible-tracker' +import { + useAutoPageviews, + useAutoOutboundTracking +} from '@barbapapazes/plausible-tracker/extensions' + +import type { App } from 'vue' +import { inject } from 'vue' + +interface ScriptLoaderOption extends Partial { + 'data-domain': string +} + +function loadScript( + source: string, + options: ScriptLoaderOption = {} as ScriptLoaderOption +) { + return new Promise((resolve, reject) => { + const head = document.head || document.getElementsByTagName('head')[0] + const script = document.createElement('script') + const { + src, + type = 'text/javascript', + defer = false, + async = false, + ...restAttrs + } = options + script.type = type + script.defer = defer + script.async = async + script.src = src || source + script.setAttribute('data-domain', options['data-domain']) + + Object.keys(restAttrs).forEach((attr) => { + ; (script as any)[attr] = (restAttrs as any)[attr] + }) + + head.appendChild(script) + script.onload = resolve + script.onerror = reject + }) +} +export function createPlausible( + options: Partial & { domain: string; apiHost: string } +): { + install(app: App): void +} { + const plausible = { + install(app: App): void { + if ( + // only in production + process.env.NODE_ENV === 'production' && + // and we are ready + typeof window !== 'undefined' + ) { + const $plausible = createPlausibleTracker(options) + + const { install: _useAutoPageviews } = + // biome-ignore lint/correctness/useHookAtTopLevel: + useAutoPageviews($plausible) + const { install: _useAutoOutboundTracking } = + // biome-ignore lint/correctness/useHookAtTopLevel: + useAutoOutboundTracking($plausible) + + _useAutoPageviews() + _useAutoOutboundTracking() + + app.config.globalProperties.$plausible = $plausible + app.provide('$plausible', $plausible) + } + } + } + return plausible +} + +export function usePlausible() { + const plausible = inject('$plausible') as Plausible + + return { + ...plausible + } +} + +declare module '@vue/runtime-core' { + export interface ComponentCustomProperties { + $plausible: Plausible + } +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 00c6798b9..02f5d5f62 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -5,6 +5,7 @@ import Post from './PostLayout.vue' import { loadProgress } from './composables/nprogress' import './style.css' import 'uno.css' +import { createPlausible } from './composables/plausible' export default { extends: DefaultTheme, @@ -12,5 +13,11 @@ export default { enhanceApp({ router, app }) { app.component('Post', Post) loadProgress(router) + app.use( + createPlausible({ + apiHost: `https://${process.env.ANALYTICS_URL}`, + domain: 'https://web-24.fmhy.pages.dev' + }) + ) } } satisfies Theme diff --git a/package.json b/package.json index 87ea61383..c6deff893 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,11 @@ "postinstall": "nitropack prepare" }, "dependencies": { + "@barbapapazes/plausible-tracker": "^0.5.2", "@fmhy/colors": "^0.0.11", "@headlessui/vue": "^1.7.22", "@resvg/resvg-js": "^2.6.0", + "@vue/runtime-core": "^3.4.38", "consola": "^3.2.3", "feed": "^4.2.2", "itty-fetcher": "^0.9.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9944903b..a08f212da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@barbapapazes/plausible-tracker': + specifier: ^0.5.2 + version: 0.5.2 '@fmhy/colors': specifier: ^0.0.11 version: 0.0.11 @@ -17,6 +20,9 @@ importers: '@resvg/resvg-js': specifier: ^2.6.0 version: 2.6.2 + '@vue/runtime-core': + specifier: ^3.4.38 + version: 3.4.38 consola: specifier: ^3.2.3 version: 3.2.3 @@ -324,6 +330,9 @@ packages: resolution: {integrity: sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==} engines: {node: '>=6.9.0'} + '@barbapapazes/plausible-tracker@0.5.2': + resolution: {integrity: sha512-su3ut2STFDV+pVCRd0SbCYCA31YWqqEk0Z4/vDMeGvqLMw5hJaQt2mXxbbokIzXTnjODDTeCA/m+TjkHRTWBEg==} + '@biomejs/biome@1.8.3': resolution: {integrity: sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==} engines: {node: '>=14.21.3'} @@ -1481,9 +1490,15 @@ packages: '@vue/reactivity@3.4.33': resolution: {integrity: sha512-B24QIelahDbyHipBgbUItQblbd4w5HpG3KccL+YkGyo3maXyS253FzcTR3pSz739OTphmzlxP7JxEMWBpewilA==} + '@vue/reactivity@3.4.38': + resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==} + '@vue/runtime-core@3.4.33': resolution: {integrity: sha512-6wavthExzT4iAxpe8q37/rDmf44nyOJGISJPxCi9YsQO+8w9v0gLCFLfH5TzD1V1AYrTAdiF4Y1cgUmP68jP6w==} + '@vue/runtime-core@3.4.38': + resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==} + '@vue/runtime-dom@3.4.33': resolution: {integrity: sha512-iHsMCUSFJ+4z432Bn9kZzHX+zOXa6+iw36DaVRmKYZpPt9jW9riF32SxNwB124i61kp9+AZtheQ/mKoJLerAaQ==} @@ -1495,6 +1510,9 @@ packages: '@vue/shared@3.4.33': resolution: {integrity: sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==} + '@vue/shared@3.4.38': + resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} + '@vueuse/core@10.11.0': resolution: {integrity: sha512-x3sD4Mkm7PJ+pcq3HX8PLPBadXCAlSDR/waK87dz0gQE+qJnaaFhc/dZVfJz+IUYzTMVGum2QlR7ImiJQN4s6g==} @@ -3656,6 +3674,8 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@barbapapazes/plausible-tracker@0.5.2': {} + '@biomejs/biome@1.8.3': optionalDependencies: '@biomejs/cli-darwin-arm64': 1.8.3 @@ -4652,11 +4672,20 @@ snapshots: dependencies: '@vue/shared': 3.4.33 + '@vue/reactivity@3.4.38': + dependencies: + '@vue/shared': 3.4.38 + '@vue/runtime-core@3.4.33': dependencies: '@vue/reactivity': 3.4.33 '@vue/shared': 3.4.33 + '@vue/runtime-core@3.4.38': + dependencies: + '@vue/reactivity': 3.4.38 + '@vue/shared': 3.4.38 + '@vue/runtime-dom@3.4.33': dependencies: '@vue/reactivity': 3.4.33 @@ -4672,6 +4701,8 @@ snapshots: '@vue/shared@3.4.33': {} + '@vue/shared@3.4.38': {} + '@vueuse/core@10.11.0(vue@3.4.33)': dependencies: '@types/web-bluetooth': 0.0.20