Add Plausible and Google Site Verification support to analytics and environment configuration

This commit is contained in:
Your Name
2026-03-10 10:47:43 +02:00
parent 2d53c8df97
commit d5e6df42d3
4 changed files with 334 additions and 16 deletions

View File

@@ -1,4 +1,7 @@
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
VITE_PLAUSIBLE_DOMAIN=
VITE_PLAUSIBLE_SRC=https://plausible.io/js/script.js
VITE_GOOGLE_SITE_VERIFICATION=
VITE_ADSENSE_CLIENT_ID=ca-pub-XXXXXXXXXXXXXXXX
VITE_ADSENSE_SLOT_HOME_TOP=1234567890
VITE_ADSENSE_SLOT_HOME_BOTTOM=1234567891

View File

@@ -4,12 +4,17 @@ declare global {
interface Window {
dataLayer: unknown[];
gtag?: (...args: unknown[]) => void;
plausible?: (event: string, opts?: { props?: Record<string, string> }) => void;
}
}
const GA_MEASUREMENT_ID = (import.meta.env.VITE_GA_MEASUREMENT_ID || '').trim();
const PLAUSIBLE_DOMAIN = (import.meta.env.VITE_PLAUSIBLE_DOMAIN || '').trim();
const PLAUSIBLE_SRC = (import.meta.env.VITE_PLAUSIBLE_SRC || 'https://plausible.io/js/script.js').trim();
let initialized = false;
// ─── Google Analytics ────────────────────────────────────────────
function ensureGtagShim() {
window.dataLayer = window.dataLayer || [];
window.gtag =
@@ -34,34 +39,89 @@ function loadGaScript() {
document.head.appendChild(script);
}
export function initAnalytics() {
if (initialized || !GA_MEASUREMENT_ID || typeof window === 'undefined') return;
// ─── Plausible Analytics ─────────────────────────────────────────
function loadPlausibleScript() {
if (!PLAUSIBLE_DOMAIN) return;
const existing = document.querySelector<HTMLScriptElement>('script[data-plausible]');
if (existing) return;
const script = document.createElement('script');
script.defer = true;
script.setAttribute('data-domain', PLAUSIBLE_DOMAIN);
script.setAttribute('data-plausible', '');
script.src = PLAUSIBLE_SRC;
document.head.appendChild(script);
}
// ─── Search Console verification ─────────────────────────────────
function injectSearchConsoleVerification() {
const code = (import.meta.env.VITE_GOOGLE_SITE_VERIFICATION || '').trim();
if (!code) return;
const existing = document.querySelector('meta[name="google-site-verification"]');
if (existing) return;
const meta = document.createElement('meta');
meta.name = 'google-site-verification';
meta.content = code;
document.head.appendChild(meta);
}
// ─── Public API ──────────────────────────────────────────────────
export function initAnalytics() {
if (initialized || typeof window === 'undefined') return;
// Google Analytics
if (GA_MEASUREMENT_ID) {
ensureGtagShim();
loadGaScript();
window.gtag?.('js', new Date());
window.gtag?.('config', GA_MEASUREMENT_ID, { send_page_view: false });
}
// Plausible
loadPlausibleScript();
// Search Console
injectSearchConsoleVerification();
ensureGtagShim();
loadGaScript();
window.gtag?.('js', new Date());
window.gtag?.('config', GA_MEASUREMENT_ID, { send_page_view: false });
initialized = true;
}
export function trackPageView(path: string) {
if (!initialized || !window.gtag) return;
window.gtag('event', 'page_view', {
page_path: path,
page_location: `${window.location.origin}${path}`,
page_title: document.title,
});
// GA4
if (window.gtag) {
window.gtag('event', 'page_view', {
page_path: path,
page_location: `${window.location.origin}${path}`,
page_title: document.title,
});
}
// Plausible tracks page views automatically via its script
}
export function trackEvent(
eventName: string,
params: Record<string, AnalyticsValue> = {}
) {
if (!initialized || !window.gtag) return;
window.gtag('event', eventName, params);
// GA4
if (window.gtag) {
window.gtag('event', eventName, params);
}
// Plausible custom event
if (window.plausible) {
const props: Record<string, string> = {};
for (const [k, v] of Object.entries(params)) {
if (v !== undefined) props[k] = String(v);
}
window.plausible(eventName, { props });
}
}
export function analyticsEnabled() {
return Boolean(GA_MEASUREMENT_ID);
return Boolean(GA_MEASUREMENT_ID) || Boolean(PLAUSIBLE_DOMAIN);
}