Skip to main content
Banners in the Tappd Web SDK are placement-based content units that attach to specific DOM elements on your page. Unlike in-app messages — which are trigger-driven and float above your layout — banners live inside defined HTML containers and support rich targeting, scheduling, frequency capping, and A/B testing directly from the dashboard.

Quick Start

The SDK handles fetching, rendering, and event tracking in a single call:
import { TappdSDK } from '@tappd/web-sdk';

const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  apiUrl: 'https://sdk.gotappd.com/api/v1/sdk'
});

// Identify the user first — required for targeting to work
await tappd.identify({
  external_id: 'user_123',
  email: 'john@example.com',
  name: 'John Doe'
});

// Fetch and render banners for a placement — that's all you need
await tappd.getBanners('#header-banner');
When you call getBanners(), the SDK automatically:
  1. Fetches eligible banners from the API for the identified user
  2. Renders them inside the target DOM element
  3. Tracks display, click, and dismiss events
Banners use a placement identifier to find the right DOM element. The Tappd dashboard lets you configure each banner’s placement type.
Target an element by its CSS selector. The example below attaches a banner to <header id="header-banner">.
<!-- Your HTML -->
<header id="header-banner">
  <!-- Banner content is injected here automatically -->
</header>
await tappd.getBanners('#header-banner');

Auto-Rendering (Default)

By default, getBanners() renders banners directly into the target element. You can make this explicit with the autoRender option, and use forceRefresh to bypass the local cache and fetch the latest banner data from the API:
// Both calls below produce the same result
await tappd.getBanners('#header-banner');
await tappd.getBanners('#header-banner', { autoRender: true });

// Force a fresh fetch from the API, ignoring any cached banner data
await tappd.getBanners('#header-banner', { autoRender: true, forceRefresh: true });
The SDK handles the full rendering cycle for you:
  • Locates the target element using the selector
  • Creates and styles the banner element
  • Injects content (title, message, image, CTA button)
  • Appends a close button if the banner is dismissible
  • Applies the configured animation (fade or slide)
  • Tracks the display event automatically
  • Wires up click and dismiss event handlers

Custom UI Rendering

If you want full control over the banner’s appearance, disable auto-rendering and build your own UI with the returned banner data:
// Fetch banner data without rendering
const banners = await tappd.getBanners('#header-banner', { autoRender: false });

banners.forEach(async ({ banner, variant }) => {
  const container = document.querySelector('#header-banner');

  const bannerEl = document.createElement('div');
  bannerEl.className = 'custom-banner';
  bannerEl.innerHTML = `
    <img src="${variant.content.imageUrl}" alt="${variant.content.title}">
    <div>
      <h3>${variant.content.title}</h3>
      <p>${variant.content.message}</p>
      <button class="cta-btn">${variant.content.cta.text}</button>
      <button class="close-btn">×</button>
    </div>
  `;

  // Track the display and store the displayId for later
  const displayId = await tappd.banners.display(banner._id, variant._id, '#header-banner');
  bannerEl.dataset.displayId = displayId;
  bannerEl.dataset.bannerId = banner._id;

  // Track CTA click
  bannerEl.querySelector('.cta-btn').addEventListener('click', async () => {
    await tappd.banners.click(banner._id, displayId);
    window.location.href = variant.content.cta.link;
  });

  // Track dismiss
  bannerEl.querySelector('.close-btn').addEventListener('click', async () => {
    await tappd.banners.dismiss(banner._id, displayId);
    bannerEl.remove();
  });

  container.appendChild(bannerEl);
});

Manual Event Tracking

Use these methods when implementing a custom UI. For auto-rendered banners, event tracking is handled for you.
// Returns a displayId — store it to track subsequent interactions
const displayId = await tappd.banners.display(
  bannerId,   // Banner ID
  variantId,  // Variant ID
  selector    // Placement selector, e.g. '#header-banner'
);
getBanners() returns an array of objects, each containing a banner and a variant:
[
  {
    "banner": {
      "_id": "banner_id_123",
      "name": "Summer Sale Banner",
      "placement": {
        "type": "css_selector",
        "cssSelector": "#header-banner",
        "dataAttribute": null,
        "dataAttributeValue": null
      }
    },
    "variant": {
      "_id": "variant_id_456",
      "name": "Variant A",
      "content": {
        "title": "Summer Sale",
        "message": "Get 50% off on all items!",
        "imageUrl": "https://example.com/banner.jpg",
        "link": "https://example.com/sale",
        "cta": {
          "text": "Shop Now",
          "link": "https://example.com/sale",
          "action": "link"
        }
      },
      "design": {
        "position": "top",
        "layout": "horizontal",
        "backgroundColor": "#ffffff",
        "textColor": "#000000",
        "ctaBackgroundColor": "#007bff",
        "ctaTextColor": "#ffffff",
        "fontFamily": "Arial, sans-serif",
        "fontSize": "16px",
        "padding": "16px",
        "borderRadius": "4px"
      },
      "config": {
        "dismissible": true,
        "autoHide": false,
        "autoHideDelay": 5000,
        "animation": "fade",
        "closeButton": true
      }
    }
  }
]
Control which users see a banner based on their profile and behavior.
  • Segments: Restrict banners to specific customer segments defined in the dashboard.
  • Custom Rules: Write targeting rules against any customer attribute.
  • Toggle: Enable or disable targeting without deleting your rules.
Banners with targeting enabled are only returned by getBanners() if the identified user matches the criteria.
Define exactly when a banner is active.
  • Start / End Dates: Set a date range for the campaign.
  • Active Hours: Limit display to specific hours of the day.
  • Active Days: Limit display to specific days of the week.
  • Timezone: All schedule calculations respect a configurable timezone.
Prevent banner fatigue by limiting how many times a user sees a banner.
  • Max Displays: The total number of times the banner can be shown to a single user.
  • Period: The cap resets on a session, hour, day, week, or month cadence.
  • Toggle: Disable frequency capping for always-on banners.
Run experiments to find the most effective banner variant.
  • Multiple Variants: Create as many variants as you need per banner.
  • Traffic Allocation: Set the percentage of traffic each variant receives.
  • Automatic Assignment: Variant assignment is deterministic based on customer ID, so a user always sees the same variant.
  • Analytics: Views, clicks, dismissals, conversions, and CTR are tracked per variant automatically.

API Reference

MethodParametersReturnsDescription
getBanners(selector, options?)selector: string, options.autoRender?: boolean, options.forceRefresh?: booleanPromise<Banner[]>Fetch and optionally render banners for a placement. Pass forceRefresh: true to bypass the local cache.
banners.display(bannerId, variantId, selector)string, string, stringPromise<string>Track a banner display; returns displayId
banners.click(bannerId, displayId)string, stringPromise<void>Track a banner click
banners.dismiss(bannerId, displayId)string, stringPromise<void>Track a banner dismissal
Always call identify() before getBanners(). Without an identified user, the SDK cannot evaluate targeting rules or apply frequency caps.