track. Both SDKs queue events, send them in batches, and retry on failure.
This page covers custom events. Events that Grain collects without code are on
Automatic tracking.
track returns nothing and is safe to call before init. The call is queued and
replayed after init runs. In Analytics Web, track returns a promise that resolves when the
event is in the queue. Read Name events for the naming convention.
The TypeScript types of the published packages win over this page when they disagree.
Properties
Properties answer the questions “which one” and “how much”. Grain adds device, browser, and attribution properties to every event on its own. Read Automatic properties.- Include the identifiers and amounts that a query needs:
product_id,total,plan. - Use one naming style for every property. The site uses
snake_case. - Do not send passwords, card numbers, or other personal data.
- Put data in properties, not in the event name.
product_viewedwithproduct_id: 'SKU123', notproduct_SKU123_viewed.
Batching
Both SDKs collect events in a queue and send the queue as one request. The queue flushes every 5 seconds, or when it holds 50 events, whichever comes first.Flush the queue
flush sends the queue now and resolves when the request is complete. Call it before a
serverless function returns, and after a purchase or a signup.
track accepts a third argument of type SendEventOptions. When flush is
true, the SDK sends the queue as soon as the event is in it. The Grain Tag track has no
options argument. Call flush on the instance instead.
Analytics Web
Page unload
The Grain Tag listens forbeforeunload, pagehide, and visibilitychange. When one of them
fires, it sends the queue with the Beacon API. Analytics Web does the same on beforeunload.
Do not add your own unload listener for Grain events.
Delivery and retry
- You call
track. The SDK adds the event to the queue. - The queue reaches
batchSizeevents, orflushIntervalpasses, or you callflush. - The SDK sends the batch to the Grain API.
- If the request fails, the SDK retries up to
retryAttemptstimes with exponential backoff. - When a request succeeds, the events are stored and appear in the dashboard.
Attach a user
Events without a user ID are anonymous. Callidentify after login, and every later event
carries the user ID. Read Identify users.
Debug logging
Setdebug: true in the configuration of either SDK. The SDK then logs queueing, batching,
requests, and responses to the browser console. For the Grain Tag, you can also add
?grain_debug=1 to the page URL. This turns on the same logs without a code change.
Rules for the client
- Do not track page views by hand when automatic page views are on. Both SDKs track them, including History API navigation. Read Automatic tracking.
- Do not start an event name with
_grain_. The prefix is reserved for system events. - Call
flushbefore a process exits. A serverless function ends before the flush timer fires. - In Analytics Web, pass
{ flush: true }for an event that must leave the page now, such as a form submit that navigates away. - Do not retry a
trackcall yourself. The SDK retriesretryAttemptstimes. - In the Grain Tag,
import { track } from '@grainql/tag'has no side effects. Outside a browser it returns a no-op, so a server render does not need a guard.