Tracker.js
An event tracking pattern designed for transparency and high-availability.
Core Belief:
Everyone benefits from easy access to data regardless of technical skillset, job title, or prior context.
| Role | Need |
|---|---|
| Product Management | Wants to monitor health of cohorts, conversion rates of popular funnels |
| Design | Wants to discover new areas of opportunity to improve user experience |
| Engineering | Wants to monitor that a feature is being used and is working as designed. |
| Anyone else | Wants to make a data-driven decision. |
Problem 1:
As a company scales it becomes harder and harder to manage the context around a growing number of events, or what events exist in the first place.
Problem 2:
As we become more data-driven the reliability of event data needs to increase as well.
"Do you know the event name for when X happens?"
"What exactly are we tracking in app X?"
"I saw that X property was being sent with Y property, but it stopped sending a week ago, what happened?"

Every person asked increases time to get an answer and is a real business cost
but more importantly...

What we're trying to solve
Asks for Data
Stakeholders
People with context or ability to fulfill requests for data
Hard
Asks for Data
Easy
Easy
Easy
Easy
Easy
Easy
Hard
Hard
Easy
Easy
Complex data analysis takes longer to get and blocks asks for easy data.
Hard
Asks for Data
Easy
Easy
Easy
Easy
Easy
Easy
Hard
Hard
Easy
People with context or ability to fulfill requests for data (Periscope)
The ability to easily self-serve requests for data with Amplitude.
What we're not trying to solve
We will always need people who can crunch complex data and asks that require more complex analysis will increase as we scale.
We're not trying to create a catch-all solution. Instead, we're attempting to empower everyone by making it easier access data that's more straightforward.
✨Tracker✨
A two-part solution to scaling event tracking.
A centralized, auto-documenting dictionary of events to increase cross-team transparency.
A tracking client that validates against the event dictionary to ensure reliability.
Event Dictionary
What is the event dictionary?
Lists all the events in your project.
Lists all properties associated with those events
Lists all the expected types for those properties
Lists a description for all events and properties to provide context to external stakeholders.
A JSON file
{
"namespace": "My App",
"events": {
"page viewed": {
"description": "This event fires whenever...",
"properties": {
"url": {
"description": "The url that the user...",
"type": "string"
},
}
}
}
}{
"namespace": "My App",
}Define your namespace
Name this similarly to how you would refer to you project to a non-technical stakeholder.
{
"namespace": "My App",
"events":{
"page viewed": {
"description": "This event is fired when..."
}
}
}Defining Events
Event names are defined as keys, events can have descriptions that help provide context.
{
"namespace": "My App",
"events":{
"page viewed": {
"description": "This event is fired when...",
"properties:": {
"url": {
"description": "The location of the page view"
}
}
}
}
}Defining Properties
Properties are used to drill down into specifics about an event. Properties are used to segment similar events.
{
"namespace": "My App",
"events":{
"page viewed": {
"description": "This event is fired when...",
"properties:": {
"url": {
"description": "The location of the page view"
}
}
}
}
}Defining Properties
Properties can also be given descriptions to help provide context for generalized property names.
{
"namespace": "My App",
"events":{
"page viewed": {
"description": "This event is fired when...",
"properties:": {
"url": {
"description": "The location of the page view",
"type": "string"
}
}
}
}
}Defining Property Types
Every property has an associated type. This is the type that we expect the value to be when sent.
"string""number""boolean""null"["string", "null"]Why are we changing the way we name events?
Event Name:
Page: Viewed store/checkout/hello/there
Segmentation
Old

Old
Event Name:
"page viewed"
Properties:
"page": "home"
"url": "https://hello.com"
Segmentation
New

New
Property segmentation helps keep down noise and makes getting a holistic perspective about an event faster.
Amplitude has a limit on # of total properties while the warehouse does not.
To get around this we only allow certain properties on events. If you find that none of the whitelisted properties fit your use case ping #event-tracking.
Disclaimer
Auto-generated documentation
Since all events are static and pre-defined we can generate documentation for them.
{
"namespace": "Customer Tipping",
"events": {
"order summary page viewed": {
"description": "This event fires whenever...",
"properties": {
"url": {
"description": "The url that the user is...",
"type": "string"
},
"app_name": {
"description": "The name of the application...",
"type": "string"
},
...Customer Tipping

tracker.ezcater.net
The event dictionary also serves as the contract between engineers and stakeholders that rely on that data.
How do we enforce that contract?
tracker-js
The tracking client that goes integrates with the event dictionary pattern.
Validates events against the event dictionary at runtime to ensure that it is sent with the expected data.
Abstracts away implementation details of sending event data.
Runtime Validation
{
"namespace": "My App",
"events": {
"page viewed": {
"description": "This event fires whenever...",
"properties": {
"url": {
"description": "The url that the user...",
"type": "string"
},
}
}
}
}import {createTracker} from '@ezcater/tracker-js';
import eventDictionary from './eventDictionary.json';
const tracker = createTracker(eventDictionary);
export default tracker;tracker.js
Tracker Singleton
import tracker from '../path/to/tracker';
tracker.track('page viewed', {
url: window.location.origin
});MyApp.js
{
"namespace": "My App",
"events": {
"page viewed": {
"description": "This event...",
"properties": {
"url": {
"description": "The url...",
"type": "string"
},
}
}
}
}The event you track corresponds to an event defined in the event dictionary
import tracker from '../path/to/tracker';
tracker.track('page viewed', {
url: window.location.origin
});MyApp.js
{
"namespace": "My App",
"events": {
"page viewed": {
"description": "This event...",
"properties": {
"url": {
"description": "The url...",
"type": "string"
},
}
}
}
}Properties also correspond to a defined property in your dictionary.
import tracker from '../path/to/tracker';
tracker.track('page viewed', {
url: window.location.origin
});MyApp.js
{
"namespace": "My App",
"events": {
"page viewed": {
"description": "This event...",
"properties": {
"url": {
"description": "The url...",
"type": "string"
},
}
}
}
}The values of these properties are validated against the defined type.
What else does it validate?
Undefined Events
'No definition found for event
"page viewed" in event dictionary.'Undefined Properties
'No definition found for property "url" on
event "page viewed" in event dictionary.'
Invalid Types
'Invalid value "123" for property "url",
must be of type "string"'Type validation avoids undefined values and helps build and maintain trust between your team and external stakeholders that rely on your data.
Incorrect events will throw an error. Your unit tests will break event if you don't write a test for it if the call to "track" is incorrect.
Technical Goodies
Send Beacon
A browser API that can make HTTP requests even if you close the tab or navigate away from the page.
Tracked events on elements like <a /> should not be dropped.
Track Anything
The tracking client is view-layer agnostic so you can track interactions on a React component or track calls to a vanilla JavaScript function.

This is an ongoing project, we can support flexible use cases as they arise but the goal is having a centralized way to get data and share context about data as we scale.
New tracking clients for Ruby or Swift can be made as the project is adopted more.
Get Involved

Questions?
#event-tracking
Get Started Today
Thank you!
Tracker.js
By Alec Ortega
Tracker.js
- 458