92 lines
2.4 KiB
JavaScript
92 lines
2.4 KiB
JavaScript
import { getCLS, getFCP, getFID, getLCP, getTTFB } from "web-vitals";
|
|
|
|
let isRegistered = false;
|
|
|
|
function onError(err) {
|
|
console.error("[gatsby-plugin-vercel]", err); // eslint-disable-line no-console
|
|
}
|
|
|
|
function onDebug(label, payload) {
|
|
console.log(label, payload); // eslint-disable-line no-console
|
|
}
|
|
|
|
function sendToAnalytics(metric, options) {
|
|
// Scrape the intial component name from the DOM:
|
|
const pageScript = [].slice
|
|
.call(
|
|
/^\/component---(.+)\-(.+?)\-.{20}\.js$/.exec(
|
|
document
|
|
.querySelector(`script[src^="/component---"]`)
|
|
?.getAttribute("src")
|
|
) ?? []
|
|
)
|
|
.slice(1)
|
|
.join("-");
|
|
|
|
const chunkMapping = self.___chunkMapping
|
|
? typeof self.___chunkMapping === "string"
|
|
? JSON.parse(self.___chunkMapping)
|
|
: self.___chunkMapping
|
|
: {};
|
|
|
|
// Verify page name is correct:
|
|
const pageName =
|
|
"component---" + pageScript in chunkMapping ? pageScript : null;
|
|
|
|
if (options.debug && !pageName) {
|
|
onDebug(
|
|
`[gatsby-plugin-vercel]`,
|
|
"Unable to detect Page Name, skipping reporting."
|
|
);
|
|
}
|
|
|
|
const body = {
|
|
dsn: options.analyticsId,
|
|
id: metric.id,
|
|
page: pageName ?? "",
|
|
href: location.href,
|
|
event_name: metric.name,
|
|
value: metric.value.toString(),
|
|
speed:
|
|
"connection" in navigator &&
|
|
navigator["connection"] &&
|
|
"effectiveType" in navigator["connection"]
|
|
? navigator["connection"]["effectiveType"]
|
|
: "",
|
|
};
|
|
|
|
if (options.debug) {
|
|
onDebug(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",
|
|
});
|
|
const vitalsUrl = "https://vitals.vercel-analytics.com/v1/vitals";
|
|
(navigator.sendBeacon && navigator.sendBeacon(vitalsUrl, blob)) ||
|
|
fetch(vitalsUrl, {
|
|
body: blob,
|
|
method: "POST",
|
|
credentials: "omit",
|
|
keepalive: true,
|
|
});
|
|
}
|
|
|
|
export async function webVitals({ options }) {
|
|
// Only register listeners once
|
|
if (isRegistered) {
|
|
return;
|
|
}
|
|
isRegistered = true;
|
|
|
|
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) {
|
|
onError(err);
|
|
}
|
|
}
|