Pentru site-urile care nu vor un <script> lipit în HTML, aceeași colectare vine și ca
pachet: @hazeloft/insights. Fără dependențe la runtime, ESM și CommonJS, fără efecte
secundare la import.
Instalare
bun add @hazeloft/insightsUtilizare (React / Next.js)
Componenta se pune o dată, în layout-ul rădăcină. Nu randează nimic și nu are
nevoie de nicio configurare: proiectul se recunoaște din Origin-ul cererii, deci nu
există chei sau id-uri de copiat.
import { HazeloftInsights } from "@hazeloft/insights";
export default function RootLayout({ children }) {
return (
<html lang="ro">
<body>
{children}
<HazeloftInsights />
</body>
</html>
);
}Componenta e un client component ("use client" e în pachet) — merge pusă direct
într-un layout server-component din App Router.
Utilizare (fără React)
Aceeași colectare, ca funcție — o chemi o dată, într-un modul încărcat pe client:
import { initInsights } from "@hazeloft/insights";
initInsights();| Opțiune | Tip | Implicit | Ce face |
|---|---|---|---|
endpoint | string | producția Hazeloft | Originea backendului. De setat doar pentru un alt mediu. |
path | string | /insights/v1/collect | Suprascrie calea de colectare. Rar necesar. |
Aceleași opțiuni există și ca props pe <HazeloftInsights />. Endpoint-ul se poate da
și prin variabila de mediu NEXT_PUBLIC_HAZELOFT_INSIGHTS_ENDPOINT; prioritatea e
prop/opțiune → variabilă de mediu → producția Hazeloft.
Pornirea e idempotentă per încărcare de pagină: dacă ajunge să fie chemată de două
ori (un StrictMode care re-montează, un snippet dublat), a doua oară nu se întâmplă
nimic — traficul nu se dublează. Pe server (fără window) nu face nimic, deci se poate
importa liniștit într-un framework cu randare pe server.
Ce trimite
Aceleași lucruri ca scriptul inline: vizualizări de pagină (inclusiv navigări client-side) și Core Web Vitals — LCP, INP, CLS, TTFB, FCP — grupate și trimise o singură dată, la ascunderea filei.
Trei decizii merită știute, pentru că explică forma lui:
navigator.sendBeaconcutext/plain. Cererea rămâne „simplă" în sensul CORS, deci nu are nevoie de preflight și nici ca serverul să țină o listă de origini permise care s-ar schimba la fiecare proiect nou. În plus,sendBeaconsupraviețuiește închiderii paginii — exact momentul în care se raportează metricile finale.- Evenimentele se acumulează. Un beacon per metrică ar însemna câteva cereri per pagină; grupate, e una singură.
- Sesiunea trăiește în
sessionStorage, nu într-un cookie. Moare cu fila, nu traversează site-uri și nu cere consimțământ. Serverul nu primește niciodată valoarea — doar un boolean „e prima pagină din sesiune".