Skip to content

Extension SDK reference

@analyticstrend/extension. Chromium and Firefox, one package.

initBackground(options)

Call at the top level of your background script, on every start. Returns a client.

js
const analytics = await initBackground({
  writeKey: "wk_...",
  uninstallTracking: true,
});
OptionTypeDefaultNotes
writeKeystringrequiredFrom your dashboard's Settings screen. Public by design.
endpointstringhttps://analyticstrend.comPoint at your own collector when self-hosting.
appVersionstringnoneYour extension's version, so you can compare releases.
uninstallTrackingbooleanfalseRegisters the uninstall URL on every start. Required for correct behaviour on Firefox — see below.
onError(error) => voidnoneDiagnostic only. Never throws, never changes behaviour.

Returns { track, flush }.

Why uninstallTracking belongs here

Chrome remembers an uninstall URL across service-worker restarts; Firefox forgets it when the event page unloads. Registering from initBackground means it happens on every background start on both browsers, so the difference stops mattering. Registering from an onInstalled handler instead works on Chrome forever and stops working on Firefox within a minute.

client.track(name, props?)

Queues an event. Returns a promise that resolves once the event is persisted.

js
analytics.track("session_saved", { itemCount: 12 });

Do not await this on a path a person is waiting on. Queue operations are serialised, so a track issued during a slow send waits for that send to finish. It is designed to be called and forgotten.

The name must match ^[a-z0-9_]{1,64}$. An invalid name is reported through onError and never enters the queue, so it cannot affect events queued beside it.

client.flush()

Sends everything queued. Always resolves, never rejects, even when the network is down — which is what makes it safe to call from a timer without a catch.

You rarely need it. initBackground flushes at startup, and the queue sends itself once it reaches 50 events.

trackFromContentScript(name, props?)

Sends an event from a content script or popup to the background context, which owns the queue.

js
trackFromContentScript("popup_opened", { source: "toolbar" });

Returns immediately and never throws. If no background listener is live — the service worker is still starting, or the extension is reloading — the event is dropped rather than queued, because a content script has nowhere durable to keep it.

enableUninstallTracking(options)

Registers the uninstall URL directly. Prefer uninstallTracking: true on initBackground.

js
enableUninstallTracking({ writeKey, anonymousId, endpoint });

If you do call it yourself, call it unconditionally on every background start, never inside onInstalled.

getBrowserApi()

Returns Firefox's browser namespace or Chromium's chrome, whichever exists. Throws with a clear message outside an extension context.

getOrCreateAnonymousId(api)

Reads the stored identifier, generating and persisting one on first call.

This is a check-then-act. Calling it concurrently from two contexts can generate two identifiers, of which one wins. Within normal use there is no race, because only initBackground calls it and a browser runs one background context at a time.

What the SDK guarantees

  • Nothing is lost to a teardown. Events are persisted before any send, so a suspended service worker mid-flush costs nothing.
  • Nothing is sent twice. Progress is recorded after every batch, so a restart resumes rather than replaying.
  • The queue is bounded. At 500 events the oldest are dropped, keeping the most recent behaviour rather than a stale prefix.
  • Retries back off. After a failed send the automatic retry waits 30 seconds, so an offline browser does not make one request per event.

Data hosted in Canada. No cookies, no fingerprinting, no personal data.