Custom properties
Custom properties are key/value pairs attached to an event. They turn a single event name into a richer signal. Instead of Plan Selected alone, you get Plan Selected with plan=pro, billing=annual, currency=usd.
Use them whenever one event covers several variants you want to compare. One event with three properties beats three near-duplicate event names.
Make sure s.js is installed on the page. See Install the tracking script.
Four ways to attach properties
1. JavaScript API
Pass a plain object as the second argument to window.statable.t():
Values can be strings, numbers, or booleans. An object or an array is not refused: it is stored as its raw JSON text, so the property arrives as an unusable value like {"tier":"pro"}. Flatten before sending.
2. HTML data-attributes on the element
Add any number of data-statable-{key} attributes alongside data-statable-event on the same element. When the click fires, the tracking script reads every data-statable-* attribute (except data-statable-event itself) and attaches its value as a property:
<button
data-statable-event="Sign Up"
data-statable-plan="pro"
data-statable-source="footer">
Start Pro plan
</button>
That fires the event Sign Up with plan=pro and source=footer.
Stick to single-word, lowercase keys
The tracking script lowercases property keys read from element attributes. data-statable-plan becomes plan, data-statable-source becomes source. Multi-word kebab keys like data-statable-user-id flatten to userid (no separator, all lowercase). Surprising, and a frequent source of dashboard mismatches. Prefer one-word keys, or use the JavaScript API where you control the exact key shape.
A click inside a link brings its address along
When the click happens anywhere inside an <a>, the tracking script adds one property you did not ask for: url, holding the link's address cut at the path.
<a href="/pricing?ref=nav#plans"
data-statable-event="Pricing Click"
data-statable-position="header">Pricing</a>
That sends position=header and url=https://example.com/pricing. Everything after ? or # is dropped before the event leaves the browser.
It follows the click rather than the tagged element, so a tagged <div> wrapping a link still gets a url when someone clicks the link inside it. A tagged <button> with no link above it gets none, which is why the same markup behaves differently on the two tags.
The property shows up in the dashboard as prop_url.
url is taken on a link
Your own data-statable-url is read first and then overwritten by the link's address, silently. Name it something else, target or destination, whenever the tagged element sits inside a link.
3. Default properties on the script tag
Attach properties to every pageview by adding data-statable-{key} directly to the <script> tag. The tracking script reads them once at load and merges them into each one:
<script defer
src="https://statable.com/js/YOUR_SITE_ID/s.js"
data-statable-app-version="2.4.1"
data-statable-environment="production"></script>
Custom events do not inherit these
Properties on the <script> tag reach pageviews only. An event fired by window.statable.t() or by a data-statable-event click carries just the properties passed to it, so repeat anything it needs there.
Property keys on the script tag keep their hyphens
Unlike attributes on a clicked element, properties read from the <script> tag preserve the raw attribute suffix. So data-statable-app-version arrives as app-version (kebab-case). Single-word keys (data-statable-version, data-statable-env) behave the same everywhere.
4. data-before-send hook (pageviews only)
For dynamic pageview enrichment (values that depend on auth state, A/B buckets, or runtime config), define a global function and reference it from the script tag with data-before-send:
<script>
window.enrichProps = function (props) {
props.logged_in = Boolean(window.currentUser)
props.experiment = window.abTestBucket || 'control'
return props
}
</script>
<script defer
src="https://statable.com/js/YOUR_SITE_ID/s.js"
data-before-send="enrichProps"></script>
The function receives the current properties object, mutates or replaces it, and returns the new value. Return false instead and the pageview is dropped, along with the engagement time and heartbeat that would have followed it. The hook only runs for pageviews. Custom events triggered by window.statable.t() or data-statable-event clicks bypass it. To enrich custom events dynamically, build the props object in JavaScript and pass it to window.statable.t() directly.
Naming conventions
- Use lowercase, single-word keys:
plan,source,userid,cohort. They map identically wherever you set them. - Keep keys stable. Renaming creates a new property in the dashboard; the old one stays until it ages out.
- Keep strings short. Truncate IDs and URLs on your side if needed.
- Don't put PII in properties. No email addresses, full names, or IP-equivalents. Use a hashed or anonymous ID if you need to correlate users.
Viewing properties
Properties are auto-discovered. Fire an event with a new key and it becomes filterable in the dashboard within minutes. Every property surfaces as a filter named prop_<key>. For example, prop_plan = pro scopes every widget to sessions where any event carried plan=pro. Combine property filters with other filters to slice by source, device, or country at the same time.
Limits
- There is a ceiling on how many distinct property keys one site may accumulate. Keep the set small and stable: a key that varies per user or per URL will exhaust it, and makes reports harder to read rather than richer.
- Boolean values are stored as strings in reports. Filter on
"true"/"false", not unquoted values.
Next steps
- Fire an event with properties: Custom events
- Slice the dashboard by property: Filters and segments
- Convert events into measurable outcomes: Goals
Ready to take control of your web analytics? Try Statable free for 30 days. No credit card required, full feature access, built for GDPR. Start your free trial or view a live demo.

