Skip to content

Click Tracking Examples

Track user clicks across different platforms and frameworks with the FanFest SDK.

WordPress/CMS Examples

Basic Button Tracking

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

Dynamic Social Sharing with Vue.js

Here's how to implement dynamic social sharing with engagement tracking:

vue
<template>
  <!-- Social sharing buttons with dynamic tracking -->
  <button
    v-for="value in socialShare"
    :key="value.name"
    class="rounded-full bg-brand-50 text-brand-600 hover:bg-brand-600 hover:text-white transition-all duration-300 p-2 size-10 flex items-center justify-center"
    :data-fanfest-track="value.dataFanfestTrack"
    data-fanfest-on="click"
    :data-fanfest-description="`Shared on ${value.name}`"
    :data-fanfest-experience-id="`SHARE_ARTICLE_ON_${value.name.toUpperCase()}`"
  >
    <Icon :name="value.icon" class="size-4" />
  </button>
</template>

<script setup>
const socialShare = [
  {
    name: "Facebook",
    icon: "mdi:facebook",
    dataFanfestTrack: "SHARE_ARTICLE_ON_FACEBOOK",
  },
  {
    name: "X",
    icon: "mdi:twitter",
    dataFanfestTrack: "SHARE_ARTICLE_ON_X",
  },
  {
    name: "Instagram",
    icon: "mdi:instagram",
    dataFanfestTrack: "SHARE_ARTICLE_ON_INSTAGRAM",
  },
];
</script>

Product Purchase Button

html
<button
  data-fanfest-track="purchase"
  data-fanfest-on="click"
  data-fanfest-description="Product Purchase"
  data-fanfest-object-id="product-123"
  data-fanfest-meta-amount="99.99"
  data-fanfest-meta-currency="USD"
>
  Buy Now - $99.99
</button>

Newsletter Signup

html
<form
  data-fanfest-track="newsletter_signup"
  data-fanfest-on="submit"
  data-fanfest-description="Newsletter Signup"
  data-fanfest-object-id="newsletter-form"
>
  <input type="email" placeholder="Enter your email" required />
  <button type="submit">Subscribe</button>
</form>

Gutenberg Block Example

html
<!-- WordPress Gutenberg block -->
<div class="wp-block-button">
  <button
    data-fanfest-track="cta_click"
    data-fanfest-on="click"
    data-fanfest-description="Block CTA"
    data-fanfest-object-id="block-cta-1"
    class="wp-block-button__link"
  >
    Learn More
  </button>
</div>

React/SPA Examples

Basic Click Handler

jsx
// FanFestSDK is available globally after loading the SDK script
function CTAButton() {
  const handleClick = async () => {
    await FanFestSDK.trackEvent({
      action: "cta_click",
      description: "Hero CTA",
      externalObjectId: "hero-cta-1",
    });

    // Handle the click
    navigateToSignup();
  };

  return <button onClick={handleClick}>Get Started</button>;
}

Product Card with Tracking

jsx
function ProductCard({ product }) {
  const handleViewProduct = async () => {
    await FanFestSDK.trackEvent({
      action: "product_view",
      description: "Product Card Click",
      externalObjectId: product.id,
      metadata: {
        category: product.category,
        price: product.price,
      },
    });

    navigateToProduct(product.id);
  };

  return (
    <div className="product-card">
      <h3>{product.name}</h3>
      <p>${product.price}</p>
      <button onClick={handleViewProduct}>View Details</button>
    </div>
  );
}

Form Submission with Error Handling

jsx
function ContactForm() {
  const handleSubmit = async (event) => {
    event.preventDefault();

    try {
      // Track the form submission
      await FanFestSDK.trackEvent({
        action: "form_submit",
        description: "Contact Form Submission",
        externalObjectId: "contact-form",
      });

      // Handle the form
      await submitForm();
    } catch (error) {
      console.error("Form submission failed:", error);
      // Continue with error handling
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="name" required />
      <input type="email" name="email" required />
      <button type="submit">Send Message</button>
    </form>
  );
}

Advanced Patterns

Conditional Tracking

jsx
function ConditionalCTA({ user, product }) {
  const handleClick = async () => {
    // Track based on user state
    if (user.isLoggedIn) {
      await FanFestSDK.trackEvent({
        action: "authenticated_cta_click",
        description: "Logged-in User CTA",
        externalObjectId: product.id,
        metadata: {
          userType: "authenticated",
          productCategory: product.category,
        },
      });
    } else {
      await FanFestSDK.trackEvent({
        action: "anonymous_cta_click",
        description: "Anonymous User CTA",
        externalObjectId: product.id,
        metadata: {
          userType: "anonymous",
        },
      });
    }

    // Handle the click
    handleCTAClick();
  };

  return (
    <button onClick={handleClick}>
      {user.isLoggedIn ? "Add to Cart" : "Sign Up to Purchase"}
    </button>
  );
}

Batch Tracking

jsx
function ProductGrid({ products }) {
  const handleProductClick = async (product) => {
    // Track the individual click
    await FanFestSDK.trackEvent({
      action: "product_click",
      description: "Product Grid Click",
      externalObjectId: product.id,
      metadata: {
        position: product.position,
        category: product.category,
      },
    });

    // Track grid interaction
    await FanFestSDK.trackEvent({
      action: "grid_interaction",
      description: "Product Grid Interaction",
      externalObjectId: "product-grid",
      metadata: {
        totalProducts: products.length,
        clickedProduct: product.id,
      },
    });

    navigateToProduct(product.id);
  };

  return (
    <div className="product-grid">
      {products.map((product) => (
        <div key={product.id} onClick={() => handleProductClick(product)}>
          <h3>{product.name}</h3>
          <p>${product.price}</p>
        </div>
      ))}
    </div>
  );
}

Edge Cases

Disabled Buttons

html
<!-- Track disabled state -->
<button
  data-fanfest-track="cta_click"
  data-fanfest-on="click"
  data-fanfest-description="Disabled CTA"
  data-fanfest-object-id="disabled-cta"
  disabled
>
  Coming Soon
</button>
jsx
// React: Track disabled state
function DisabledButton() {
  const handleClick = async () => {
    await FanFestSDK.trackEvent({
      action: "disabled_cta_click",
      description: "Disabled CTA Clicked",
      externalObjectId: "disabled-cta",
      metadata: {
        state: "disabled",
      },
    });
  };

  return (
    <button onClick={handleClick} disabled>
      Coming Soon
    </button>
  );
}

Delegated Events

jsx
// Track dynamically added elements
function DynamicList({ items }) {
  const handleItemClick = async (event) => {
    const itemId = event.target.dataset.itemId;

    await FanFestSDK.trackEvent({
      action: "list_item_click",
      description: "Dynamic List Item Click",
      externalObjectId: itemId,
      metadata: {
        listType: "dynamic",
        itemIndex: event.target.dataset.index,
      },
    });

    handleItemClick(itemId);
  };

  return (
    <div onClick={handleItemClick}>
      {items.map((item, index) => (
        <div key={item.id} data-item-id={item.id} data-index={index}>
          {item.name}
        </div>
      ))}
    </div>
  );
}

Accessibility Considerations

html
<!-- Accessible button with tracking -->
<button
  data-fanfest-track="cta_click"
  data-fanfest-on="click"
  data-fanfest-description="Accessible CTA"
  data-fanfest-object-id="accessible-cta"
  aria-label="Get started with our service"
  role="button"
>
  Get Started
</button>
jsx
// React: Accessible with proper event handling
function AccessibleButton() {
  const handleClick = async () => {
    await FanFestSDK.trackEvent({
      action: "accessible_cta_click",
      description: "Accessible CTA Click",
      externalObjectId: "accessible-cta",
    });

    handleCTAClick();
  };

  const handleKeyDown = async (event) => {
    if (event.key === "Enter" || event.key === " ") {
      event.preventDefault();
      await handleClick();
    }
  };

  return (
    <button
      onClick={handleClick}
      onKeyDown={handleKeyDown}
      aria-label="Get started with our service"
      role="button"
    >
      Get Started
    </button>
  );
}

Next Steps

Released under the MIT License.