@nuxtjs/web-vitals
Version:
Web Vitals for Nuxt.js
127 lines (123 loc) • 3.9 kB
JavaScript
import { dirname, join } from 'pathe';
import { defu } from 'defu';
import { defineNuxtModule, createResolver, addTemplate, isNuxt2, addPlugin } from '@nuxt/kit';
const PROVIDERS = [
{
name: "log",
runtime: "./runtime/providers/log",
autoDetect: false,
defaults: () => ({}),
validate: () => {
}
},
{
name: "gtm",
runtime: "./runtime/providers/gtm",
autoDetect: false,
defaults: () => ({}),
validate: () => {
}
},
{
name: "ga",
runtime: "./runtime/providers/ga",
defaults: (nuxtOptions) => ({
eventCategory: "Web Vitals",
id: process.env.GOOGLE_ANALYTICS_ID || nuxtOptions.googleAnalytics && nuxtOptions.googleAnalytics.id
}),
validate({ id }) {
if (!id) {
throw new Error("[@nuxtjs/web-vitals] `googleAnalytics.id` is required for Google Analytics integration");
}
}
},
{
name: "vercel",
runtime: "./runtime/providers/vercel",
defaults: (_nuxtOptions) => ({
dsn: process.env.VERCEL_ANALYTICS_ID
}),
validate({ dsn }) {
if (!dsn) {
throw new Error("[@nuxtjs/web-vitals] `vercel.dsn` or `VERCEL_ANALYTICS_ID` environment is required for Vercel integration");
}
}
},
{
name: "api",
runtime: "./runtime/providers/api",
defaults: () => ({}),
validate({ url }) {
if (!url) {
throw new Error("[@nuxtjs/web-vitals] api.url is required for API integration");
}
}
}
];
const module = defineNuxtModule({
meta: {
name: "web-vitals",
configKey: "webVitals",
compatibility: {
nuxt: "^3.0.0 || ^2.15.0"
}
},
defaults: {
provider: "auto",
debug: false,
disabled: false
},
async setup(options, nuxt) {
if (options.disabled) {
return;
}
const resolver = createResolver(import.meta.url);
const resolveProvider = (providerName, userOptions = {}) => {
const provider2 = PROVIDERS.find((p) => p.name === providerName);
if (!provider2) {
throw new Error("Provider not found: " + providerName);
}
provider2.options = defu(userOptions, provider2.defaults(nuxt.options));
provider2.validate(provider2.options);
return provider2;
};
let provider;
if (options.provider === "auto") {
for (const _provider of PROVIDERS) {
if (_provider.autoDetect === false) {
continue;
}
try {
provider = resolveProvider(_provider.name, options[_provider.name]);
console.info("[@nuxtjs/web-vitals] Auto detected provider:", provider.name);
break;
} catch (err) {
}
}
if (!provider) {
if (nuxt.options.dev && options.debug) {
provider = resolveProvider("log");
} else {
console.warn("[@nuxtjs/web-vitals] Please define a provider to activate this module.");
return;
}
}
} else {
provider = resolveProvider(options.provider, options[options.provider]);
}
provider.runtime = resolver.resolve(provider.runtime);
nuxt.options.build.transpile.push(dirname(provider.runtime));
nuxt.options.alias["~web-vitals-provider"] = provider.runtime;
nuxt.options.build.transpile.push(resolver.resolve("./runtime"));
const runtimeOptions = { debug: options.debug, ...provider.options };
addTemplate({ filename: "web-vitals-config.mjs", getContents: () => `export default ${JSON.stringify(runtimeOptions, null, 2)}` });
if (isNuxt2()) {
nuxt.options.alias["#build/web-vitals-config.mjs"] = join(nuxt.options.buildDir, "web-vitals-config.mjs");
nuxt.options.alias.ufo = await resolver.resolvePath("ufo/dist/index.mjs");
addPlugin(resolver.resolve("./runtime/plugin.nuxt2.client.mjs"));
} else {
addPlugin(resolver.resolve("./runtime/plugin.client"));
}
}
});
export { module as default };