Skip to content

Attributes vs Imperative API

The FanFest SDK supports two approaches for tracking events: declarative attributes and imperative API calls. Choose the approach that best fits your use case.

Declarative Attributes

Use HTML data attributes for simple, static tracking. Perfect for CMS users and static content.

Basic Attributes

html
<button
  data-fanfest-track="cta_click"
  data-fanfest-on="click"
  data-fanfest-object-id="hero-cta-1"
>
  Get Started
</button>

Supported Triggers

| -------- | ------------------ | -------------------------- | | click | Mouse click events | data-fanfest-on="click" | | submit | Form submission | data-fanfest-on="submit" | | render | Element visibility | data-fanfest-on="render" |

Event Modifiers

Modifiers control event behavior and can be combined:

html
<!-- Prevent default behavior -->
<button data-fanfest-on="click:prevent">Submit</button>

<!-- Fire only once -->
<button data-fanfest-on="click:once">One-time Action</button>

<!-- Stop event propagation -->
<button data-fanfest-on="click:stop">Isolated Click</button>

<!-- Use capture phase -->
<button data-fanfest-on="click:capture">Early Capture</button>

<!-- Combined modifiers -->
<button data-fanfest-on="click:prevent:once">Submit Once</button>

Metadata Attributes

Add custom metadata with data-fanfest-meta-* attributes:

html
<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
</button>

Imperative API

Use JavaScript method calls for dynamic, programmatic tracking. Perfect for React/SPA developers.

Basic Tracking

javascript
FanFestSDK.trackEvent({
  action: "cta_click",
  externalObjectId: "hero-cta-1",
});

Advanced Tracking

javascript
FanFestSDK.trackEvent({
  action: "purchase",
  externalObjectId: "product-123",
  externalExperienceId: "checkout",
  metadata: {
    campaign: "BlackFriday",
    amount: 99.99,
    currency: "USD",
  },
});

React Integration

jsx
// FanFestSDK is available globally after loading the SDK script
function CTAButton({ productId, campaign }) {
  const handleClick = async () => {
    // Track the click
    await FanFestSDK.trackEvent({
      action: "cta_click",
      externalObjectId: productId,
      metadata: { campaign },
    });

    // Handle the click
    navigateToProduct(productId);
  };

  return <button onClick={handleClick}>View Product</button>;
}

When to Use Each Approach

Use Declarative Attributes When:

  • CMS/WordPress content management
  • Static HTML pages
  • Simple tracking requirements
  • Non-technical users managing content
  • Server-side rendering (SSR)

Use Imperative API When:

  • React/Vue/Angular applications
  • Dynamic content generation
  • Complex tracking logic
  • Conditional tracking based on user state
  • Async operations and error handling

Performance Considerations

Attributes Performance

Pros:

  • Zero JavaScript overhead for tracking
  • Automatic cleanup when elements are removed
  • Works with server-side rendering

Cons:

  • Limited to static data
  • No conditional logic
  • Harder to debug

Imperative Performance

Pros:

  • Full control over when/how to track
  • Dynamic data and conditional logic
  • Better error handling and debugging

Cons:

  • Requires JavaScript execution
  • Manual cleanup in SPAs
  • More complex implementation

Accessibility Considerations

Attributes Approach

html
<!-- Good: Accessible button with tracking -->
<button
  data-fanfest-track="cta_click"
  data-fanfest-on="click"
  aria-label="Get started with our service"
>
  Get Started
</button>

<!-- Good: Form with tracking -->
<form data-fanfest-track="form_submit" data-fanfest-on="submit">
  <input type="email" required />
  <button type="submit">Subscribe</button>
</form>

Imperative Approach

javascript
// Good: Accessible with proper event handling
function handleFormSubmit(event) {
  event.preventDefault();

  // Track the submission
  FanFestSDK.trackEvent({
    action: "form_submit",
  });

  // Handle the form
  submitForm();
}

Best Practices

Choose Stable Object IDs

html
<!-- Good: Stable, meaningful ID -->
<button data-fanfest-object-id="hero-cta-2024">Get Started</button>

<!-- Bad: DOM-dependent ID -->
<button data-fanfest-object-id="button-1">Get Started</button>

Use Meaningful Descriptions

javascript
// Good: Descriptive and actionable
FanFestSDK.trackEvent({
  action: "purchase",
  externalObjectId: "plan-premium-annual",
});

// Bad: Generic and unhelpful
FanFestSDK.trackEvent({
  action: "click",
});

Handle Errors Gracefully

javascript
async function trackPurchase(productId) {
  try {
    await FanFestSDK.trackEvent({
      action: "purchase",
      externalObjectId: productId,
    });
  } catch (error) {
    console.warn("Failed to track purchase:", error);
    // Continue with purchase flow
  }
}

Next Steps

Released under the MIT License.