@caravela-studio/glancy-web
Glancy in the browser, for any framework (or none): events, page views, session replay and heatmaps.
On Next.js use @caravela-studio/glancy-next, which wraps this with a provider and a server client. On a site without a
build step (or WordPress), use the script tag glancy.js below.
npm
Public on npm, no token needed:
npm install @caravela-studio/glancy-web
import { BrowserClient } from "@caravela-studio/glancy-web";
export const glancy = new BrowserClient({
writeKey: "glc_prod_…", // Glancy → Setup
// host: "https://analytics.example.com", // only when self-hosting (default https://ingest.heyglancy.com)
heatmaps: true, // optional
sessionReplay: { sampleRate: 0.5 }, // optional; inputs are masked
});
glancy.page(); // on every route change (your router's hook)
glancy.track("Order Completed", { revenue: 42 });
glancy.identify(user.id, { name: user.name, email: user.email });
glancy.reset(); // on sign out
| Option | Default | |
|---|---|---|
writeKey, host | — | Required |
heatmaps | false | Clicks and scroll depth |
sessionReplay | false | true or { sampleRate, maskAllInputs, maskAllText, maskTextSelector, blockSelector } |
redactParams | key, token, code, password… | Query parameters replaced by redacted in URLs |
flushAt / flushInterval | 20 / 2000 ms | Batching |
consent | — | { ads: boolean }, the visitor's ad consent if already known |
debug | false | Log every event |
Methods: track, page, identify, group, alias, reset, flush, getAnonymousId, getUserId,
getSessionId, startRecording, stopRecording (e.g. when consent is withdrawn), consent({ ads }) (from
your consent banner: with ads: false, the visitor's events are never sent on to ad platforms; a browser with
Global Privacy Control on counts as ads: false).
Privacy: data-glancy-mask hides an element's text in replays, data-glancy-block leaves it out.
Server
@caravela-studio/glancy-web/server: glancy() / ServerClient for any JavaScript server, plus request tracking
with status and duration_ms as API Request events: withGlancyRoute(handler, { waitUntil? }) for fetch-style
handlers and trackRequests() for Express / Connect. Events report @glancy/web-server as their library, so
ingestion treats them as server events. See /docs/sdks/web.
Script tag (glancy.js)
Every Glancy serves it (~7 KB gzipped). Each feature is its own file, fetched only when it's on: glancy-capture.js (autocapture, heatmaps), glancy-errors.js, glancy-vitals.js (at idle) and glancy-replay.js (only for sampled sessions):
<script defer src="https://ingest.heyglancy.com/glancy.js" data-key="glc_prod_…" data-heatmaps data-replay></script>
| Attribute | |
|---|---|
data-key | The bucket's write key (required) |
data-host | Where Glancy runs (default: where the script came from) |
data-heatmaps, data-replay, data-replay-sample="0.25" | Heatmaps / session replay |
data-outbound-links | Track clicks on links to other sites |
data-redact-params="order,email" | More query parameters to hide |
data-manual | No automatic page views |
data-debug | Log everything |
Then glancy.track(…), glancy.identify(…), glancy.reset(). To call it before the script has loaded, add the
stub first and use the function form:
<script>window.glancy=window.glancy||function(){(glancy.q=glancy.q||[]).push([].slice.call(arguments))}</script>
<script>glancy("track", "Pricing Viewed")</script>
No code at all: <button data-glancy-event="Demo Requested" data-glancy-prop-plan="pro"> (works on forms too).