Skip to content

Naming events and properties

Event names

Lowercase letters, digits and underscores, up to 64 characters: ^[a-z0-9_]{1,64}$.

js
analytics.track("popup_opened");
analytics.track("session_saved");
analytics.track("export_failed");

An event whose name does not match is rejected and reported back, and the rest of the batch is still accepted. Nothing else is lost because one name had a space in it.

Name events after what happened, in the past tense, not after where the code lives. A name like popup_opened still means something in six months. handleClick does not.

The distinct-name limit

A project may accumulate 200 distinct event names. That is a deliberate ceiling, and reaching it almost always means a name is being generated rather than chosen:

js
// Wrong. Every user creates a new event name, and the budget is gone in an hour.
analytics.track(`saved_session_${sessionId}`);

// Right. One name, with the varying part as a property.
analytics.track("session_saved", { sessionId });

Names that stop being used free their budget once they age past the 90-day raw retention window. But the limit exists to catch this mistake early, not to be managed around.

Properties

Up to 2048 bytes of JSON per event, after serialisation.

js
analytics.track("export_failed", {
  format: "csv",
  rowCount: 1200,
  reason: "timeout",
});

Prefer a handful of low-cardinality values you will actually group by. A property holding a free-text error message is a property you can never aggregate.

Never put personal data in properties

No email addresses, no names, no user identifiers from your own system, and no URLs that contain any of those. This is not only a privacy position. It is what keeps your extension inside the Chrome Web Store User Data Policy and Mozilla's equivalent, covered on the store policy page.

The identifier the SDK generates is random and scoped to your extension alone. The moment you attach your own account identifier to an event, you have linked that identifier to a person, and the disclosure you filed with the store is no longer accurate.

js
// Never.
analytics.track("signed_in", { email: user.email });

// Fine: a fact about the account, not a way to identify it.
analytics.track("signed_in", { plan: user.plan });

Timestamps

The SDK stamps each event when you call track, not when it sends, so an event queued offline keeps the time it actually happened.

Events are accepted up to seven days from the server's clock in either direction. That window covers an offline laptop, a suspended service worker, and a badly wrong device clock. Beyond it an event is rejected rather than silently filed under the wrong day.

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