API Reference
Plugins

Plugins

The Experience SDK uses a plugin architecture powered by @lytics/sdk-kit (opens in a new tab). Plugins extend the runtime with additional capabilities.

Official Plugins

Banner Plugin

Renders banner experiences in the DOM with automatic positioning, theming, and responsive layout.

Configuration

import { createInstance } from '@prosdevlab/experience-sdk';
 
const experiences = createInstance({
  banner: {
    position: 'top',      // 'top' | 'bottom' (default: 'top')
    zIndex: 10000,        // Custom z-index (default: 10000)
    dismissable: true     // Allow dismissal (default: true)
  }
});

API Methods

banner.show(experience)

Manually show a banner experience.

experiences.banner.show({
  id: 'welcome',
  type: 'banner',
  targeting: {},
  content: {
    title: 'Welcome!',
    message: 'Thanks for visiting.',
    buttons: [
      { text: 'Get Started', url: '/start', variant: 'primary' }
    ]
  }
});
banner.remove(experienceId)

Remove a specific banner.

experiences.banner.remove('welcome');
banner.isShowing(experienceId?)

Check if a banner is currently showing.

// Check specific banner
if (experiences.banner.isShowing('welcome')) {
  console.log('Welcome banner is visible');
}
 
// Check if any banner is showing
if (experiences.banner.isShowing()) {
  console.log('A banner is visible');
}

Button Variants

Banners support multiple buttons with different visual styles:

buttons: [
  {
    text: 'Accept all',
    action: 'accept',
    variant: 'primary',     // Blue, prominent
    metadata: { consent: ['all'] }
  },
  {
    text: 'Reject',
    action: 'reject',
    variant: 'secondary',   // Gray, outlined
    metadata: { consent: [] }
  },
  {
    text: 'Preferences',
    action: 'preferences',
    variant: 'link',        // Text link style
    url: '/preferences'
  }
]

Variants:

  • primary - Blue button for main actions (default)
  • secondary - Gray outlined button for secondary actions
  • link - Text link style for tertiary actions

Responsive Layout

Banners automatically adapt to screen size:

  • Desktop (>640px): Buttons display inline horizontally
  • Mobile (≤640px): Buttons stack vertically for better touch interaction

Events

The banner plugin emits the following events:

experiences:shown

experiences.on('experiences:shown', ({ experienceId, type }) => {
  console.log(`${type} shown:`, experienceId);
});

experiences:action

experiences.on('experiences:action', ({ experienceId, action, variant, metadata, url }) => {
  console.log('Button clicked:', action, 'variant:', variant);
  if (metadata) {
    console.log('Metadata:', metadata);
  }
});

experiences:dismissed

experiences.on('experiences:dismissed', ({ experienceId }) => {
  console.log('Banner dismissed:', experienceId);
});

See Banner Examples for complete usage examples.

Customization

The Experience SDK focuses on targeting logic, not visual design. The banner plugin provides minimal, functional default styles that you can customize using CSS.

CSS Classes

The banner plugin uses the .xp-* namespace for all CSS classes:

  • .xp-banner - Main container
  • .xp-banner--top - Top positioned banner
  • .xp-banner--bottom - Bottom positioned banner
  • .xp-banner__container - Inner wrapper
  • .xp-banner__content - Content section
  • .xp-banner__title - Optional title
  • .xp-banner__message - Main message text
  • .xp-banner__buttons - Buttons container
  • .xp-banner__button - Individual button
  • .xp-banner__button--primary - Primary button variant
  • .xp-banner__button--secondary - Secondary button variant
  • .xp-banner__button--link - Link button variant
  • .xp-banner__close - Close button

Use Case 1: User with Tailwind

Add Tailwind classes via the className property:

experiences.register('flash-sale', {
  type: 'banner',
  content: {
    message: 'Flash Sale: 50% Off Everything!',
    className: 'bg-gradient-to-r from-blue-600 to-purple-600 text-white',
    buttons: [{
      text: 'Shop Now',
      url: '/shop',
      variant: 'primary',
      className: 'bg-white text-blue-600 hover:bg-gray-100'
    }]
  },
  targeting: { url: { contains: '/shop' } }
});

Use Case 2: User with Design System

Build your own plugin using your design system components:

import { MyBannerComponent } from '@your-org/design-system';
 
const myBannerPlugin: PluginFunction = (plugin, instance, config) => {
  instance.on('experiences:evaluated', ({ decision, experience }) => {
    if (decision.show && experience.type === 'banner') {
      // Render using your React component
      ReactDOM.render(
        <MyBannerComponent {...experience.content} />,
        document.getElementById('banner-root')
      );
    }
  });
};
 
experiences.use(myBannerPlugin);

Use Case 3: User with CSS Framework

Add Bootstrap, Material UI, or other framework classes:

experiences.register('alert', {
  type: 'banner',
  content: {
    message: 'Important notice',
    className: 'alert alert-warning',
    buttons: [{
      text: 'Learn More',
      className: 'btn btn-primary'
    }]
  },
  targeting: {}
});

Inline Styles

For quick overrides, use the style property:

content: {
  message: 'Flash Sale!',
  style: {
    background: 'linear-gradient(90deg, #667eea 0%, #764ba2 100%)',
    color: 'white',
    padding: '24px'
  }
}

Frequency Plugin

Manages impression tracking and frequency capping using persistent storage.

Configuration

const experiences = createInstance({
  frequency: {
    enabled: true,           // Enable frequency tracking (default: true)
    storage: 'local'         // 'local' | 'session' | 'memory' (default: 'local')
  }
});

Experience-Level Frequency

Define frequency caps per experience:

experiences.register('welcome', {
  type: 'banner',
  content: { message: 'Welcome!' },
  frequency: {
    max: 3,                 // Maximum impressions
    per: 'session'          // 'session' | 'day' | 'week'
  }
});

API Methods

frequency.getImpressionCount(experienceId, period?)

Get impression count for an experience.

const count = experiences.frequency.getImpressionCount('welcome', 'session');
console.log(`Shown ${count} times this session`);

Parameters:

  • experienceId: string - Experience to check
  • period?: 'session' | 'day' | 'week' - Time period (optional)

Returns: number

frequency.recordImpression(experienceId)

Manually record an impression.

experiences.frequency.recordImpression('welcome');
frequency.reset(experienceId?)

Reset impression counts.

// Reset specific experience
experiences.frequency.reset('welcome');
 
// Reset all experiences
experiences.frequency.reset();

How It Works

  1. Impressions are recorded when experiences:shown event is emitted
  2. Storage persists counts in localStorage (or sessionStorage/memory)
  3. Evaluation checks counts before showing experiences
  4. Dismissals do NOT count as impressions

Storage Keys

Frequency data is stored with namespaced keys:

experiences.frequency.session:welcome = 3
experiences.frequency.day:2024-12-25:welcome = 1
experiences.frequency.week:2024-W52:welcome = 5

Debug Plugin

Provides console logging and window event emission for debugging and Chrome extension integration.

Configuration

const experiences = createInstance({
  debug: {
    enabled: true,           // Enable debug output (default: false)
    windowEvents: true,      // Emit to window (default: true when enabled)
    prefix: 'experiences'    // Log prefix (default: 'experiences')
  }
});

Or use the shorthand:

const experiences = createInstance({ debug: true });

API Methods

debug.log(message, data?)

Log a message with optional data.

experiences.debug.log('User clicked button', { action: 'cta' });

Console output:

[experiences] User clicked button { action: 'cta' }

Window event:

window.addEventListener('experiences:debug', (event) => {
  console.log(event.detail);
  // { message: 'User clicked button', data: { action: 'cta' }, timestamp: ... }
});

Automatic Logging

When debug mode is enabled, the plugin automatically logs:

  • SDK initialization
  • Experience registration
  • Evaluation results
  • Decision reasons
  • Event emissions
const experiences = createInstance({ debug: true });
 
experiences.register('welcome', { ... });
// [experiences] Experience registered: welcome
 
const decision = experiences.evaluate();
// [experiences] Evaluating 1 experience(s)
// [experiences] Decision: show=true, experience=welcome
// [experiences] Reasons: ["✅ URL matches", "✅ Frequency: 0/3 this session"]

Chrome Extension Integration

The debug plugin emits events to window that can be captured by Chrome extensions:

// In Chrome extension content script
window.addEventListener('experiences:debug', (event) => {
  chrome.runtime.sendMessage({
    type: 'EXPERIENCE_DEBUG',
    payload: event.detail
  });
});

This enables building DevTools panels for inspecting experience decisions in real-time.


Plugin Development

The SDK uses @lytics/sdk-kit (opens in a new tab)'s plugin system. Custom plugins can be created using the PluginFunction interface:

import type { PluginFunction } from '@lytics/sdk-kit';
 
const myPlugin: PluginFunction = (plugin, instance, config) => {
  // Namespace
  plugin.ns('my.plugin');
  
  // Default config
  plugin.defaults({ myPlugin: { enabled: true } });
  
  // Expose API
  plugin.expose({
    myMethod() {
      console.log('Hello from plugin!');
    }
  });
  
  // Listen to events
  instance.on('experiences:evaluated', (decision) => {
    // React to evaluations
  });
};
 
// Use the plugin
const experiences = createInstance();
experiences.use(myPlugin);

See the sdk-kit documentation (opens in a new tab) for complete plugin development guide.


Next Steps