Destiner / astro-analytics

Astro components for site analytics

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Please add Vercel Analytics

louiss0 opened this issue · comments

I want to use vercel analytics in astro but I'd have to create a library for that I see that you have a nice set of Components that Allow the user to integrate analytics from other sites. I'm going to just give you the code for how to integrate Vercel Analytics if you want more info look into the docs.

You need to install web-vitals in order to use the code below.

Code needed for Web Analytics

import { Metric, onCLS, onFCP, onFID, onLCP, onTTFB } from 'web-vitals';

const vitalsUrl = 'https://vitals.vercel-analytics.com/v1/vitals';

function getConnectionSpeed() {
    return 'connection' in navigator
        && navigator['connection']
        && typeof navigator['connection'] === "object"
        && 'effectiveType' in navigator['connection']
        ? navigator['connection']['effectiveType']
        : '';
}

type Options = { params: { [s: string]: any; } | ArrayLike<any>; path: string; analyticsId: string; debug: boolean; }


function sendToAnalytics(metric:Metric, options:Options) {
  const page = Object.entries(options.params).reduce(
    (acc, [key, value]) => acc.replace(value, `[${key}]`),
    options.path,
  );

  const body = {
    dsn: options.analyticsId, // qPgJqYH9LQX5o31Ormk8iWhCxZO
    id: metric.id, // v2-1653884975443-1839479248192
    page, // /blog/[slug]
    href: location.href, // https://my-app.vercel.app/blog/my-test
    event_name: metric.name, // TTFB
    value: metric.value.toString(), // 60.20000000298023
    speed: getConnectionSpeed(), // 4g
  };

  if (options.debug) {
    console.log('[Analytics]', metric.name, JSON.stringify(body, null, 2));
  }

  const blob = new Blob([new URLSearchParams(body as Record<string, any>).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:Options) {
  try {
    onFID((metric) => sendToAnalytics(metric, options));
    onTTFB((metric) => sendToAnalytics(metric, options));
    onLCP((metric) => sendToAnalytics(metric, options));
    onCLS((metric) => sendToAnalytics(metric, options));
    onFCP((metric) => sendToAnalytics(metric, options));
  } catch (err) {
    console.error('[Analytics]', err);
  }
}

Astro Component

<script>

   // Replace this with the one that comes from the file with the script that I have written above. 
      import { webVitals } from "~/utils/vitals";

      const analyticsId = import.meta.env.PUBLIC_VERCEL_ANALYTICS_ID;

      if (analyticsId) {
        webVitals({
          analyticsId,
          path: location.pathname,
          params: location.search,
          debug: !import.meta.env.PROD,
        });
      }</script>