From a2f125f1e91606d65918a1fdbaeb7183e4b289f0 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Mon, 14 Nov 2022 21:35:53 +0100 Subject: [PATCH] docs: add vercel analytics --- docs/package.json | 3 +- docs/src/.vitepress/config.ts | 3 ++ .../plugins/vercel-web-vitals-api.ts | 53 +++++++++++++++++++ docs/src/.vitepress/theme/index.ts | 2 + docs/src/custom.d.ts | 1 + pnpm-lock.yaml | 6 +++ 6 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 docs/src/.vitepress/plugins/vercel-web-vitals-api.ts create mode 100644 docs/src/custom.d.ts diff --git a/docs/package.json b/docs/package.json index 4f41c877..96ef41f6 100644 --- a/docs/package.json +++ b/docs/package.json @@ -21,7 +21,8 @@ "blobity": "^0.2.1", "canvas-confetti": "^1.6.0", "vite": "^2.9.15", - "vue": "^3.2.37" + "vue": "^3.2.37", + "web-vitals": "^3.0.4" }, "devDependencies": { "@iconify/json": "^2.1.95", diff --git a/docs/src/.vitepress/config.ts b/docs/src/.vitepress/config.ts index 2db45ba2..84024f52 100644 --- a/docs/src/.vitepress/config.ts +++ b/docs/src/.vitepress/config.ts @@ -70,6 +70,9 @@ export default defineConfigWithTheme({ optimizeDeps: { exclude: ['@animxyz/vue3'], }, + define: { + __ANALYTICS_ID__: process.env.VERCEL_ANALYTICS_ID, + }, plugins: [ copyVueFlowPlugin(), AutoImport({ diff --git a/docs/src/.vitepress/plugins/vercel-web-vitals-api.ts b/docs/src/.vitepress/plugins/vercel-web-vitals-api.ts new file mode 100644 index 00000000..f16b83a5 --- /dev/null +++ b/docs/src/.vitepress/plugins/vercel-web-vitals-api.ts @@ -0,0 +1,53 @@ +import { getCLS, getFCP, getFID, getLCP, getTTFB } from 'web-vitals' + +const vitalsUrl = 'https://vitals.vercel-analytics.com/v1/vitals' + +function getConnectionSpeed() { + const _navigator = navigator as Navigator & { connection?: { effectiveType: string } } + + return 'connection' in _navigator && _navigator.connection && 'effectiveType' in _navigator.connection + ? _navigator.connection.effectiveType + : '' +} + +function sendToAnalytics(metric, options) { + const body = { + dsn: options.analyticsId, + id: metric.id, + page: window.location.pathname, + href: window.location.href, + event_name: metric.name, + value: metric.value.toString(), + speed: getConnectionSpeed(), + } + + if (options.debug) { + console.log('[Analytics]', metric.name, JSON.stringify(body, null, 2)) + } + + const blob = new Blob([new URLSearchParams(body).toString()], { + // This content type is necessary for `sendBeacon` + type: 'application/x-www-form-urlencoded', + }) + if (navigator.sendBeacon) { + navigator.sendBeacon(vitalsUrl, blob) + } else + fetch(vitalsUrl, { + body: blob, + method: 'POST', + credentials: 'omit', + keepalive: true, + }) +} + +export function webVitals(options) { + try { + getFID((metric) => sendToAnalytics(metric, options)) + getTTFB((metric) => sendToAnalytics(metric, options)) + getLCP((metric) => sendToAnalytics(metric, options)) + getCLS((metric) => sendToAnalytics(metric, options)) + getFCP((metric) => sendToAnalytics(metric, options)) + } catch (err) { + console.error('[Analytics]', err) + } +} diff --git a/docs/src/.vitepress/theme/index.ts b/docs/src/.vitepress/theme/index.ts index 1d1bcad6..e95ba3a8 100644 --- a/docs/src/.vitepress/theme/index.ts +++ b/docs/src/.vitepress/theme/index.ts @@ -1,6 +1,7 @@ import type { Theme } from 'vitepress' import VueAnimXyz from '@animxyz/vue3' import DefaultTheme from 'vitepress/theme' +import { webVitals } from '../plugins/vercel-web-vitals-api' import Layout from './layouts/default.vue' import 'virtual:windi.css' import '@animxyz/core' @@ -13,6 +14,7 @@ const CustomTheme = { Layout, enhanceApp: ({ app }) => { app.use(VueAnimXyz) + webVitals({ analyticsId: '__ANALYTICS_ID__', debug: true }) }, } as Theme diff --git a/docs/src/custom.d.ts b/docs/src/custom.d.ts new file mode 100644 index 00000000..34b82b3b --- /dev/null +++ b/docs/src/custom.d.ts @@ -0,0 +1 @@ +declare const __ANALYTICS_ID__: string diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 909c0613..e11dafa2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,6 +55,7 @@ importers: vite-plugin-windicss: ^1.8.8 vitepress: ^1.0.0-alpha.4 vue: ^3.2.37 + web-vitals: ^3.0.4 windicss: ^3.5.6 dependencies: '@algolia/client-search': 4.14.2 @@ -68,6 +69,7 @@ importers: canvas-confetti: 1.6.0 vite: 2.9.15 vue: 3.2.37 + web-vitals: 3.0.4 devDependencies: '@iconify/json': 2.1.95 '@types/canvas-confetti': 1.4.3 @@ -10823,6 +10825,10 @@ packages: engines: {node: '>= 8'} dev: true + /web-vitals/3.0.4: + resolution: {integrity: sha512-Yau8qf1AJ/dm6MY180Bi0qpCIuWmAfKAnOqmxLecGfIHn0+ND3H4JOhXeY73Pyi9zjSF5J4SNUewHLNUzU7mmA==} + dev: false + /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true