AddonPulse
SDKs

JavaScript (Web)

Official JavaScript SDK for AddonPulse Analytics

Installation

npm install @addonpulse/js
yarn add @addonpulse/js

Initialization

addonpulse.init() must be called once before any other tracking methods (pageview, event, etc.) can be used. Attempting to call other methods before init will result in errors or no tracking.

Syntax

async addonpulse.init(config: AddonpulseConfig): Promise<void>;

Example

import addonpulse from "@addonpulse/js";

await addonpulse.init({
  analyticsHost: "https://app.addonpulse.com/api",
  siteId: "1",
});

Configuration Options

Required Options

OptionTypeDescription
analyticsHoststringURL of your AddonPulse analytics instance (e.g., https://addonpulse.yourdomain.com/api).
siteIdstringThe Site ID for your website obtained from your AddonPulse instance.

Local Configuration Options

These options are configured in your code and control SDK behavior locally:

OptionTypeDefaultDescription
debounceDurationnumber500Debounce time in milliseconds for tracking pageviews after route changes. Set to 0 to disable debouncing (track immediately).
skipPatternsstring[][]Array of path patterns. Pageviews whose path matches any pattern will not be tracked. See Path Matching.
maskPatternsstring[][]Array of path patterns. For matching pageview paths, the original path will be replaced by the pattern itself in tracked data. See Path Matching.
debugbooleanfalseEnable detailed logging to the browser console.

Remote Configuration

These settings are controlled through your AddonPulse dashboard and cannot be set in the init config:

Dashboard SettingDescriptionDefault
Track Initial PageviewTrack pageview on initial page loadtrue
Track SPA NavigationTrack pageviews on Single Page Application route changestrue
Track URL ParametersInclude URL query strings in tracked datatrue
Track Outbound LinksAutomatically track clicks on external linkstrue
Track Button ClicksAutomatically track button click interactionsfalse
Track CopyAutomatically track copy eventsfalse
Track Form InteractionsAutomatically track form submissions and input changesfalse

If fetching settings fails or times out, the SDK uses sensible defaults.

Tracking Pageviews

Pageviews are tracked automatically based on your dashboard settings. This includes the initial page load and subsequent route changes in Single Page Applications (SPAs).

Syntax

addonpulse.pageview(path?: string);

Parameters

  • path (string, Optional):
    • Replaces the detected URL path (window.location.pathname) and query string (window.location.search) for this specific pageview event.
    • Should start with a / (e.g., /virtual/my-custom-page).
    • If path includes its own query string (e.g., /virtual/step?id=123), that query string will be used for the event. If path has no query string, the querystring property will be empty.
    • skipPatterns and maskPatterns will be applied to path.

When to Use Manually

  • Automatic tracking disabled: If you disabled automatic pageview tracking in your dashboard.
  • Virtual Pageviews: In SPAs where a significant view change occurs without a URL change.
  • Specific Timing: If you need to ensure a pageview is tracked only after certain conditions are met.

Example

// Standard manual pageview (usually not needed if auto-tracking is on)
addonpulse.pageview();

// Example: Track a step within a multi-step modal
function openUserDetailsModal(userId, step) {
  // ... logic to open and display the modal step ...
  addonpulse.pageview(`/users/${userId}/modal/${step}`);
}
openUserDetailsModal("user-abc", "contact-info");

// Example: Track a virtual pageview with its own query parameters
function showFilteredProductList(category, sortBy) {
   let virtualPathWithQuery = `/products/category/${category}?sort=${sortBy}&view=grid`;
   addonpulse.pageview(virtualPathWithQuery);
}
showFilteredProductList("electronics", "price_desc");

Tracking Custom Events

Use custom events to track specific user interactions. Examples include button clicks, form submissions, or adding an item to a cart.

Programmatic Tracking

You can trigger events from your JavaScript code.

Syntax

addonpulse.event(name: string, properties?: TrackProperties);

Parameters

  • name (string, Required): The name of the event you want to track.
  • properties (object, Optional): An object containing additional key-value pairs related to the event. Values can be a string, number, boolean, or an array of these types.

Example

// Track a simple button click
document.getElementById("cta-button")?.addEventListener("click", () => {
  addonpulse.event("cta_click");
});

// Track adding an item to a shopping cart with properties
function addToCart(item) {
  // ... add item ...
  addonpulse.event("add_to_cart", {
    itemId: item.id,
    itemName: item.name,
    price: item.price,
    quantity: 1
  });
}

Declarative Tracking with Data Attributes

The SDK automatically listens for clicks on elements with the data-addonpulse-event attribute.

  • data-addonpulse-event="<event-name>": This attribute makes the element trackable. The value is used as the event name.
  • data-addonpulse-prop-<property-name>="<value>": You can add multiple properties to the event by using this attribute format. The SDK collects all attributes starting with data-addonpulse-prop- and includes them as key-value pairs in the event data.

Example

<button data-addonpulse-event="cta_click">Click Me</button>

<button
  data-addonpulse-event="add_to_cart"
  data-addonpulse-prop-item_id="product-123"
  data-addonpulse-prop-item_name="Classic T-Shirt"
  data-addonpulse-prop-price="29.99"
>
  Add to Cart
</button>

Outbound links (links to external domains) are tracked automatically by default based on your dashboard settings. The SDK attaches a global click listener to capture clicks on <a> tags with external href attributes.

Syntax

addonpulse.trackOutbound(url: string, text?: string, target?: string);

Parameters

  • url (string, Required): The destination URL of the outbound link.
  • text (string, Optional): The text content of the link. Defaults to "".
  • target (string, Optional): The target attribute of the link (e.g., _blank). Defaults to _self.

When to Use Manually

  • Automatic tracking disabled: If you disabled outbound link tracking in your dashboard.
  • Non-anchor elements: If you trigger navigation to an external site using JavaScript from an element that isn't an <a> tag.

Example

// Manually track an outbound click triggered by a button
document.getElementById("external-service-button")?.addEventListener("click", () => {
  let url = "https://external-service.com";
  addonpulse.trackOutbound(url, "Visit External Service", "_blank");
  // Optionally navigate after tracking
  window.open(url, "_blank");
});

User Identification

You can associate tracking events with a specific user ID and optional traits. The ID is persisted in localStorage and will be attached to all subsequent tracking events for that user.

identify

Assigns a user ID with optional traits.

addonpulse.identify(userId: string, traits?: Record<string, unknown>);

Parameters:

  • userId (string, Required): The user ID to associate with tracking events.
  • traits (object, Optional): An object containing user attributes/properties.

Example:

// After a user logs in
addonpulse.identify("user-xzy-123");

// With traits
addonpulse.identify("user-xzy-123", {
  email: "user@example.com",
  plan: "premium",
  signupDate: "2024-01-15"
});

setTraits

Updates traits for the currently identified user without changing the user ID.

addonpulse.setTraits(traits: Record<string, unknown>);

Example:

// Update user traits after they upgrade
addonpulse.setTraits({
  plan: "enterprise",
  upgradeDate: "2024-03-01"
});

clearUserId

Clears the stored user ID.

addonpulse.clearUserId();

Example:

// When a user logs out
addonpulse.clearUserId();

getUserId

Retrieves the currently stored user ID.

addonpulse.getUserId(): string | null;

Example:

let currentUserId = addonpulse.getUserId();
console.log("Current AddonPulse User ID:", currentUserId);

Page Change Callbacks

Register callbacks that execute when the page or route changes. This is useful for integrating with third-party tools or triggering custom logic on navigation.

Syntax

addonpulse.onPageChange(callback: (newPath: string, previousPath: string) => void): () => void;

Parameters

  • callback (function, Required): Function to execute on page change. Receives:
    • newPath: The new pathname
    • previousPath: The previous pathname

Returns

Returns an unsubscribe function to remove the callback.

Example

// Register a callback
const unsubscribe = addonpulse.onPageChange((newPath, previousPath) => {
  console.log(`Navigated from ${previousPath} to ${newPath}`);

  // Example: Track scroll position reset
  window.scrollTo(0, 0);
});

// Later, to remove the callback
unsubscribe();

// Example: Multiple callbacks can be registered
addonpulse.onPageChange((newPath) => {
  // Update page title
  document.title = `${newPath} - My Site`;
});

addonpulse.onPageChange((newPath, previousPath) => {
  // Log navigation for debugging
  if (process.env.NODE_ENV === 'development') {
    console.log('Navigation:', { from: previousPath, to: newPath });
  }
});

Callbacks are only triggered when the pathname actually changes. Multiple calls to the same path won't trigger callbacks repeatedly.

Opting Out

Users can opt out of all tracking by setting a flag in localStorage or on the window object. When opted out, all tracking calls are silently ignored.

// Opt out via localStorage (persists across sessions)
localStorage.setItem("disable-addonpulse", "true");

// Opt out via window flag (current session only)
window.__ADDONPULSE_OPTOUT__ = true;

To re-enable tracking, remove the localStorage item and reload the page:

localStorage.removeItem("disable-addonpulse");

Cleanup

In Single Page Applications or other dynamic environments, you may need to manually clean up the listeners that the SDK sets up.

Syntax

addonpulse.cleanup();

What Gets Cleaned Up

  • SPA route change listeners (popstate, hashchange)
  • Outbound link click listeners
  • Data attribute click listeners
  • Page change callbacks
  • Resets initialization state

Example

// In React
useEffect(() => {
  addonpulse.init({
    analyticsHost: "https://app.addonpulse.com/api",
    siteId: "1",
  });

  return () => {
    addonpulse.cleanup();
  };
}, []);

Path Matching

These options allow you to control which page paths are tracked and how they appear in your analytics data using wildcard patterns.

Wildcards

  • *: Matches any sequence of characters except the forward slash (/). Useful for matching single path segments.
  • **: Matches any sequence of characters including the forward slash (/). Useful for matching multiple path segments.

Regex Patterns

For more advanced matching, you can use raw regular expressions by prefixing the pattern with re::

skipPatterns: [
  "re:^/users/\\d+/profile$",  // Match numeric user IDs only
  "re:^/api/v[0-9]+/"          // Match any API version prefix
]

skipPatterns

If a page's path matches any pattern in skipPatterns, the pageview for that path will not be sent.

Examples:

  • "/admin/*": Skips /admin/login, /admin/users, but not /admin/settings/profile.
  • "/admin/**": Skips /admin/login, /admin/users, and /admin/settings/profile.
  • "/users/*/profile": Skips /users/123/profile, /users/abc/profile, but not /users/123/settings.
// Example skipPatterns in init
await addonpulse.init({
  // ... other options
  skipPatterns: [
    "/admin/**",        // Skip all admin sections
    "/debug",           // Skip exact /debug path
    "/users/*/settings" // Skip settings page for any user
  ]
});

maskPatterns

If a page's path matches a pattern in maskPatterns, the pageview will be sent, but the pathname will be replaced by the pattern string itself. This is useful for grouping similar pages or hiding sensitive IDs.

If a path matches both a skipPatterns and a maskPatterns pattern, skipping takes priority.

Examples:

  • Pattern: "/users/*/profile"
    • /users/123/profile is tracked as pathname: "/users/*/profile".
  • Pattern: "/products/**"
    • /products/electronics/tv-123 is tracked as pathname: "/products/**".
// Example maskPatterns in init
await addonpulse.init({
  // ... other options
  maskPatterns: [
    "/users/*/profile",  // Group all user profile views
    "/orders/*"          // Mask specific order IDs
  ]
});

On this page