Skip to content

Instantly share code, notes, and snippets.

@daliborgogic
Last active January 27, 2023 18:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save daliborgogic/912c1bad2dccd6523348c2d1d528c721 to your computer and use it in GitHub Desktop.
Save daliborgogic/912c1bad2dccd6523348c2d1d528c721 to your computer and use it in GitHub Desktop.
[POC] Sending Vite.js Core Web Vitals to Google Analytics
const transformer = options => ({
apply: 'post',
transform({ code, isBuild }) {
if (!isBuild) return code
return code.replace('</body>', `<script defer type="module">
const KEY = 'ga:user'
const UID = (localStorage[KEY] = localStorage[KEY] || Math.random() + '.' + Math.random())
const onError = err => console.error('[vite vitals] ', err)
const onDebug = (label, payload) => console.log(label, payload)
function sendToAnalytics (fullPath, metric) {
const { name, delta, id, entries } = metric
const opts = {
ec: '${options.eventCategory}',
ea: name,
el: id,
ev: parseInt(delta),
dp: fullPath,
ni: true
}
if (name === 'TTFB') opts.ev = parseInt(delta - entries[0].requestStart)
const args = { tid: '${options.trackingID}', cid: UID, ...opts }
const obj = { t: 'event', ...args, ...opts, z: Date.now() }
const blob = new Blob([new URLSearchParams(obj).toString()], {
type: 'application/x-www-form-urlencoded'
})
const url = 'https://www.google-analytics.com/collect?v=1'
const debug = ${options.debug}
if (debug) onDebug(name, JSON.stringify(obj, null, 2))
;(navigator.sendBeacon && navigator.sendBeacon(url, blob)) ||
fetch(url, {
body: blob,
method: 'POST',
credentials: 'omit',
keepalive: true
})
}
async function webVitals (fullPath) {
try {
const { getCLS, getFID, getLCP, getTTFB, getFCP } = await import('https://unpkg.com/web-vitals@0.2.4/dist/web-vitals.es5.min.js?module')
getFID(metric => sendToAnalytics(fullPath, metric))
getTTFB(metric => sendToAnalytics(fullPath, metric))
getLCP(metric => sendToAnalytics(fullPath, metric))
getCLS(metric => sendToAnalytics(fullPath, metric))
getFCP(metric => sendToAnalytics(fullPath, metric))
} catch (err) {
onError(err)
}
}
webVitals(window.location.pathname + window.location.search)
</script></body>`)
}
})
export function vitals (opts) {
return {
indexHtmlTransforms: [transformer(opts)]
}
}
import { vitals } from './plugins/vitals'
export default {
plugins:[vitals({
// Tracking ID (required) { string }
trackingID: 'UA-XXXXXXXX-X',
// Event Category (optional) { string }
eventCategory: 'Vite Vitals',
// Debug (optional) { boolean }
debug: false
})]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment