Declarative Tracking
Declarative tracking uses data-fanfest-* HTML attributes to track user interactions. The SDK automatically discovers annotated elements, attaches event listeners, and reports actions to FanFest. When elements are added or removed from the DOM, the SDK updates its tracking via a MutationObserver — no manual cleanup is needed.
This approach is ideal for CMS-managed content, static sites, and server-rendered pages where you want to add tracking without writing JavaScript.
Data Attributes
The SDK recognizes 6 data attributes. All values come from the TrackDataAttribute enum in the SDK source.
data-fanfest-track (required)
The action name or alias to track. This must match a key you registered with registerActionMapping().
<button data-fanfest-track="READ_ARTICLE">Read More</button>data-fanfest-on
The DOM event that triggers the tracking action. If omitted, defaults to click.
<button data-fanfest-track="READ_ARTICLE" data-fanfest-on="click">
Read More
</button>Supported events (only these 3 are recognized):
| Event | Description | Use Case |
|---|---|---|
click | Mouse click or tap (default) | Buttons, links, cards |
render | Fires immediately when the element is set up by the SDK | Section views, impression tracking |
submit | Form submission | Newsletter signups, contact forms |
Only 3 Events Supported
The SDK only supports click, render, and submit. Other DOM events (scroll, input, timeupdate, etc.) are not tracked declaratively. For custom events, use the imperative API.
data-fanfest-description
A human-readable description of the action. Appears in analytics and can help distinguish between similar actions.
<button
data-fanfest-track="purchase"
data-fanfest-description="Premium Plan Annual"
>
Buy Now
</button>data-fanfest-experience-id
Groups related actions into a logical experience or flow. Useful for tracking multi-step funnels.
<div
data-fanfest-track="CHECKOUT_VIEW"
data-fanfest-on="render"
data-fanfest-experience-id="checkout-flow"
>
<!-- Checkout content -->
</div>data-fanfest-object-id
A unique identifier for the specific object being interacted with (e.g., an article ID, product SKU, or page slug).
<button
data-fanfest-track="READ_ARTICLE"
data-fanfest-on="click"
data-fanfest-object-id="article-2024-champions-league"
>
Read Article
</button>Choose Stable IDs
Use meaningful, stable identifiers like article-champions-league-final rather than DOM-dependent values like button-3. Stable IDs produce better analytics.
data-fanfest-meta-*
Custom key-value metadata. Any attribute prefixed with data-fanfest-meta- is collected into a metadata object. The portion after data-fanfest-meta- becomes the key.
<button
data-fanfest-track="purchase"
data-fanfest-on="click"
data-fanfest-object-id="product-123"
data-fanfest-meta-campaign="BlackFriday"
data-fanfest-meta-amount="99.99"
data-fanfest-meta-currency="USD"
>
Buy Now - $99.99
</button>This produces the metadata object { campaign: "BlackFriday", amount: "99.99", currency: "USD" }.
INFO
All data-fanfest-meta-* values are strings in declarative tracking (HTML attributes are always strings). For typed values, use the imperative API.
Attribute Reference
| Attribute | Required | Description |
|---|---|---|
data-fanfest-track | Yes | Action name or alias (must match a registered mapping) |
data-fanfest-on | No | Trigger event: click (default), render, or submit |
data-fanfest-description | No | Human-readable action description |
data-fanfest-experience-id | No | Groups related actions into a flow |
data-fanfest-object-id | No | Unique identifier for the tracked object |
data-fanfest-meta-* | No | Custom metadata key-value pairs |
Event Modifiers
Modifiers control event listener behavior. Append them to the event name in data-fanfest-on separated by colons. Modifiers correspond to the TrackEventModifier enum in the SDK.
Available modifiers:
| Modifier | Effect |
|---|---|
stop | Calls event.stopPropagation() |
preventDefault | Calls event.preventDefault() and sets passive: false on the listener |
capture | Attaches the listener in the capture phase |
once | Fires the listener only once, then removes it |
Use Full Modifier Names
Modifiers must use their full names exactly as shown. For example, use preventDefault (not prevent) and stop (not stopPropagation).
Modifier Syntax
Append modifiers after the event name, separated by colons:
data-fanfest-on="<event>:<modifier1>:<modifier2>"Examples
<!-- Prevent default form submission behavior -->
<form
data-fanfest-track="newsletter_signup"
data-fanfest-on="submit:preventDefault"
>
<input type="email" required />
<button type="submit">Subscribe</button>
</form>
<!-- Track only the first click -->
<button
data-fanfest-track="first_interaction"
data-fanfest-on="click:once"
>
Welcome Offer
</button>
<!-- Stop propagation to parent handlers -->
<button
data-fanfest-track="isolated_click"
data-fanfest-on="click:stop"
>
Isolated Button
</button>
<!-- Capture phase listener -->
<div
data-fanfest-track="early_capture"
data-fanfest-on="click:capture"
>
Captured Area
</div>Combining Modifiers
Multiple modifiers can be chained:
<!-- Prevent default and fire only once -->
<form
data-fanfest-track="signup"
data-fanfest-on="submit:preventDefault:once"
data-fanfest-description="One-time Newsletter Signup"
data-fanfest-object-id="newsletter-form"
>
<input type="email" placeholder="Enter your email" required />
<button type="submit">Subscribe</button>
</form>
<!-- Stop propagation, prevent default, capture phase -->
<button
data-fanfest-track="priority_action"
data-fanfest-on="click:stop:preventDefault:capture"
>
Priority Action
</button>How It Works
- When the SDK initializes, it scans the DOM for elements with
data-fanfest-track - For each element, it reads the event type from
data-fanfest-on(defaulting toclick) - For
renderevents, the tracking action fires immediately when the element is discovered - For
clickandsubmitevents, the SDK attaches an event listener with the specified modifiers - A MutationObserver watches for DOM changes — new elements are automatically tracked, removed elements are cleaned up
When to Use Declarative Tracking
- CMS-managed content (WordPress, Contentful, etc.)
- Static HTML pages and landing pages
- Server-rendered pages (SSR)
- Simple tracking where no conditional logic is needed
- Non-technical content editors managing tracked elements
For dynamic content, conditional tracking, or typed metadata values, use the imperative API.
Accessibility
Tracking attributes do not affect accessibility. Ensure your tracked elements are already accessible:
<!-- Accessible button with tracking -->
<button
data-fanfest-track="cta_click"
data-fanfest-on="click"
aria-label="Get started with FanFest"
>
Get Started
</button>
<!-- Accessible form with tracking -->
<form
data-fanfest-track="contact_submit"
data-fanfest-on="submit:preventDefault"
>
<label for="email">Email</label>
<input id="email" type="email" required />
<button type="submit">Subscribe</button>
</form>Next Steps
- Imperative Tracking — JavaScript API for dynamic tracking
- Tracking Examples — Real-world patterns and code samples
