@tappd/web-sdk
v1.0.0
Published
Tappd Web SDK for customer data collection and content delivery
Maintainers
Readme
Tappd Web SDK
Customer Data Platform SDK for web applications. Track user behavior, sessions, page visits, and custom events with automatic session management and anonymous user tracking.
Features
✅ Automatic Session Management - Hybrid approach with browser and time-based sessions
✅ Anonymous User Tracking - Track users before identification, automatically merge data
✅ Auto Page View Tracking - Automatic page visit tracking with SPA support
✅ Manual Event Tracking - Track custom events throughout your application
✅ Auto-Capture - Optional automatic click and form tracking
✅ Comprehensive Device Info - Browser, OS, screen, timezone, language tracking
✅ UTM Parameter Tracking - Automatic UTM parameter extraction
✅ Duration Tracking - Track time spent on pages
Installation
You can use the SDK via CDN (recommended for quick integration) or NPM (for build tools).
Option 1: CDN (Recommended for Quick Start)
Add this script tag to your HTML:
<!-- Load from CDN -->
<script src="https://cdn.tappd.io/web-sdk/v1/tappd-sdk.min.js"></script>
<script>
// SDK is now available as TappdSDK global variable
const tappd = new TappdSDK.TappdSDK({
appId: 'YOUR_APP_ID',
apiUrl: 'https://api.tappd.io/api/v1/sdk'
});
</script>Or load from your local server:
<script src="./path/to/tappd-sdk.min.js"></script>
<script>
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID'
});
</script>Option 2: NPM (For Build Tools)
npm install @tappd/web-sdkThen in your JavaScript:
// ES Module
import { TappdSDK } from '@tappd/web-sdk';
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
apiUrl: 'https://api.tappd.io/api/v1/sdk'
});
// CommonJS
const { TappdSDK } = require('@tappd/web-sdk');
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
apiUrl: 'https://api.tappd.io/api/v1/sdk'
});Quick Start
1. Get Your App ID
- Log into your Tappd dashboard
- Navigate to Settings > Apps
- Copy the App ID for your web app
2. Initialize the SDK
import TappdSDK from '@tappd/web-sdk';
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
apiUrl: 'https://sdk.gotappd.com/api/v1/sdk', // Optional
autoTrack: true, // Auto-track page views (default: true)
sessionTimeout: 30, // Session timeout in minutes (default: 30)
enableAutoCapture: false, // Auto-capture clicks/forms (default: false)
debug: false // Enable debug logging (default: false)
});3. Identify Users
// When user logs in or signs up
await tappd.identify('user_123', {
name: 'John Doe',
email: '[email protected]',
phone: '+1234567890',
external_id: 'ext_123',
// Custom attributes
age: 28,
plan: 'premium',
company: 'Acme Corp'
});4. Track Custom Events
We recommend using standard event names for consistency:
// Ecommerce events
await tappd.track('ecommerce.product_viewed', {
productId: 'prod_123',
productName: 'Pro Plan',
price: 99.99
});
await tappd.track('ecommerce.add_to_cart', {
productId: 'prod_123',
quantity: 1,
price: 99.99,
currency: 'USD'
});
await tappd.track('ecommerce.purchase', {
orderId: 'ord_123',
total: 99.99,
currency: 'USD',
items: [...]
});
// Web interaction events
await tappd.track('web.interaction.click', {
element: 'button',
text: 'Get Started',
location: 'hero'
});
await tappd.track('web.form.submitted', {
formId: 'contact-form',
formName: 'Contact Us',
success: true
});
// User events
await tappd.track('user.signup', {
method: 'email',
source: 'landing-page'
});Configuration
TappdConfig Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| appId | string | Required | Your App ID from the dashboard |
| apiUrl | string | https://sdk.gotappd.com/api/v1/sdk | Custom API URL |
| autoTrack | boolean | true | Auto-track page views |
| sessionTimeout | number | 30 | Session timeout in minutes |
| enableAutoCapture | boolean | false | Auto-capture clicks/forms |
| debug | boolean | false | Enable debug logging |
API Reference
Core Methods
identify(userId, attributes?)
Identify or update a customer. Automatically merges anonymous data if user was previously anonymous.
await tappd.identify('user_123', {
name: 'John Doe',
email: '[email protected]',
// Custom attributes
age: 28,
plan: 'premium'
});Returns: Promise<void>
track(eventName, properties?)
Track a custom event. We recommend using standard event names (see Standard Events).
// Using standard event names
await tappd.track('ecommerce.add_to_cart', {
productId: 'prod_123',
quantity: 1,
price: 99.99,
currency: 'USD'
});
// Or custom event names
await tappd.track('custom_event', {
customProperty: 'value'
});Returns: Promise<void>
trackPageView(url?, properties?)
Manually track a page view.
await tappd.trackPageView('https://example.com/pricing');Returns: Promise<void>
setExternalId(externalId)
Set the external ID for the current user.
await tappd.setExternalId('ext_user_123');Returns: Promise<void>
setUserAttributes(attributes)
Update user attributes.
await tappd.setUserAttributes({
plan: 'enterprise',
lastLogin: new Date()
});Returns: Promise<void>
setCustomAttributes(attributes)
Set custom user attributes.
await tappd.setCustomAttributes({
preferences: { theme: 'dark', language: 'en' }
});Returns: Promise<void>
Utility Methods
getSessionId()
Get the current session ID.
const sessionId = tappd.getSessionId();
console.log('Session ID:', sessionId);Returns: string | null
getAnonymousId()
Get the anonymous ID (persists across sessions).
const anonymousId = tappd.getAnonymousId();
console.log('Anonymous ID:', anonymousId);Returns: string
reset()
Reset the SDK state (clear user data, useful for logout).
tappd.reset();Returns: void
Session Management
How Sessions Work
The SDK uses a hybrid session approach:
- Browser-based: New session per browser tab/window (stored in
sessionStorage) - Time-based: Session expires after 30 minutes of inactivity (configurable)
Session Lifecycle
- Session Start: Automatically when SDK initializes
- Heartbeat: Every 30 seconds to keep session alive
- Session End: On page unload or after timeout
Manual Session Control
// Get current session ID
const sessionId = tappd.getSessionId();
// Sessions are managed automatically
// No manual start/end neededAnonymous User Tracking
How Anonymous Tracking Works
- First Visit: SDK generates an
anonymousIdand stores it inlocalStorage - Anonymous Tracking: All events, pages, and sessions are tracked with
anonymousId - Identification: When
identify()is called, all anonymous data is automatically merged - Data Persistence: Anonymous ID persists across browser sessions until identification
Example Flow
// User visits site (anonymous)
// SDK generates anonymousId and tracks page views, events
// Later, user logs in
await tappd.identify('user_123', {
email: '[email protected]',
name: 'John Doe'
});
// All previous anonymous data is now associated with user_123Page View Tracking
Automatic Tracking
Page views are automatically tracked when:
- SDK initializes on page load
- User navigates (SPA support via History API)
- Browser back/forward button is used
Manual Tracking
// Manually track a page view
await tappd.trackPageView('https://example.com/pricing');SPA Support
The SDK automatically tracks page views in Single Page Applications (SPAs) by:
- Overriding
history.pushState()andhistory.replaceState() - Listening for
popstateevents - Tracking browser back/forward navigation
Auto-Capture
Enable Auto-Capture
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
enableAutoCapture: true // Enable automatic event capture
});What Gets Auto-Captured
- Link Clicks: All
<a>tags clicked - Form Submissions: All form submissions
- Page Views: (Always enabled if
autoTrack: true)
Device Information
The SDK automatically collects comprehensive device information:
{
userAgent: "Mozilla/5.0...",
browser: { name: "Chrome", version: "120" },
os: { name: "macOS", version: "14.0" },
device: { type: "desktop" },
screenSize: { width: 1920, height: 1080, pixelRatio: 2 },
timezone: "America/New_York",
language: "en-US",
platform: "MacIntel",
connection: "4g"
}UTM Parameter Tracking
UTM parameters are automatically extracted from page URLs:
// If URL is: https://example.com?utm_source=google&utm_medium=cpc&utm_campaign=summer
// SDK automatically extracts:
{
source: "google",
medium: "cpc",
campaign: "summer"
}Standard Events
We've pre-defined standard event names for common use cases. These are automatically available in your workspace:
Web Events
| Event Name | Description | Properties |
|------------|-------------|------------|
| web.pageView | User viewed a page | page, title, referrer |
| web.interaction.click | User clicked an element | element, text, location |
| web.form.viewed | User viewed a form | formId, formName |
| web.form.started | User started filling a form | formId, formName |
| web.form.filled | User filled out a form | formId, formName, fields |
| web.form.submitted | User submitted a form | formId, formName, success |
Ecommerce Events
| Event Name | Description | Required Properties |
|------------|-------------|---------------------|
| ecommerce.product_viewed | User viewed a product | productId |
| ecommerce.add_to_cart | User added to cart | productId |
| ecommerce.remove_from_cart | User removed from cart | productId |
| ecommerce.checkout_started | User started checkout | - |
| ecommerce.checkout_step_completed | User completed checkout step | step |
| ecommerce.purchase | User completed purchase | orderId, total, currency |
User Events
| Event Name | Description | Properties |
|------------|-------------|------------|
| user.signup | User signed up | method, source |
| user.login | User logged in | method |
| user.logout | User logged out | - |
Usage
// Ecommerce example
await tappd.track('ecommerce.product_viewed', {
productId: 'prod_123',
productName: 'Pro Plan',
category: 'Subscription',
price: 99.99
});
// Web interaction example
await tappd.track('web.interaction.click', {
element: 'button',
text: 'Get Started',
location: 'hero'
});
// User event example
await tappd.track('user.signup', {
method: 'email',
source: 'landing-page'
});Note: You can still use custom event names (e.g., custom.event_name), but using standard names ensures consistency and better analytics.
Examples
Example 1: E-commerce Purchase
// Track product viewed
await tappd.track('ecommerce.product_viewed', {
productId: 'prod_123',
productName: 'iPhone 15',
price: 999,
category: 'Electronics'
});
// Track add to cart
await tappd.track('ecommerce.add_to_cart', {
productId: 'prod_123',
quantity: 1,
price: 999,
currency: 'USD'
});
// Track purchase
await tappd.track('ecommerce.purchase', {
orderId: 'order_456',
total: 999,
currency: 'USD',
items: [{ productId: 'prod_123', name: 'iPhone 15', price: 999, quantity: 1 }]
});Example 2: User Journey
// User visits site (anonymous)
// SDK automatically tracks page views
// User signs up
await tappd.identify('user_123', {
email: '[email protected]',
name: 'John Doe'
});
// All previous anonymous data is now linked to user_123
// Track signup event
await tappd.track('user.signup', {
source: 'homepage',
plan: 'free'
});
// User upgrades
await tappd.track('upgrade', {
from: 'free',
to: 'pro',
amount: 99
});
// Update user attributes
await tappd.setUserAttributes({
plan: 'pro',
upgradedAt: new Date()
});Example 3: SPA Integration
// Initialize in main app file
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
autoTrack: true // SPA navigation is automatically tracked
});
// In your router
router.onRouteChange = async (to) => {
// Optional: Manually track route change
await tappd.track('route_change', {
from: router.previousRoute,
to: to.path,
title: to.meta.title
});
};Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
Debugging
Enable debug logging to see SDK activity:
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
debug: true // Enable debug logging
});
// Check browser console for SDK logs
// [Tappd SDK] Initialized with App ID: a1b2c3d4...
// [Tappd SDK] Customer identified: user_123
// [Tappd SDK] Event tracked: button_clickAPI Endpoints
The SDK uses these API endpoints on https://sdk.gotappd.com/api/v1/sdk (automatically configured):
POST /identify # Identify user
POST /track # Track event
POST /page # Track page view
POST /session/start # Start session
POST /session/heartbeat # Session heartbeat
GET /in-app-messages # Get pending messages
POST /in-app-messages/:id/delivered # Mark message delivered
POST /in-app-messages/:id/dismiss # Dismiss message
GET /banners # Get eligible banners
POST /banners/:id/display # Track banner display
POST /banners/:id/click # Track banner click
POST /banners/:id/dismiss # Track banner dismiss
POST /bridge/action # Execute bridge action
POST /bridge/capture # Capture form data
GET /web-push/vapid-public-key # Get VAPID key
GET /web-push/subscription-status # Check push statusFor detailed endpoint documentation, see API_ENDPOINTS.md
---
## Data Privacy
- All data is sent securely via HTTPS
- Anonymous IDs are stored in browser localStorage
- Session IDs are stored in sessionStorage (cleared when browser closes)
- No sensitive data is stored in the SDK
- Comply with GDPR, CCPA, and other privacy regulations
---
## Troubleshooting
### SDK not tracking events
1. Check App ID is correct
2. Enable debug mode: `debug: true`
3. Check browser console for errors
4. Verify API endpoint is accessible
### Anonymous data not merging
1. Ensure `identify()` is called with the same `userId`
2. Check that `anonymousId` is passed during identification
3. Verify anonymous tracking happened before identification
### Session not starting
1. Check browser console for errors
2. Verify session initialization completed
3. Look for network errors in Network tab
---
---
## In-App Messages
The SDK supports displaying in-app messages (banners, popups, and modals) created in your Tappd dashboard. Messages are automatically fetched and displayed when enabled using **smart polling** that only polls when users are active.
### Configuration
```javascript
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
enableInAppMessages: true, // Enable in-app message rendering (default: true)
autoDisplayMessages: true, // Automatically display pending messages (default: true)
messagePollingInterval: 300, // Poll for new messages every 300 seconds (5 minutes) when active (default: 300)
inactivityThreshold: 300, // Stop polling after 300 seconds (5 minutes) of inactivity (default: 300)
messageContainerId: 'custom-container' // Optional: Custom DOM container ID
});Smart Polling Strategy
The SDK uses an intelligent polling strategy to minimize API calls and improve battery life:
- Always Fetch on Launch - Messages are fetched immediately when the SDK initializes or page loads
- Poll When Active - Polls for new messages every 5 minutes (configurable) when user is active
- Stop When Inactive - Automatically stops polling after 5 minutes (configurable) of user inactivity
- Resume on Activity - Immediately fetches messages and resumes polling when user becomes active again
- Local Caching - Messages are cached in localStorage for 5 minutes for offline support and faster display
Activity Detection:
- Tracks user interactions: clicks, scrolls, keyboard input, mouse movement, touch events
- Uses Page Visibility API to detect when page is hidden/visible
- Automatically stops polling when page is hidden or user is inactive
Automatic Display
When autoDisplayMessages is enabled, the SDK will:
- Fetch on launch - Immediately fetch messages when SDK initializes
- Load from cache - Display cached messages instantly (if available)
- Poll when active - Update messages every 5 minutes (configurable) when user is active
- Stop when inactive - Stop polling after 5 minutes (configurable) of inactivity
- Resume on return - Fetch immediately when user returns
- Evaluate trigger conditions
- Display messages that are ready to be shown
- Track message views and interactions
Manual Control
// Fetch pending messages
const messages = await tappd.getInAppMessages();
// Display a specific message
await tappd.displayInAppMessage(message);
// Display all pending messages
await tappd.displayPendingMessages();
// Dismiss a message
await tappd.dismissMessage(messageId);Message Types
The SDK supports three message types:
- Banner - Fixed position at top, bottom, or center of screen
- Popup - Centered modal with overlay (smaller size)
- Modal - Centered modal with overlay (larger size)
Message Blocks
Messages can contain multiple blocks:
- Image - Display images with alignment options
- Text - Text content with styling (font size, weight, color, alignment)
- Button - Clickable buttons with links and custom styling
- HTML - Raw HTML content (sanitized)
Event Tracking
The SDK automatically tracks message events:
message.viewed- When a message is displayedmessage.clicked- When a button in the message is clickedmessage.dismissed- When a message is dismissed
Example
// Initialize SDK with in-app messages
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
enableInAppMessages: true,
autoDisplayMessages: true
});
// Identify user (messages will be fetched automatically)
await tappd.identify({
external_id: 'user_123',
email: '[email protected]',
name: 'John Doe'
});
// Messages are now being fetched and displayed automatically
// You can also manually fetch and display:
const messages = await tappd.getInAppMessages();
await tappd.displayPendingMessages();License
MIT
Support
For issues and questions:
- GitHub Issues: https://github.com/tappd/web-sdk/issues
- Documentation: https://docs.tappd.io/web-sdk
- Email: [email protected]
