diff --git a/docs/campaign-cart/analytics/best-practices.md b/docs/campaign-cart/analytics/best-practices.md
new file mode 100644
index 00000000..7606eab6
--- /dev/null
+++ b/docs/campaign-cart/analytics/best-practices.md
@@ -0,0 +1,1149 @@
+---
+title: Best Practices
+description: Patterns and recommendations for implementing Campaign Cart analytics including configuration strategies, event naming conventions, tracking patterns, and optimization techniques.
+sidebar_position: 12
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+This guide covers patterns and recommendations for implementing Campaign Cart analytics across your application.
+
+## Configuration Best Practices
+
+### 1. Use Auto Mode
+
+Auto mode handles most tracking automatically:
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: {
+ enabled: true,
+ mode: 'auto' // Automatic tracking
+ }
+};
+```
+
+**Auto Mode Tracks:**
+- `dl_user_data` - Every page load
+- `dl_view_item_list` - Collection/category pages
+- `dl_add_to_cart` - Cart additions
+- `dl_begin_checkout` - Checkout initiation
+
+**Manual Tracking Required:**
+- Purchase events (order confirmation page)
+- Login/signup events
+- Custom business events
+
+### 2. Set storeName for Facebook Pixel
+
+The `storeName` parameter is required for Facebook Pixel purchase deduplication. Without it, duplicate purchases may be reported:
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ storeName: 'my-store', // Required for Facebook deduplication
+ analytics: {
+ enabled: true,
+ providers: {
+ facebook: {
+ enabled: true,
+ settings: { pixelId: 'YOUR_PIXEL_ID' }
+ }
+ }
+ }
+};
+```
+
+Use a consistent, unique store identifier across all environments to prevent duplicate purchase attribution in Facebook Ads Manager.
+
+### 3. Use Debug Mode in Development
+
+Enable debug mode only during development to see detailed console logs without polluting production data:
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: {
+ enabled: true,
+ debug: process.env.NODE_ENV === 'development' // Enable only in dev
+ }
+};
+```
+
+**Debug Mode Shows:**
+- Event names and data
+- Provider routing decisions
+- Validation errors
+- Transform function results
+
+### 4. Environment-Specific Configuration
+
+Use environment variables to manage different configurations across environments:
+
+```javascript
+window.nextConfig = {
+ apiKey: process.env.REACT_APP_API_KEY,
+ analytics: {
+ enabled: process.env.REACT_APP_ANALYTICS_ENABLED === 'true',
+ debug: process.env.NODE_ENV === 'development',
+ mode: 'auto',
+ providers: {
+ gtm: { enabled: true },
+ facebook: {
+ enabled: true,
+ settings: { pixelId: process.env.REACT_APP_FACEBOOK_PIXEL_ID }
+ }
+ }
+ }
+};
+```
+
+## Event Naming Conventions
+
+### Use Consistent snake_case Format
+
+Adopt a consistent naming convention across all custom events. Use snake_case (lowercase with underscores):
+
+```javascript
+// Good - Consistent snake_case
+'newsletter_subscribe'
+'video_completed'
+'form_submitted'
+'feature_enabled'
+'product_reviewed'
+'wishlist_added'
+
+// Avoid - Inconsistent formats
+'subscribeNewsletter' // camelCase
+'VideoCompleted' // PascalCase
+'form-submitted' // kebab-case
+'FEATURE_ENABLED' // UPPER_CASE
+```
+
+### Naming Patterns by Category
+
+Follow these naming patterns to make event names self-documenting:
+
+
+
+
+```javascript
+// Format: [verb]_[noun]
+'newsletter_subscribe'
+'video_play'
+'form_submit'
+'product_add'
+'account_create'
+'payment_process'
+```
+
+
+
+
+```javascript
+// Format: [noun]_[status]
+'video_started'
+'video_completed'
+'download_finished'
+'upload_error'
+'sync_failed'
+```
+
+
+
+
+```javascript
+// Format: [noun]_[verb]_[context]
+'product_view_search'
+'product_add_recommendation'
+'video_complete_onboarding'
+'form_submit_footer'
+'checkout_error_payment'
+```
+
+
+
+
+## Tracking Patterns
+
+### 1. Track Purchase Events ASAP
+
+Track purchase events on the order confirmation page immediately when the page loads, before users navigate away:
+
+```javascript
+// On order confirmation page
+window.addEventListener('DOMContentLoaded', () => {
+ // Get order data from page or API
+ const orderData = window.__ORDER_DATA__ || getOrderFromAPI();
+
+ if (orderData) {
+ // Track immediately
+ next.trackPurchase({
+ id: orderData.orderId,
+ total: orderData.total,
+ currency: orderData.currency,
+ items: orderData.items
+ });
+ }
+});
+```
+
+Users often navigate away quickly. Track immediately to capture the event before they leave.
+
+### 2. Track Before Navigation
+
+For events that might cause navigation, track before the navigation occurs:
+
+```javascript
+// Bad - Event might not send before navigation
+document.getElementById('checkout-btn').addEventListener('click', () => {
+ next.trackBeginCheckout();
+ window.location.href = '/checkout'; // May interrupt tracking
+});
+
+// Good - Track with callback
+document.getElementById('checkout-btn').addEventListener('click', (e) => {
+ e.preventDefault();
+ next.trackBeginCheckout();
+ // Give the event time to send
+ setTimeout(() => {
+ window.location.href = '/checkout';
+ }, 100);
+});
+
+// Better - Use async tracking
+document.getElementById('checkout-btn').addEventListener('click', async (e) => {
+ e.preventDefault();
+ await window.NextAnalytics.trackAsync({
+ event: 'checkout_initiated',
+ from_page: window.location.pathname
+ });
+ window.location.href = '/checkout';
+});
+```
+
+### 3. Include Context in Events
+
+Provide context data with custom events:
+
+```javascript
+// Good - With context
+window.NextAnalytics.track({
+ event: 'video_completed',
+ video_id: 'intro-video',
+ video_title: 'Product Introduction',
+ video_duration: 120,
+ video_category: 'onboarding',
+ user_watched_percent: 100,
+ completion_time_seconds: 118,
+ playback_quality: '720p'
+});
+
+// Avoid - Minimal context
+window.NextAnalytics.track({
+ event: 'video_completed'
+ // Missing critical context
+});
+```
+
+### 4. Track User Journey Flows
+
+For multi-step flows, track key checkpoints using consistent flow IDs:
+
+```javascript
+// Generate a unique flow ID
+const flowId = generateUUID();
+
+// Track flow start
+window.NextAnalytics.track({
+ event: 'checkout_flow_started',
+ flow_id: flowId,
+ entry_point: 'cart_page',
+ cart_value: cartTotal,
+ item_count: cartItems.length
+});
+
+// Track each step
+window.NextAnalytics.track({
+ event: 'checkout_step_completed',
+ flow_id: flowId,
+ step: 'shipping_info',
+ step_number: 1,
+ duration_ms: Date.now() - stepStartTime
+});
+
+// Track completion or abandonment
+window.NextAnalytics.track({
+ event: 'checkout_flow_completed',
+ flow_id: flowId,
+ steps_completed: 4,
+ total_duration_ms: Date.now() - flowStartTime,
+ conversion: true
+});
+```
+
+### 5. Track Errors and Edge Cases
+
+Capture error events for debugging and monitoring:
+
+```javascript
+// Track checkout errors
+window.NextAnalytics.track({
+ event: 'checkout_error',
+ error_code: 'PAYMENT_DECLINED',
+ error_message: 'Your card was declined',
+ step: 'payment_processing',
+ attempted_amount: 99.99
+});
+
+// Track form validation failures
+window.NextAnalytics.track({
+ event: 'form_validation_error',
+ form_id: 'contact_form',
+ field_errors: ['email', 'phone'],
+ error_count: 2
+});
+
+// Track API failures
+window.NextAnalytics.track({
+ event: 'api_call_failed',
+ endpoint: '/api/orders',
+ status_code: 500,
+ retry_attempt: 1,
+ error_type: 'server_error'
+});
+```
+
+## Error Handling
+
+### Wrap Tracking in Try-Catch Blocks
+
+Never let analytics errors break your application functionality:
+
+```javascript
+function trackAnalyticsEvent(eventName, eventData) {
+ try {
+ window.NextAnalytics.track({
+ event: eventName,
+ ...eventData
+ });
+ } catch (error) {
+ // Log the error for monitoring
+ console.error('Analytics tracking failed:', {
+ event: eventName,
+ error: error.message,
+ stack: error.stack
+ });
+
+ // Don't re-throw - continue with app functionality
+ // Consider sending to error tracking service
+ if (window.errorReporter) {
+ window.errorReporter.captureException(error);
+ }
+ }
+}
+
+// Usage
+trackAnalyticsEvent('form_submitted', {
+ form_id: 'contact',
+ fields_count: 5
+});
+```
+
+### Implement Graceful Degradation
+
+Ensure the app works even if analytics fails:
+
+```javascript
+// Wrap the entire initialization
+try {
+ window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: { enabled: true }
+ };
+} catch (error) {
+ console.warn('Analytics initialization failed:', error);
+ // App continues to work without analytics
+}
+
+// For critical tracking, use a wrapper
+async function trackPurchaseWithFallback(orderData) {
+ try {
+ await window.NextAnalytics.trackAsync({
+ event: 'purchase',
+ ...orderData
+ });
+ } catch (error) {
+ console.error('Failed to track purchase:', error);
+
+ // Fallback: Send to error service
+ if (window.errorReporter) {
+ window.errorReporter.captureException(error, {
+ tags: { event: 'purchase_tracking_failed' },
+ extra: { orderData }
+ });
+ }
+ }
+}
+```
+
+## Performance Optimization
+
+### 1. Batch Events
+
+For multiple events in quick succession, batch them together:
+
+```javascript
+// Avoid - Multiple individual calls
+items.forEach(item => {
+ window.NextAnalytics.track({
+ event: 'item_viewed',
+ item_id: item.id
+ });
+});
+
+// Better - Batch in a single event
+window.NextAnalytics.track({
+ event: 'items_batch_viewed',
+ items: items.map(item => ({
+ item_id: item.id,
+ item_title: item.title
+ })),
+ batch_size: items.length,
+ timestamp: Date.now()
+});
+```
+
+### 2. Lazy Load Analytics
+
+For non-critical tracking, defer analytics initialization:
+
+```javascript
+// Defer analytics to idle time
+if ('requestIdleCallback' in window) {
+ requestIdleCallback(() => {
+ initializeAnalytics();
+ });
+} else {
+ // Fallback for browsers without requestIdleCallback
+ setTimeout(initializeAnalytics, 2000);
+}
+
+function initializeAnalytics() {
+ window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: { enabled: true }
+ };
+}
+```
+
+### 3. Use Appropriate API Based on Timing
+
+Choose the API that matches your timing needs:
+
+```javascript
+// Immediate tracking (synchronous)
+next.trackAddToCart('item-123', 1);
+
+// For critical events that must complete
+await window.NextAnalytics.trackAsync({
+ event: 'purchase_confirmation',
+ order_id: 'ORD-12345'
+});
+
+// For background tracking
+window.NextAnalytics.track({
+ event: 'page_interaction',
+ interaction_type: 'scroll'
+ // Fires in background, doesn't block
+});
+```
+
+### 4. Debounce Frequent Events
+
+For high-frequency events, debounce to reduce overhead:
+
+```javascript
+// Debounce scroll tracking
+let scrollTimeout;
+window.addEventListener('scroll', () => {
+ clearTimeout(scrollTimeout);
+ scrollTimeout = setTimeout(() => {
+ window.NextAnalytics.track({
+ event: 'page_scrolled',
+ scroll_depth: (window.scrollY / document.body.scrollHeight) * 100
+ });
+ }, 1000); // Track once per second max
+});
+
+// Debounce resize events
+let resizeTimeout;
+window.addEventListener('resize', () => {
+ clearTimeout(resizeTimeout);
+ resizeTimeout = setTimeout(() => {
+ window.NextAnalytics.track({
+ event: 'viewport_changed',
+ width: window.innerWidth,
+ height: window.innerHeight
+ });
+ }, 500);
+});
+```
+
+## Custom Events Best Practices
+
+### 1. Use EventBuilder for E-commerce Events
+
+Use EventBuilder for e-commerce events to ensure GA4 compliance:
+
+```javascript
+import { EventBuilder, dataLayer } from '@/utils/analytics';
+
+// Track wishlist addition
+const item = {
+ id: 'pkg-123',
+ title: 'Premium Package',
+ price: 99.99,
+ category: 'packages'
+};
+
+const event = EventBuilder.createEvent('wishlist_add', {
+ ecommerce: {
+ currency: EventBuilder.getCurrency(),
+ items: [EventBuilder.formatEcommerceItem(item, 0)]
+ }
+});
+
+dataLayer.push(event);
+```
+
+### 2. Use Transform Functions for Data Enrichment
+
+Enrich events globally without modifying every tracking call:
+
+```javascript
+import { dataLayer } from '@/utils/analytics';
+
+// Add context to all events
+dataLayer.setTransformFunction((event) => {
+ // Add app metadata
+ event.app_version = window.APP_VERSION;
+ event.environment = window.ENV;
+
+ // Add user context
+ if (window.currentUser) {
+ event.user_id = window.currentUser.id;
+ event.user_tier = window.currentUser.tier;
+ }
+
+ // Add session data
+ event.session_duration = Date.now() - window.sessionStartTime;
+
+ return event;
+});
+```
+
+### 3. Filter Events Strategically
+
+Use transform functions to filter out unwanted events:
+
+```javascript
+dataLayer.setTransformFunction((event) => {
+ // Filter out internal events in production
+ const internalEvents = ['internal_test', 'dev_event'];
+ if (internalEvents.includes(event.event) && window.ENV === 'production') {
+ return null; // Event won't be sent
+ }
+
+ // Filter test users
+ if (event.user_properties?.customer_email?.includes('@test.com')) {
+ return null;
+ }
+
+ return event;
+});
+```
+
+### 4. Validate Events in Development
+
+Enable event validation to catch issues early:
+
+```javascript
+if (process.env.NODE_ENV === 'development') {
+ import { EventValidator } from '@/utils/analytics';
+
+ const validator = new EventValidator(true);
+
+ // Create a wrapper function
+ const trackWithValidation = (eventName, eventData) => {
+ const event = {
+ event: eventName,
+ ...eventData
+ };
+
+ // Validate before tracking
+ const result = validator.validateEvent(event);
+ if (!result.valid) {
+ console.error('Invalid event:', {
+ event: eventName,
+ errors: result.errors,
+ data: eventData
+ });
+ return; // Don't send invalid events
+ }
+
+ window.NextAnalytics.track(event);
+ };
+
+ // Use throughout app
+ window.trackWithValidation = trackWithValidation;
+}
+```
+
+## Provider-Specific Best Practices
+
+### Google Tag Manager
+
+
+
+
+```javascript
+window.nextConfig = {
+ analytics: {
+ providers: {
+ gtm: {
+ enabled: true
+ // Optional: custom settings
+ }
+ }
+ }
+};
+```
+
+
+
+
+1. **Test in GTM Preview Mode**: Always test events in GTM's preview mode before publishing containers.
+
+```javascript
+// Verify GTM is loading
+console.log('GTM ready:', typeof dataLayer !== 'undefined');
+
+// Check event in Preview
+window.NextAnalytics.track({
+ event: 'test_event',
+ timestamp: new Date().toISOString()
+});
+```
+
+2. **Use GTM's Debug View**: Enable GTM's Real-time Debug View in Google Analytics for verification.
+
+3. **Version Control Containers**: Use GTM's version history feature to manage changes.
+
+
+
+
+### Facebook Pixel
+
+
+
+
+```javascript
+window.nextConfig = {
+ storeName: 'my-store', // Critical for deduplication
+ analytics: {
+ providers: {
+ facebook: {
+ enabled: true,
+ settings: {
+ pixelId: 'YOUR_PIXEL_ID'
+ }
+ }
+ }
+ }
+};
+```
+
+
+
+
+1. **Set storeName**: Required for purchase deduplication across web and app.
+
+```javascript
+window.nextConfig = {
+ storeName: 'consistent-store-name', // Use same name in app SDK
+ analytics: { ... }
+};
+```
+
+2. **Track Purchase Immediately**: Track purchases on confirmation page before navigation.
+
+```javascript
+window.addEventListener('DOMContentLoaded', () => {
+ next.trackPurchase(orderData);
+});
+```
+
+3. **Use Correct Currency**: Ensure currency matches your Facebook Ads account settings.
+
+```javascript
+window.nextConfig = {
+ currency: 'USD', // Match your ad account currency
+ analytics: { ... }
+};
+```
+
+4. **Verify in Pixel Helper**: Use Facebook's Pixel Helper browser extension to verify events.
+
+
+
+
+### RudderStack
+
+
+
+
+```javascript
+window.nextConfig = {
+ analytics: {
+ providers: {
+ rudderstack: {
+ enabled: true,
+ settings: {
+ writeKey: 'YOUR_WRITE_KEY',
+ dataPlaneURL: 'https://your-dataplane.rudderstack.com'
+ }
+ }
+ }
+ }
+};
+```
+
+
+
+
+1. **Identify Users**: Set user context for better tracking.
+
+```javascript
+// After login
+window.NextAnalytics.setUserProperties({
+ user_id: user.id,
+ email: user.email,
+ name: user.name,
+ plan: user.plan
+});
+```
+
+2. **Use Traits**: Attach user traits for segmentation.
+
+```javascript
+window.NextAnalytics.track({
+ event: 'feature_used',
+ feature: 'advanced_search',
+ traits: {
+ plan: 'premium',
+ company: 'acme-corp'
+ }
+});
+```
+
+3. **Monitor Transformations**: Use RudderStack's transformations for event routing.
+
+
+
+
+### Custom Webhooks
+
+
+
+
+```javascript
+window.nextConfig = {
+ analytics: {
+ providers: {
+ custom: {
+ enabled: true,
+ settings: {
+ endpoint: 'https://api.yourapp.com/events',
+ batchSize: 10,
+ flushInterval: 5000
+ }
+ }
+ }
+ }
+};
+```
+
+
+
+
+1. **Implement Retry Logic**: Handle failed requests gracefully.
+
+```javascript
+// Server-side webhook handler
+app.post('/events', async (req, res) => {
+ const events = req.body.events;
+
+ try {
+ await processEvents(events);
+ res.json({ success: true, processedCount: events.length });
+ } catch (error) {
+ // Client will retry
+ res.status(500).json({ error: 'Processing failed' });
+ }
+});
+```
+
+2. **Validate Signatures**: Verify webhook authenticity if sensitive.
+
+```javascript
+// Client-side: Add signature to webhook
+const crypto = require('crypto');
+const signature = crypto
+ .createHmac('sha256', SECRET_KEY)
+ .update(JSON.stringify(events))
+ .digest('hex');
+
+// Include in request headers
+```
+
+3. **Handle Batch Events**: Custom webhooks receive batched events for efficiency.
+
+```javascript
+// Webhook receives multiple events
+{
+ "events": [
+ { "event": "view_item", ... },
+ { "event": "add_to_cart", ... },
+ { "event": "begin_checkout", ... }
+ ]
+}
+```
+
+
+
+
+## Testing Strategies
+
+### 1. Development Testing Checklist
+
+Use this checklist when testing analytics implementation:
+
+```javascript
+// 1. Verify initialization
+console.assert(
+ typeof window.NextAnalytics !== 'undefined',
+ 'NextAnalytics not initialized'
+);
+
+// 2. Check debug mode
+window.NextAnalytics.setDebugMode(true);
+
+// 3. Test simple event
+window.NextAnalytics.track({
+ event: 'test_event',
+ timestamp: new Date().toISOString()
+});
+
+// 4. Test add to cart
+next.trackAddToCart('test-item', 1);
+
+// 5. Test begin checkout
+next.trackBeginCheckout();
+
+// 6. Verify in console
+const status = window.NextAnalytics.getStatus();
+console.log('Analytics status:', status);
+```
+
+### 2. Browser Console Testing
+
+Monitor events in real-time using the browser console:
+
+```javascript
+// Enable debug mode
+window.NextAnalytics.setDebugMode(true);
+
+// Monitor all events
+window.addEventListener('NextAnalyticsEvent', (event) => {
+ console.log('Event tracked:', event.detail);
+});
+
+// Check data layer
+console.log('Data layer:', window.NextDataLayer);
+
+// Verify provider routing
+const status = window.NextAnalytics.getStatus();
+console.table(status.providers);
+```
+
+### 3. Testing Purchase Flow
+
+Test the complete purchase flow:
+
+```javascript
+// Simulate checkout initiation
+window.addEventListener('DOMContentLoaded', () => {
+ // Step 1: View items
+ next.trackViewItem('item-1');
+ next.trackViewItem('item-2');
+
+ // Step 2: Add to cart
+ next.trackAddToCart('item-1', 1);
+ next.trackAddToCart('item-2', 2);
+
+ // Step 3: Begin checkout
+ next.trackBeginCheckout();
+
+ // Step 4: Track purchase
+ next.trackPurchase({
+ id: 'ORDER_' + Date.now(),
+ total: 199.99,
+ currency: 'USD',
+ items: [
+ { id: 'item-1', title: 'Item 1', price: 99.99 },
+ { id: 'item-2', title: 'Item 2', price: 100.00 }
+ ]
+ });
+});
+```
+
+### 4. Error Scenario Testing
+
+Test error handling:
+
+```javascript
+// Test error tracking
+window.NextAnalytics.track({
+ event: 'payment_error',
+ error_code: 'CARD_DECLINED',
+ error_message: 'Your card was declined',
+ attempted_amount: 99.99
+});
+
+// Test recovery
+window.NextAnalytics.track({
+ event: 'payment_retry',
+ retry_attempt: 2,
+ original_error: 'CARD_DECLINED'
+});
+
+// Verify error is tracked but doesn't break app
+console.assert(
+ document.body !== null,
+ 'App broken after tracking error'
+);
+```
+
+## Production Checklist
+
+Before deploying analytics to production, verify:
+
+
+
+
+- [ ] Analytics enabled in production config
+- [ ] Debug mode disabled (set based on environment)
+- [ ] storeName set for Facebook Pixel
+- [ ] All required API keys configured via environment variables
+- [ ] Mode set to 'auto' (unless specific reason for manual)
+- [ ] All required providers enabled
+- [ ] Custom webhook endpoints verified if using custom provider
+
+
+
+
+- [ ] All purchase tracking implemented on confirmation page
+- [ ] All custom events use consistent snake_case naming
+- [ ] Error handling wrapped around all tracking calls
+- [ ] Critical events (purchase, signup) have error handling
+- [ ] Transform functions added for data enrichment
+- [ ] Event validation enabled in development
+- [ ] No PII tracked (emails, phone numbers) in non-critical events
+
+
+
+
+- [ ] Tested with GTM Debug View (if using GTM)
+- [ ] Tested with Facebook Pixel Helper (if using Facebook)
+- [ ] Verified purchase events on test transaction
+- [ ] Verified custom events in GA4 Real-time Report
+- [ ] Tested error scenarios (failed payment, form errors)
+- [ ] Verified browser console has no analytics errors
+- [ ] Cross-browser testing completed
+- [ ] Mobile testing completed
+
+
+
+
+- [ ] Set up alerting for tracking failures
+- [ ] Monitor event delivery rates
+- [ ] Check for unexpected event spikes
+- [ ] Review GA4 real-time dashboard for first 24 hours
+- [ ] Verify revenue data matches internal records
+- [ ] Monitor error event rates
+- [ ] Set up weekly data quality checks
+
+
+
+
+- [ ] Document all custom events and their parameters
+- [ ] Document any event transform functions
+- [ ] Document custom webhook endpoint schema
+- [ ] Document any environment-specific configuration
+- [ ] Create runbook for disabling analytics if needed
+- [ ] Document provider credentials location
+- [ ] Keep change log of analytics modifications
+
+
+
+
+## Common Patterns and Examples
+
+### User Journey Tracking
+
+Track complete user flows with contextual data:
+
+```javascript
+class UserJourneyTracker {
+ constructor() {
+ this.journeyId = this.generateId();
+ this.events = [];
+ this.startTime = Date.now();
+ }
+
+ generateId() {
+ return `journey_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+ }
+
+ trackStep(stepName, stepData = {}) {
+ const eventData = {
+ event: `journey_${stepName}`,
+ journey_id: this.journeyId,
+ step_timestamp: Date.now(),
+ elapsed_time: Date.now() - this.startTime,
+ ...stepData
+ };
+
+ window.NextAnalytics.track(eventData);
+ this.events.push(eventData);
+ }
+
+ complete(metadata = {}) {
+ this.trackStep('completed', {
+ total_duration: Date.now() - this.startTime,
+ total_events: this.events.length,
+ ...metadata
+ });
+ }
+
+ abandon(reason, metadata = {}) {
+ this.trackStep('abandoned', {
+ abandon_reason: reason,
+ last_step: this.events[this.events.length - 1]?.event,
+ ...metadata
+ });
+ }
+}
+
+// Usage
+const journey = new UserJourneyTracker();
+journey.trackStep('initiated', { entry_point: 'homepage' });
+journey.trackStep('browsing', { category_viewed: 'premium-packages' });
+journey.trackStep('added_to_cart', { product_id: 'pkg-123' });
+journey.complete({ conversion: true });
+```
+
+### Feature Flag Analytics
+
+Track feature flag usage:
+
+```javascript
+function trackFeatureUsage(featureName, enabled, metadata = {}) {
+ window.NextAnalytics.track({
+ event: 'feature_flag_evaluated',
+ feature_name: featureName,
+ enabled: enabled,
+ timestamp: Date.now(),
+ ...metadata
+ });
+}
+
+// Usage
+if (shouldEnableNewCheckout()) {
+ trackFeatureUsage('new_checkout_ui', true, {
+ variant: 'experimental',
+ user_segment: 'premium'
+ });
+ renderNewCheckout();
+} else {
+ trackFeatureUsage('new_checkout_ui', false, {
+ reason: 'user_segment_not_matched'
+ });
+ renderLegacyCheckout();
+}
+```
+
+### Conversion Funnel Tracking
+
+Track conversion funnel steps:
+
+```javascript
+class FunnelTracker {
+ constructor(funnelName) {
+ this.funnelName = funnelName;
+ this.funnelId = `funnel_${Date.now()}`;
+ this.steps = [];
+ }
+
+ trackStep(stepName, stepNumber, metadata = {}) {
+ const event = {
+ event: `funnel_step`,
+ funnel_name: this.funnelName,
+ funnel_id: this.funnelId,
+ step_name: stepName,
+ step_number: stepNumber,
+ steps_completed: stepNumber,
+ ...metadata
+ };
+
+ window.NextAnalytics.track(event);
+ this.steps.push(event);
+ }
+
+ trackDropoff(stepName, stepNumber, reason, metadata = {}) {
+ window.NextAnalytics.track({
+ event: `funnel_dropoff`,
+ funnel_name: this.funnelName,
+ funnel_id: this.funnelId,
+ dropped_at_step: stepName,
+ step_number: stepNumber,
+ dropoff_reason: reason,
+ steps_completed: stepNumber - 1,
+ ...metadata
+ });
+ }
+}
+
+// Usage
+const checkoutFunnel = new FunnelTracker('checkout');
+checkoutFunnel.trackStep('shipping', 1, { state_entered: 'CA' });
+checkoutFunnel.trackStep('payment', 2, { payment_method: 'credit_card' });
+checkoutFunnel.trackDropoff('confirmation', 3, 'payment_failed', {
+ error_code: 'CARD_DECLINED'
+});
+```
+
+## Summary
+
+Following these practices:
+- Events reach their destinations consistently
+- Events contain context for analysis
+- Analytics doesn't slow down your application
+- Consistent patterns make code easier to understand
+- Error handling and configuration provide stable systems
+
+Review this guide regularly and update your implementation as needed.
diff --git a/docs/campaign-cart/analytics/configuration.md b/docs/campaign-cart/analytics/configuration.md
new file mode 100644
index 00000000..c6831142
--- /dev/null
+++ b/docs/campaign-cart/analytics/configuration.md
@@ -0,0 +1,510 @@
+---
+title: Configuration & Modes
+description: Complete analytics configuration reference including tracking modes, provider settings, and runtime options.
+sidebar_position: 2
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+Configure the analytics system through `window.nextConfig` to control tracking behavior, enable providers, and set operational modes.
+
+## Basic Configuration
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ storeName: 'my-store', // Important for Facebook deduplication
+ analytics: {
+ enabled: true,
+ debug: false,
+ mode: 'auto',
+ providers: {
+ gtm: { enabled: true },
+ facebook: {
+ enabled: true,
+ settings: { pixelId: 'YOUR_PIXEL_ID' }
+ },
+ rudderstack: { enabled: true },
+ custom: {
+ enabled: true,
+ settings: { endpoint: 'https://api.yourapp.com/analytics' }
+ }
+ }
+ }
+};
+```
+
+## Configuration Options
+
+### Top-Level Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `enabled` | boolean | `false` | Master switch for all analytics tracking |
+| `debug` | boolean | `false` | Enable detailed console logging for troubleshooting |
+| `mode` | string | `'auto'` | Tracking mode: `'auto'` or `'manual'` |
+| `providers` | object | `{}` | Provider configurations (GTM, Facebook, RudderStack, custom) |
+
+### Store-Level Options
+
+| Option | Type | Description |
+|--------|------|-------------|
+| `storeName` | string | **Required for Facebook Pixel** - Used for purchase deduplication |
+
+## Tracking Modes
+
+### Auto Mode (Recommended)
+
+Auto mode automatically tracks common e-commerce events without manual intervention.
+
+```javascript
+analytics: {
+ mode: 'auto'
+}
+```
+
+**Automatically tracked events:**
+
+| Event | When | Trigger |
+|------|------|---------|
+| `dl_user_data` | First event on page load | Analytics initialization in auto mode |
+| `dl_view_item_list` | Page load or when products are detected | ViewItemListTracker scans for elements with `data-next-package-id` |
+| `dl_view_item` | Single product view | When only one product is detected on page (via ViewItemListTracker) |
+| `dl_add_to_cart` | Item added to cart | `cart:item-added` SDK event (auto-tracked via AutoEventListener) |
+| `dl_remove_from_cart` | Item removed from cart | `cart:item-removed` SDK event (auto-tracked via AutoEventListener) |
+| `dl_begin_checkout` | Checkout form initializes | CheckoutFormEnhancer detects checkout form and cart has items |
+| `dl_add_shipping_info` | Shipping form submission | Shipping information entered |
+| `dl_add_payment_info` | Payment form submission | After all credit card fields are valid and complete or when the express checkout button is clicked |
+| `dl_purchase` | Order completed | `order:completed` SDK event (auto-tracked via AutoEventListener) |
+| `dl_viewed_upsell` | Upsell offer displayed | `upsell:viewed` SDK event (auto-tracked) |
+| `dl_accepted_upsell` | User accepts upsell | `upsell:accepted` or `upsell:added` SDK events (auto-tracked) |
+
+**Events requiring manual tracking:**
+- `dl_sign_up` - User registration
+- `dl_login` - User login
+- Custom business events
+
+**Event Queue:**
+
+Events with redirects (like `dl_purchase`) are queued to `sessionStorage` and automatically fired after navigation completes.
+
+**When to use auto mode:**
+- Standard e-commerce implementations
+- Minimal custom tracking requirements
+- Want to minimize code complexity
+- Need consistent tracking across pages
+
+### Manual Mode
+
+Full control over when and how events are tracked.
+
+```javascript
+analytics: {
+ mode: 'manual'
+}
+```
+
+**All events must be manually tracked** using the tracking API.
+
+**When to use manual mode:**
+- Need complete control over event timing
+- Custom e-commerce flows that don't match standard patterns
+- Want to track only specific events
+- Implementing custom event logic
+
+**Example manual tracking:**
+
+```javascript
+// View item
+window.NextAnalytics.trackViewItem({ id: '123', title: 'Product', price: 99.99 });
+
+// Add to cart
+window.NextAnalytics.trackAddToCart({ id: '123', quantity: 1 });
+
+// Begin checkout
+window.NextAnalytics.trackBeginCheckout();
+
+// Purchase
+window.NextAnalytics.trackPurchase(orderData);
+```
+
+## Provider Configuration
+
+### Google Tag Manager
+
+```javascript
+providers: {
+ gtm: {
+ enabled: true,
+ blockedEvents: ['dl_test_event', 'internal_event'] // Optional
+ }
+}
+```
+
+**Options:**
+
+| Option | Type | Description |
+|--------|------|-------------|
+| `enabled` | boolean | Enable GTM integration |
+| `blockedEvents` | string[] | Events to exclude from GTM |
+
+Events are pushed to `window.dataLayer` and `window.ElevarDataLayer`.
+
+See [Google Tag Manager Setup](/docs/campaign-cart/analytics/examples/google-tag-manager/) for detailed configuration.
+
+### Facebook Pixel
+
+```javascript
+storeName: 'my-store', // CRITICAL for deduplication
+analytics: {
+ providers: {
+ facebook: {
+ enabled: true,
+ settings: {
+ pixelId: 'YOUR_PIXEL_ID'
+ },
+ blockedEvents: [] // Optional
+ }
+ }
+}
+```
+
+**Options:**
+
+| Option | Type | Description |
+|--------|------|-------------|
+| `enabled` | boolean | Enable Facebook Pixel integration |
+| `settings.pixelId` | string | **Required** - Facebook Pixel ID |
+| `blockedEvents` | string[] | Events to exclude from Facebook |
+
+:::caution
+Always set `storeName` in your config when using Facebook Pixel to ensure proper purchase deduplication with server-side events.
+:::
+
+See [Facebook Pixel Setup](/docs/campaign-cart/analytics/examples/facebook-pixel/) for event mapping and deduplication details.
+
+### RudderStack
+
+```javascript
+providers: {
+ rudderstack: {
+ enabled: true,
+ blockedEvents: [] // Optional
+ }
+}
+```
+
+**Options:**
+
+| Option | Type | Description |
+|--------|------|-------------|
+| `enabled` | boolean | Enable RudderStack integration |
+| `blockedEvents` | string[] | Events to exclude from RudderStack |
+
+Events are mapped to Segment specification format.
+
+See [RudderStack Setup](/docs/campaign-cart/analytics/examples/rudderstack/) for event mapping details.
+
+### Custom Webhook
+
+```javascript
+providers: {
+ custom: {
+ enabled: true,
+ settings: {
+ // Required
+ endpoint: 'https://api.yourapp.com/analytics',
+
+ // Optional headers
+ headers: {
+ 'Authorization': 'Bearer YOUR_TOKEN',
+ 'Content-Type': 'application/json',
+ 'X-Store-ID': 'store-123'
+ },
+
+ // Batching settings
+ batchSize: 10, // Events per batch (default: 10)
+ batchIntervalMs: 5000, // Max time before sending (default: 5000ms)
+
+ // Retry configuration
+ maxRetries: 3, // Retry attempts (default: 3)
+ retryDelayMs: 1000, // Initial retry delay (default: 1000ms)
+
+ // Transform function
+ transformFunction: (event) => {
+ event.app_version = '1.0.0';
+ return event;
+ }
+ },
+ blockedEvents: [] // Optional
+ }
+}
+```
+
+**Options:**
+
+| Option | Type | Description |
+|--------|------|-------------|
+| `enabled` | boolean | Enable custom webhook integration |
+| `settings.endpoint` | string | **Required** - Your webhook URL |
+| `settings.headers` | object | Custom HTTP headers |
+| `settings.batchSize` | number | Events per batch (default: 10) |
+| `settings.batchIntervalMs` | number | Max batch wait time (default: 5000ms) |
+| `settings.maxRetries` | number | Retry attempts on failure (default: 3) |
+| `settings.retryDelayMs` | number | Initial retry delay with exponential backoff (default: 1000ms) |
+| `settings.transformFunction` | function | Transform events before sending |
+| `blockedEvents` | string[] | Events to exclude from webhook |
+
+See [Custom Webhook Setup](/docs/campaign-cart/analytics/examples/custom-webhook/) for batching, retry logic, and implementation details.
+
+## Multiple Providers
+
+Enable all providers simultaneously - each operates independently:
+
+```javascript
+providers: {
+ gtm: { enabled: true },
+ facebook: { enabled: true, settings: { pixelId: 'xxx' } },
+ rudderstack: { enabled: true },
+ custom: { enabled: true, settings: { endpoint: 'https://...' } }
+}
+```
+
+**How it works:**
+- Each event sent to ALL enabled providers
+- Providers operate independently (one failure doesn't affect others)
+- Events always stored in `NextDataLayer` regardless of provider status
+- Debug mode shows which providers received each event
+
+## Runtime Configuration
+
+### Enable Debug Mode
+
+
+
+
+```javascript
+analytics: {
+ debug: true
+}
+```
+
+
+
+
+```javascript
+// Enable at runtime
+window.NextAnalytics.setDebugMode(true);
+
+// Disable
+window.NextAnalytics.setDebugMode(false);
+```
+
+
+
+
+### Check Analytics Status
+
+```javascript
+const status = window.NextAnalytics.getStatus();
+console.log(status);
+
+// Output:
+// {
+// enabled: true,
+// mode: 'auto',
+// providers: ['GTM', 'Facebook', 'RudderStack'],
+// eventsTracked: 15,
+// debugMode: false
+// }
+```
+
+### Disable Tracking Temporarily
+
+Add `?ignore=true` to URL:
+
+```
+https://yoursite.com?ignore=true
+```
+
+This disables ALL tracking for the entire session.
+
+To clear ignore flag:
+```javascript
+window.NextAnalyticsClearIgnore();
+```
+
+## Configuration Examples
+
+### Minimal Configuration (GTM Only)
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: {
+ enabled: true,
+ mode: 'auto',
+ providers: {
+ gtm: { enabled: true }
+ }
+ }
+};
+```
+
+### E-commerce with Facebook Ads
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ storeName: 'my-store',
+ analytics: {
+ enabled: true,
+ mode: 'auto',
+ providers: {
+ gtm: { enabled: true },
+ facebook: {
+ enabled: true,
+ settings: { pixelId: 'YOUR_PIXEL_ID' }
+ }
+ }
+ }
+};
+```
+
+### Development Configuration
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: {
+ enabled: true,
+ debug: true, // Enable debug logging
+ mode: 'auto',
+ providers: {
+ gtm: { enabled: false }, // Disable GTM in dev
+ custom: {
+ enabled: true,
+ settings: {
+ endpoint: 'http://localhost:3000/analytics',
+ headers: { 'X-Dev-Mode': 'true' }
+ }
+ }
+ }
+ }
+};
+```
+
+### Enterprise Multi-Platform Setup
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ storeName: 'enterprise-store',
+ analytics: {
+ enabled: true,
+ mode: 'auto',
+ providers: {
+ gtm: {
+ enabled: true,
+ blockedEvents: ['internal_test', 'dev_event']
+ },
+ facebook: {
+ enabled: true,
+ settings: { pixelId: 'PROD_PIXEL_ID' }
+ },
+ rudderstack: { enabled: true },
+ custom: {
+ enabled: true,
+ settings: {
+ endpoint: 'https://api.yourapp.com/analytics',
+ headers: {
+ 'Authorization': 'Bearer YOUR_PRODUCTION_TOKEN',
+ 'X-Environment': 'production',
+ 'X-Region': 'US-WEST'
+ },
+ batchSize: 20,
+ batchIntervalMs: 3000,
+ maxRetries: 5,
+ transformFunction: (event) => {
+ // Add custom metadata
+ event.app_version = window.APP_VERSION;
+ event.environment = 'production';
+ event.region = 'us-west-1';
+
+ // Filter sensitive data
+ if (event.user_properties?.customer_phone) {
+ delete event.user_properties.customer_phone;
+ }
+
+ return event;
+ }
+ }
+ }
+ }
+ }
+};
+```
+
+## Configuration Best Practices
+
+### 1. Always Set storeName for Facebook
+
+```javascript
+{
+ storeName: 'my-store', // Required for purchase deduplication
+ analytics: {
+ providers: {
+ facebook: { enabled: true, settings: { pixelId: 'xxx' } }
+ }
+ }
+}
+```
+
+### 2. Use Auto Mode for Standard Implementations
+
+```javascript
+analytics: {
+ mode: 'auto' // Handles 90% of tracking automatically
+}
+```
+
+### 3. Enable Debug in Development
+
+```javascript
+analytics: {
+ debug: process.env.NODE_ENV === 'development'
+}
+```
+
+### 4. Block Internal Events
+
+```javascript
+providers: {
+ gtm: {
+ enabled: true,
+ blockedEvents: ['internal_test', 'dev_event', 'debug_event']
+ }
+}
+```
+
+### 5. Use Transform Functions for Custom Data
+
+```javascript
+custom: {
+ settings: {
+ transformFunction: (event) => {
+ event.custom_field = getCustomData();
+ return event;
+ }
+ }
+}
+```
+
+## Related Documentation
+
+- [Tracking API Reference](/docs/campaign-cart/analytics/tracking-api/) - Complete API documentation
+- [Examples Overview](/docs/campaign-cart/analytics/examples/) - Provider-specific setup guides
+- [Event Reference](/docs/campaign-cart/analytics/events/) - Complete event schemas
+- [Debugging Guide](/docs/campaign-cart/analytics/debugging/) - Troubleshooting and testing
+
diff --git a/docs/campaign-cart/analytics/custom-events.md b/docs/campaign-cart/analytics/custom-events.md
new file mode 100644
index 00000000..fe2ba053
--- /dev/null
+++ b/docs/campaign-cart/analytics/custom-events.md
@@ -0,0 +1,610 @@
+---
+title: Custom Events & Advanced Tracking
+description: Create custom analytics events and implement advanced tracking patterns with transform functions.
+sidebar_position: 10
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+Track custom business events and transform events before they're sent to providers.
+
+## Simple Custom Events
+
+Track custom events with arbitrary data:
+
+```javascript
+window.NextAnalytics.track({
+ event: 'newsletter_subscribe',
+ email: 'user@example.com',
+ list_name: 'Weekly Newsletter',
+ source: 'footer_form'
+});
+```
+
+Custom events are sent to **all enabled providers** and stored in `window.NextDataLayer`.
+
+### Automatic Enrichment
+
+Every event is automatically enriched with:
+- **event_id** - Unique event identifier
+- **event_time** - ISO timestamp
+- **user_properties** - Current user data (visitor_type, customer_email, etc.)
+- **attribution** - UTM parameters, funnel, affiliate data
+- **session_id** - Current session identifier
+- **Context** - page_location, page_title, user_agent, screen_resolution, viewport_size
+
+You don't need to add these manually - they're included automatically.
+
+### Common Custom Event Examples
+
+
+
+
+```javascript
+// Newsletter subscription
+window.NextAnalytics.track({
+ event: 'newsletter_subscribe',
+ email: 'user@example.com',
+ list: 'weekly_digest',
+ source: 'footer'
+});
+```
+
+
+
+
+```javascript
+// Video engagement
+window.NextAnalytics.track({
+ event: 'video_played',
+ video_id: 'intro-demo',
+ video_title: 'Product Introduction',
+ duration: 120
+});
+
+window.NextAnalytics.track({
+ event: 'video_completed',
+ video_id: 'intro-demo',
+ percent_watched: 100
+});
+```
+
+
+
+
+```javascript
+// Form submission
+window.NextAnalytics.track({
+ event: 'form_submitted',
+ form_id: 'contact',
+ form_type: 'contact_us',
+ fields_filled: 5
+});
+```
+
+
+
+
+```javascript
+// Feature usage
+window.NextAnalytics.track({
+ event: 'feature_used',
+ feature_name: 'product_comparison',
+ items_compared: 3,
+ user_id: currentUserId
+});
+```
+
+
+
+
+## E-commerce Custom Events
+
+For custom e-commerce events, include product data using the GA4 ecommerce format:
+
+```javascript
+window.NextAnalytics.track({
+ event: 'wishlist_add',
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [{
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ item_category: 'Electronics',
+ price: 99.99,
+ quantity: 1
+ }]
+ }
+});
+```
+
+### Custom E-commerce Examples
+
+
+
+
+```javascript
+function trackWishlistAdd(item) {
+ window.NextAnalytics.track({
+ event: 'wishlist_add',
+ ecommerce: {
+ currency: 'USD',
+ value: item.price,
+ items: [{
+ item_id: item.sku,
+ item_name: item.name,
+ item_category: item.category,
+ price: item.price,
+ quantity: 1
+ }]
+ }
+ });
+}
+```
+
+
+
+
+```javascript
+function trackProductComparison(products) {
+ window.NextAnalytics.track({
+ event: 'product_compare',
+ comparison_count: products.length,
+ ecommerce: {
+ currency: 'USD',
+ items: products.map((product, index) => ({
+ item_id: product.sku,
+ item_name: product.name,
+ item_category: product.category,
+ price: product.price,
+ quantity: 1,
+ index: index
+ }))
+ }
+ });
+}
+```
+
+
+
+
+```javascript
+function trackQuickView(item) {
+ window.NextAnalytics.track({
+ event: 'quick_view',
+ view_type: 'modal',
+ ecommerce: {
+ currency: 'USD',
+ value: item.price,
+ items: [{
+ item_id: item.sku,
+ item_name: item.name,
+ item_category: item.category,
+ price: item.price,
+ quantity: 1
+ }]
+ }
+ });
+}
+```
+
+
+
+
+## Transform Functions
+
+Modify ALL events before they're sent to providers using transform functions.
+
+### Using DataLayerManager
+
+```javascript
+// Access the data layer manager
+const dataLayer = window.NextDataLayerManager;
+
+dataLayer.setTransformFunction((event) => {
+ // Add custom fields to every event
+ event.app_version = '1.0.0';
+ event.environment = 'production';
+ event.custom_user_id = getCurrentUserId();
+
+ // Filter out events
+ if (event.event === 'internal_test') {
+ return null; // Event won't be sent
+ }
+
+ // Modify specific events
+ if (event.event === 'dl_purchase') {
+ event.ecommerce.custom_order_type = getOrderType();
+ event.fulfillment_center = 'US-WEST';
+ }
+
+ return event;
+});
+```
+
+### Global Transform Function
+
+You can also set a transform function globally in the window:
+
+```javascript
+window.NextDataLayerTransformFn = function(event) {
+ event.custom_property = 'value';
+ return event;
+};
+```
+
+This runs before the configured transform function.
+
+### Transform Function Use Cases
+
+
+
+
+```javascript
+window.NextDataLayerTransformFn = function(event) {
+ // Add app context to all events
+ event.app_version = window.APP_VERSION;
+ event.environment = window.ENV;
+ event.build_number = window.BUILD_NUM;
+
+ // Add user context
+ if (window.userSession) {
+ event.session_duration = Date.now() - window.userSession.startTime;
+ event.page_views = window.userSession.pageViews;
+ }
+
+ return event;
+};
+```
+
+
+
+
+```javascript
+window.NextDataLayerTransformFn = function(event) {
+ // Filter out internal events
+ const internalEvents = ['internal_test', 'dev_event', 'debug'];
+ if (internalEvents.includes(event.event)) {
+ return null; // Don't send
+ }
+
+ // Filter test users
+ if (event.user_properties?.customer_email?.includes('@test.com')) {
+ return null;
+ }
+
+ return event;
+};
+```
+
+
+
+
+```javascript
+window.NextDataLayerTransformFn = function(event) {
+ // Remove PII in certain environments
+ if (window.ENV === 'development') {
+ if (event.user_properties) {
+ event.user_properties.customer_email = 'redacted@example.com';
+ event.user_properties.customer_phone = 'REDACTED';
+ delete event.user_properties.customer_address_1;
+ }
+ }
+
+ return event;
+};
+```
+
+
+
+
+```javascript
+window.NextDataLayerTransformFn = function(event) {
+ // Add region-specific data
+ const region = getUserRegion();
+ event.region = region;
+ event.currency_override = getRegionalCurrency(region);
+
+ // Route high-value purchases
+ if (event.event === 'dl_purchase' && event.ecommerce.value > 1000) {
+ event.priority = 'high';
+ event.fraud_check_required = true;
+ }
+
+ return event;
+};
+```
+
+
+
+
+## Advanced Event Patterns
+
+### Event Chaining
+
+Track sequences of related events:
+
+```javascript
+// Start checkout flow
+window.NextAnalytics.track({
+ event: 'checkout_flow_started',
+ flow_id: generateFlowId(),
+ entry_point: 'cart_page'
+});
+
+// Track each step
+window.NextAnalytics.track({
+ event: 'checkout_step_completed',
+ flow_id: currentFlowId,
+ step: 'shipping_info',
+ duration_ms: stepDuration
+});
+
+// Track completion
+window.NextAnalytics.track({
+ event: 'checkout_flow_completed',
+ flow_id: currentFlowId,
+ total_duration_ms: totalDuration,
+ steps_completed: 4
+});
+```
+
+### Conditional Event Tracking
+
+Track events based on business logic:
+
+```javascript
+function trackCartMilestone(cartValue) {
+ const milestones = [
+ { threshold: 50, name: 'free_shipping_eligible' },
+ { threshold: 100, name: 'discount_eligible' },
+ { threshold: 200, name: 'premium_tier_reached' }
+ ];
+
+ milestones.forEach(milestone => {
+ if (cartValue >= milestone.threshold && !hasMilestone(milestone.name)) {
+ window.NextAnalytics.track({
+ event: 'cart_milestone',
+ milestone: milestone.name,
+ cart_value: cartValue,
+ threshold: milestone.threshold
+ });
+
+ saveMilestone(milestone.name);
+ }
+ });
+}
+```
+
+### Time-based Event Tracking
+
+Track engagement duration:
+
+```javascript
+class VideoTracker {
+ constructor(videoId) {
+ this.videoId = videoId;
+ this.startTime = Date.now();
+ this.milestones = [25, 50, 75, 100];
+ this.tracked = new Set();
+ }
+
+ trackProgress(percentComplete) {
+ this.milestones.forEach(milestone => {
+ if (percentComplete >= milestone && !this.tracked.has(milestone)) {
+ window.NextAnalytics.track({
+ event: 'video_progress',
+ video_id: this.videoId,
+ milestone: milestone,
+ duration_watched: Date.now() - this.startTime
+ });
+
+ this.tracked.add(milestone);
+ }
+ });
+ }
+
+ trackComplete() {
+ window.NextAnalytics.track({
+ event: 'video_completed',
+ video_id: this.videoId,
+ total_duration: Date.now() - this.startTime
+ });
+ }
+}
+```
+
+## Best Practices
+
+### 1. Consistent Event Naming
+
+Use snake_case for all custom events:
+
+```javascript
+// Good
+'newsletter_subscribe'
+'video_completed'
+'form_submitted'
+'feature_enabled'
+
+// Avoid
+'subscribeNewsletter'
+'VideoCompleted'
+'form-submitted'
+'FEATURE_ENABLED'
+```
+
+### 2. Include Context
+
+Provide event context:
+
+```javascript
+// Good - With context
+window.NextAnalytics.track({
+ event: 'video_completed',
+ video_id: 'intro-video',
+ video_title: 'Product Introduction',
+ video_duration: 120,
+ video_category: 'onboarding',
+ user_watched_percent: 100,
+ completion_time_seconds: 118
+});
+
+// Avoid - Minimal context
+window.NextAnalytics.track({
+ event: 'video_completed'
+});
+```
+
+### 3. Use GA4 Ecommerce Format
+
+For e-commerce events, use the GA4 standard format:
+
+```javascript
+// Good - GA4 format
+window.NextAnalytics.track({
+ event: 'wishlist_add',
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [{
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1
+ }]
+ }
+});
+
+// Avoid - Non-standard format
+window.NextAnalytics.track({
+ event: 'wishlist_add',
+ product: item // Wrong structure
+});
+```
+
+### 4. Handle Errors Gracefully
+
+Never let analytics errors break your app:
+
+```javascript
+try {
+ window.NextAnalytics.track(customEvent);
+} catch (error) {
+ console.error('Analytics tracking failed:', error);
+ // Don't throw - continue with app functionality
+}
+```
+
+### 5. Debug in Development
+
+Enable debug mode to see detailed logs:
+
+```javascript
+// In browser console
+window.NextAnalytics.setDebugMode(true);
+
+// Or via config
+window.nextConfig = {
+ analytics: {
+ debug: true
+ }
+};
+```
+
+## Examples
+
+### Product Recommendation Tracking
+
+```javascript
+function trackRecommendationClick(item, recommendationType) {
+ window.NextAnalytics.track({
+ event: 'recommendation_clicked',
+ item_id: item.id,
+ item_name: item.title,
+ recommendation_type: recommendationType, // 'similar', 'upsell', 'cross-sell'
+ recommendation_position: item.position,
+ algorithm: 'collaborative_filtering'
+ });
+}
+```
+
+### A/B Test Tracking
+
+```javascript
+function trackExperiment(experimentId, variantId) {
+ window.NextAnalytics.track({
+ event: 'experiment_viewed',
+ experiment_id: experimentId,
+ variant_id: variantId,
+ user_id: getCurrentUserId()
+ });
+}
+
+function trackExperimentConversion(experimentId, variantId) {
+ window.NextAnalytics.track({
+ event: 'experiment_converted',
+ experiment_id: experimentId,
+ variant_id: variantId,
+ conversion_value: getCartValue()
+ });
+}
+```
+
+### Search Tracking
+
+```javascript
+function trackSearch(query, resultsCount) {
+ window.NextAnalytics.track({
+ event: 'search_performed',
+ search_query: query,
+ results_count: resultsCount,
+ search_filters: getActiveFilters(),
+ search_sort: getCurrentSort()
+ });
+}
+
+function trackSearchResultClick(query, item, position) {
+ window.NextAnalytics.track({
+ event: 'search_result_clicked',
+ search_query: query,
+ item_id: item.id,
+ item_position: position,
+ results_count: getTotalResults()
+ });
+}
+```
+
+## Accessing the Data Layer
+
+View all tracked events:
+
+```javascript
+// View all events
+console.log(window.NextDataLayer);
+
+// Get event count
+const count = window.NextDataLayerManager.getEventCount();
+console.log(`Tracked ${count} events`);
+
+// Get analytics status
+const status = window.NextAnalytics.getStatus();
+console.log(status);
+// {
+// initialized: true,
+// debugMode: false,
+// providers: ['GTM', 'Facebook'],
+// eventsTracked: 15,
+// ignored: false
+// }
+```
+
+## Related Documentation
+
+- [Analytics Overview](/docs/campaign-cart/analytics/) - Main analytics documentation
+- [Tracking API](/docs/campaign-cart/analytics/tracking-api/) - Core tracking methods and events
+- [Configuration](/docs/campaign-cart/analytics/configuration/) - SDK configuration options
+- [Examples](/docs/campaign-cart/analytics/examples/) - Provider setup guides
diff --git a/docs/campaign-cart/analytics/debugging.md b/docs/campaign-cart/analytics/debugging.md
new file mode 100644
index 00000000..f5a9a208
--- /dev/null
+++ b/docs/campaign-cart/analytics/debugging.md
@@ -0,0 +1,421 @@
+---
+title: "Debugging & Testing"
+description: "Test analytics implementation, troubleshoot issues, and verify event tracking across all providers."
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+## Overview
+
+This guide provides debugging tools and troubleshooting strategies for testing your analytics implementation. Use these techniques to verify events are being tracked correctly across all providers and identify issues.
+
+## Enable Debug Mode
+
+Debug mode provides console logging of analytics events and provider interactions.
+
+
+
+
+Enable debug mode in your analytics configuration:
+
+```javascript
+analytics: {
+ debug: true // Enable in config
+}
+```
+
+
+
+
+Enable or check debug mode at runtime via the browser console:
+
+```javascript
+// Enable at runtime
+window.NextAnalytics.setDebugMode(true);
+
+// Check current status
+const status = window.NextAnalytics.getStatus();
+console.log(status);
+```
+
+
+
+
+When debug mode is enabled, you'll see detailed console output for every event tracked, including which providers received the event and any transformations applied.
+
+## Disable Tracking for Testing
+
+Temporarily disable all tracking while testing your site without affecting session data.
+
+### Enable Ignore Mode
+
+Add the `?ignore=true` query parameter to your URL:
+
+```
+https://yoursite.com?ignore=true
+```
+
+This disables **ALL** tracking for the entire session. All analytics events will be silently ignored.
+
+### Clear Ignore Mode
+
+When you're finished testing, clear the ignore flag:
+
+```javascript
+window.NextAnalyticsClearIgnore();
+```
+
+After calling this function, tracking will resume normally for new events.
+
+## Verify Events in Data Layers
+
+Check that events are properly pushed to the data layer and available for your analytics platforms to consume.
+
+### Check All Data Layers
+
+View the raw event data in each data layer:
+
+```javascript
+// NextAnalytics data layer
+console.log(window.NextDataLayer);
+
+// Google Tag Manager
+console.log(window.dataLayer);
+
+// Elevar (if enabled)
+console.log(window.ElevarDataLayer);
+```
+
+### Example Output
+
+When you track an event with debug mode enabled:
+
+```javascript
+// Check data layers
+console.log(window.NextDataLayer);
+// Output: [{
+// event: 'dl_add_to_cart',
+// ecommerce: { items: [...], value: 99.99 },
+// timestamp: 1234567890
+// }]
+
+console.log(window.dataLayer);
+// Output: [{
+// event: 'add_to_cart',
+// ecommerce: { items: [...], value: 99.99 }
+// }]
+```
+
+## Check Analytics Status
+
+Use the status API to verify providers are loaded and events are being tracked.
+
+### Get Current Status
+
+```javascript
+const status = window.NextAnalytics.getStatus();
+console.log('Events tracked:', status.eventsTracked);
+console.log('Providers:', status.providers);
+```
+
+### Example Output
+
+```javascript
+{
+ eventsTracked: 42,
+ providers: ['GTM', 'Facebook', 'RudderStack', 'Custom'],
+ debugMode: true,
+ ignoreMode: false
+}
+```
+
+This tells you:
+- **eventsTracked**: Total number of events processed in this session
+- **providers**: List of active providers receiving events
+- **debugMode**: Whether debug logging is enabled
+- **ignoreMode**: Whether tracking is temporarily disabled
+
+## Provider-Specific Debugging
+
+Each provider has different debugging tools and verification methods. Use the appropriate tab for your provider.
+
+### Verify Provider Connections
+
+First, verify that all expected providers are connected and receiving events:
+
+```javascript
+// Enable debug mode to see detailed logs
+window.NextAnalytics.setDebugMode(true);
+
+// Track a test event
+next.trackAddToCart('123', 1);
+
+// Console will show detailed output:
+// [NextDataLayer] Event pushed: dl_add_to_cart
+// [GTM] Pushing to dataLayer
+// [Facebook] Tracking AddToCart
+// [RudderStack] Tracking Product Added
+// [Custom] Batching event (1/10)
+```
+
+### Test Each Provider
+
+
+
+
+**Google Tag Manager Debugging**
+
+```javascript
+// Check if GTM container loaded
+console.log('GTM loaded:', typeof window.dataLayer !== 'undefined');
+
+// View all events in dataLayer
+console.log(window.dataLayer);
+
+// Check Elevar data layer (if using Elevar)
+console.log(window.ElevarDataLayer);
+```
+
+**Verification in GTM:**
+1. Go to your GTM container in preview mode
+2. Load your website and perform actions
+3. The GTM preview panel should show events being fired
+4. Check that events match your expected naming convention
+
+**Common GTM Issues:**
+- Events not appearing in preview mode
+- Incorrect event names or properties
+- Missing custom variables in GTM
+- Events firing after GTM container loads
+
+
+
+
+**Facebook Pixel Debugging**
+
+```javascript
+// Check if Pixel loaded
+console.log('Facebook Pixel loaded:', typeof window.fbq !== 'undefined');
+
+// Track a test event
+if (window.fbq) {
+ fbq('trackCustom', 'TestEvent', { test: true });
+}
+```
+
+**Using Facebook Pixel Helper:**
+1. Install the [Facebook Pixel Helper browser extension](https://www.facebook.com/business/tools/pixel-helper)
+2. Open the extension to see all pixel events firing in real-time
+3. Verify event names and data parameters match your Facebook Catalog
+
+**Common Facebook Issues:**
+- Duplicate purchase events from tracking same conversion twice
+- Missing `storeName` in configuration causing pixel conflicts
+- Events not matching Facebook's standard event names
+- Pixel events firing but not converting in Ads Manager
+
+
+
+
+**RudderStack Debugging**
+
+```javascript
+// Check if RudderStack SDK loaded
+console.log('RudderStack loaded:', typeof window.rudderanalytics !== 'undefined');
+
+// Check ready state
+if (window.rudderanalytics) {
+ rudderanalytics.ready(() => {
+ console.log('RudderStack is ready');
+ console.log('User ID:', rudderanalytics.getUserId());
+ });
+}
+```
+
+**Using RudderStack Debugger:**
+1. Enable the RudderStack debugger in your browser dev tools
+2. Open the Console and look for RudderStack logs
+3. Check the Network tab for POST requests to your RudderStack endpoint
+4. Verify the event payloads match your destination schema
+
+**Common RudderStack Issues:**
+- RudderStack SDK doesn't load within 5-second timeout
+- Events queued but not sent to destination
+- Invalid schema causing events to be rejected
+- Missing user identification for conversion tracking
+
+
+
+
+**Custom Endpoint Debugging**
+
+```javascript
+// Check network requests to your endpoint
+// 1. Open DevTools > Network tab
+// 2. Filter by your endpoint URL
+// 3. Look for POST requests with analytics events
+
+// Or add debug logging in your transform function:
+transformFunction: (event) => {
+ console.log('Sending to webhook:', {
+ event: event.event,
+ timestamp: new Date().toISOString(),
+ payload: event
+ });
+ return event;
+}
+```
+
+**Verification Steps:**
+1. Open DevTools > Network tab
+2. Filter requests by your webhook endpoint
+3. Look for POST requests containing your events
+4. Check the request payload matches your expected format
+5. Verify response status is 200-299 (success)
+6. Check your server logs for incoming requests
+
+**Common Custom Issues:**
+- 429 Rate Limit errors: Increase `batchIntervalMs` or reduce `batchSize`
+- Webhook not receiving batched events: Check endpoint URL and network connectivity
+- Events arriving in wrong order: Adjust batching configuration
+- Server returning 400/500 errors: Validate event schema against your API spec
+
+
+
+
+## Common Issues and Solutions
+
+Common analytics problems and solutions:
+
+| Issue | Cause | Solution |
+|-------|-------|----------|
+| No events in any provider | Analytics not initialized | Verify SDK loads before tracking events; check `debug` config |
+| GTM not receiving events | Container loads after tracking events | Ensure GTM tag loads before SDK initialization |
+| Facebook showing duplicate purchases | Same event tracked twice or storeName conflict | Remove duplicate tracking calls; configure `storeName` if using multiple pixels |
+| RudderStack events not sent | SDK not ready when events tracked | SDK waits 5 seconds for RudderStack to load; verify endpoint configuration |
+| Custom webhook 429 errors | Sending too many requests per second | Increase `batchIntervalMs` (default 3000ms) or reduce `batchSize` (default 10) |
+| Events in dataLayer but not in provider | Provider script not loaded | Verify provider scripts load and initialize before analytics events |
+| Debug logs not showing | Debug mode disabled | Enable with `window.NextAnalytics.setDebugMode(true)` |
+| ?ignore=true not working | Session already processing events | Clear ignore with `window.NextAnalyticsClearIgnore()` and refresh page |
+| Missing event properties | Insufficient context data | Verify event context (user, page, cart) populated before tracking |
+| Provider not in status list | Provider configuration disabled | Check analytics config for provider `enabled: true` setting |
+
+## Provider Not Receiving Events
+
+If a specific provider isn't receiving events, follow this debugging process:
+
+### Step 1: Verify Provider is Enabled
+
+```javascript
+const status = window.NextAnalytics.getStatus();
+console.log('Active providers:', status.providers);
+```
+
+If your provider isn't in the list, check your configuration to ensure it's enabled.
+
+### Step 2: Enable Debug Mode
+
+```javascript
+window.NextAnalytics.setDebugMode(true);
+```
+
+Now track an event and watch the console for debug output related to your provider.
+
+### Step 3: Check for Blocked Events
+
+Some events may be intentionally blocked from certain providers:
+
+```javascript
+// Check GTM blocked events as an example
+const config = window.nextConfig.analytics.providers.gtm;
+console.log('Blocked events:', config.blockedEvents);
+```
+
+Verify the event you're testing isn't in the blocked list.
+
+### Step 4: Verify Provider Script Loaded
+
+Check that the provider's JavaScript library loaded successfully:
+
+```javascript
+// Google Tag Manager
+console.log('GTM loaded:', typeof window.dataLayer !== 'undefined');
+
+// Facebook Pixel
+console.log('Facebook loaded:', typeof window.fbq !== 'undefined');
+
+// RudderStack
+console.log('RudderStack loaded:', typeof window.rudderanalytics !== 'undefined');
+```
+
+If any of these return `false` or `undefined`, the provider script didn't load. Check your configuration and network requests.
+
+## Events Not Showing in Analytics Platform
+
+Events sent from your site may not appear in your analytics platform's dashboard. Use provider-specific debugging tools:
+
+### GTM: Preview Mode
+
+1. Open your GTM container
+2. Click **Preview** to enter preview mode
+3. Visit your website in a new tab
+4. The GTM preview panel will show all tags and events firing in real-time
+5. Click on events to see their properties and which tags they trigger
+
+### Facebook: Pixel Helper
+
+1. Install the [Facebook Pixel Helper extension](https://www.facebook.com/business/tools/pixel-helper)
+2. Click the extension icon to view all pixel events
+3. Verify event names match your Facebook Catalog
+4. Check event properties like `value` and `currency` are correct
+5. Use the Diagnostics tab to identify validation issues
+
+### RudderStack: Debugger
+
+1. Check RudderStack's web console for errors
+2. Open DevTools Network tab and filter for RudderStack API calls
+3. Verify the destination is receiving events in your RudderStack workspace
+4. Check that your destination transformation rules are correct
+
+### Custom: Server Logs and Network Monitoring
+
+1. Check your server logs for incoming webhook requests
+2. Verify request headers and payload structure match your spec
+3. Check response codes (200-299 = success, 4xx/5xx = error)
+4. Monitor Network tab in DevTools for request timing and failures
+
+## Testing Checklist
+
+Verify your analytics implementation before going live:
+
+- [ ] **Debug mode enabled** - `window.NextAnalytics.setDebugMode(true)` shows detailed logs
+- [ ] **All providers active** - `window.NextAnalytics.getStatus()` lists all expected providers
+- [ ] **Events in data layer** - `console.log(window.NextDataLayer)` shows events
+- [ ] **GTM receiving events** - `console.log(window.dataLayer)` contains your events
+- [ ] **GTM preview mode** - Events appear in GTM container preview panel
+- [ ] **Facebook Pixel Helper** - Extension shows purchase and add-to-cart events
+- [ ] **RudderStack events** - Network tab shows POST requests to RudderStack
+- [ ] **Custom webhook** - Server receives POST requests with event payloads
+- [ ] **Event properties complete** - All required fields present (value, currency, items)
+- [ ] **No blocked events** - Verify events aren't in provider `blockedEvents` list
+- [ ] **No duplicate events** - Each action tracked once per provider
+- [ ] **Ignore mode works** - `?ignore=true` prevents events from being tracked
+- [ ] **Ignore mode clears** - `window.NextAnalyticsClearIgnore()` resumes tracking
+- [ ] **Status API responsive** - `getStatus()` returns current state
+- [ ] **Multiple providers tested** - Events work across all enabled providers
+- [ ] **Error handling** - Failed provider requests don't break site functionality
+- [ ] **Production ready** - Debug mode disabled in production config
+
+## Next Steps
+
+After testing and debugging your analytics:
+
+1. **Review Configuration** - Check your provider settings match your platform setup
+2. **Enable Tracking** - Remove `?ignore=true` and deploy to production
+3. **Monitor Events** - Use platform dashboards to monitor event flow
+4. **Set Up Alerts** - Configure monitoring for provider failures or dropped events
+5. **Document Setup** - Record your analytics configuration for your team
+
+See the [Configuration Guide](/docs/campaign-cart/analytics/configuration/) for detailed provider setup instructions.
diff --git a/docs/campaign-cart/analytics/events.md b/docs/campaign-cart/analytics/events.md
new file mode 100644
index 00000000..af287791
--- /dev/null
+++ b/docs/campaign-cart/analytics/events.md
@@ -0,0 +1,660 @@
+---
+title: Event Reference
+description: Complete reference of all analytics events with schemas, examples, and when they fire.
+sidebar_position: 3
+---
+
+
+Complete reference of all standard analytics events tracked by the SDK, including event structure, when they fire, and whether they're automatically tracked.
+
+## Event Naming Convention
+
+All standard events follow the `dl_*` naming pattern for consistency with data layer conventions.
+
+## Event Categories
+
+- **User Events** - User identification and authentication
+- **E-commerce Events** - Product views, cart, checkout, purchase
+- **Custom Events** - Your custom business events
+
+---
+
+## User Events
+
+### dl_user_data
+
+Base user event with cart contents. Automatically fired on every page load in auto mode.
+
+**When it fires:**
+- Page load
+- Route changes
+- User login/logout
+- Browser back/forward navigation
+
+**Auto-tracked:** Yes (in auto mode)
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_user_data',
+ event_id: 'sess_123_1_1234567890',
+ event_time: '2025-01-12T10:30:00Z',
+ user_properties: {
+ visitor_type: 'guest',
+ customer_email: 'user@example.com',
+ customer_id: 'user_123'
+ },
+ ecommerce: {
+ currency: 'USD',
+ value: 199.99,
+ items: [...] // Current cart items
+ }
+}
+```
+
+---
+
+### dl_sign_up
+
+User registration event.
+
+**When it fires:** When user creates an account
+
+**Auto-tracked:** No (manual tracking required)
+
+**Tracking:**
+
+```javascript
+// Simple
+next.trackSignUp('user@example.com');
+
+// Advanced
+window.NextAnalytics.trackSignUp('user@example.com');
+```
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_sign_up',
+ event_id: 'sess_123_2_1234567890',
+ method: 'email',
+ user_properties: {
+ visitor_type: 'logged_in',
+ customer_email: 'user@example.com',
+ customer_first_name: 'John',
+ customer_last_name: 'Doe'
+ }
+}
+```
+
+---
+
+### dl_login
+
+User login event.
+
+**When it fires:** When user logs in
+
+**Auto-tracked:** No (manual tracking required)
+
+**Tracking:**
+
+```javascript
+// Simple
+next.trackLogin('user@example.com');
+
+// Advanced
+window.NextAnalytics.trackLogin('user@example.com');
+```
+
+---
+
+## E-commerce Events
+
+### dl_view_item_list
+
+Product list view (collection, category, search results).
+
+**When it fires:** When a product list is displayed
+
+**Auto-tracked:** Yes (when URL matches collection/category patterns)
+
+**Tracking:**
+
+```javascript
+// Simple
+next.trackViewItemList(['123', '456'], 'summer-sale', 'Summer Sale');
+
+// Advanced
+window.NextAnalytics.trackViewItemList(items, listId, listName);
+```
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_view_item_list',
+ event_id: 'sess_123_3_1234567890',
+ user_properties: { ... },
+ ecommerce: {
+ item_list_id: 'summer-sale',
+ item_list_name: 'Summer Sale Collection',
+ currency: 'USD',
+ items: [
+ {
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1,
+ index: 0
+ }
+ ]
+ }
+}
+```
+
+**List Attribution:** Stores list ID and name in session storage for 30 minutes.
+
+---
+
+### dl_view_item
+
+Product detail view.
+
+**When it fires:** When a product page is viewed
+
+**Auto-tracked:** Yes (when page has exactly 1 product with `data-next-package-id`)
+
+**Manual tracking:**
+
+```javascript
+// Simple
+next.trackViewItem('123');
+
+// Advanced
+window.NextAnalytics.trackViewItem({
+ id: 'pkg-123',
+ packageId: '123',
+ title: 'Product Name',
+ price: 99.99
+});
+```
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_view_item',
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [{
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1,
+ item_list_id: 'summer-sale', // If coming from a list
+ item_list_name: 'Summer Sale'
+ }]
+ }
+}
+```
+
+---
+
+### dl_add_to_cart
+
+Item added to cart.
+
+**When it fires:** When user adds item to cart
+
+**Auto-tracked:** Yes (when using data attributes or cart methods)
+
+**Tracking:**
+
+```javascript
+// Simple
+next.trackAddToCart('123', 1);
+
+// Advanced with list attribution
+window.NextAnalytics.trackAddToCart({
+ id: 'pkg-123',
+ packageId: '123',
+ title: 'Product Name',
+ price: 99.99,
+ quantity: 1
+}, 'summer-sale', 'Summer Sale');
+```
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_add_to_cart',
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [{
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1,
+ item_list_id: 'summer-sale',
+ item_list_name: 'Summer Sale'
+ }]
+ }
+}
+```
+
+---
+
+### dl_remove_from_cart
+
+Item removed from cart.
+
+**When it fires:** When user removes item from cart
+
+**Auto-tracked:** Yes (when using cart methods)
+
+**Tracking:**
+
+```javascript
+// Simple
+next.trackRemoveFromCart('123', 1);
+
+// Advanced
+import { EcommerceEvents } from '@/utils/analytics';
+import { dataLayer } from '@/utils/analytics';
+
+const event = EcommerceEvents.createRemoveFromCartEvent(item);
+dataLayer.push(event);
+```
+
+---
+
+### dl_view_cart
+
+Cart page view.
+
+**When it fires:** When cart page is viewed
+
+**Auto-tracked:** No (manual tracking required)
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_view_cart',
+ ecommerce: {
+ currency: 'USD',
+ value: 199.99,
+ items: [...] // All cart items
+ }
+}
+```
+
+---
+
+### dl_begin_checkout
+
+Checkout process initiation.
+
+**When it fires:** When checkout starts
+
+**Auto-tracked:** Yes (when checkout page loads)
+
+**Tracking:**
+
+```javascript
+// Simple
+next.trackBeginCheckout();
+
+// Advanced
+window.NextAnalytics.trackBeginCheckout();
+```
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_begin_checkout',
+ ecommerce: {
+ currency: 'USD',
+ value: 199.99,
+ items: [...] // All cart items
+ }
+}
+```
+
+---
+
+### dl_add_shipping_info
+
+Shipping information entered.
+
+**When it fires:** When shipping details are completed
+
+**Auto-tracked:** Yes (when shipping form is submitted)
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_add_shipping_info',
+ ecommerce: {
+ currency: 'USD',
+ value: 199.99,
+ shipping_tier: 'Standard Shipping',
+ items: [...]
+ }
+}
+```
+
+---
+
+### dl_add_payment_info
+
+Payment information entered.
+
+**When it fires:** When payment method is selected
+
+**Auto-tracked:** Yes (when payment form is submitted)
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_add_payment_info',
+ ecommerce: {
+ currency: 'USD',
+ value: 199.99,
+ payment_type: 'Credit Card',
+ items: [...]
+ }
+}
+```
+
+---
+
+### dl_purchase
+
+Order completion.
+
+**When it fires:** When order is completed
+
+**Auto-tracked:** Yes
+
+**Event Queue:**
+
+Purchase events are queued to `sessionStorage` when the order completes, then automatically fired on the confirmation page after redirect. This prevents event loss during navigation.
+
+**Manual tracking (optional):**
+
+```javascript
+// Optional: Manually trigger for testing or special integrations
+// Order data automatically available in sessionStorage['next-order']
+const orderData = JSON.parse(sessionStorage.getItem('next-order'))?.state?.order;
+if (orderData) {
+ next.trackPurchase({ order: orderData });
+}
+
+// Or provide custom order data
+next.trackPurchase({
+ id: 'ORDER_123',
+ total: 159.99,
+ currency: 'USD',
+ tax: 9.99,
+ shipping: 10.00
+});
+```
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_purchase',
+ transaction_id: 'ORD-12345',
+ ecommerce: {
+ transaction_id: 'ORD-12345',
+ affiliation: 'Online Store',
+ currency: 'USD',
+ value: 159.99,
+ tax: 9.99,
+ shipping: 10.00,
+ coupon: 'SUMMER20',
+ items: [
+ {
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 149.99,
+ quantity: 1
+ }
+ ]
+ }
+}
+```
+
+---
+
+### dl_package_swapped
+
+Package swap (replace one item with another).
+
+**When it fires:** When user swaps one package for another
+
+**Auto-tracked:** No (manual tracking required)
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_package_swapped',
+ ecommerce: {
+ currency: 'USD',
+ value: 20.00, // Price difference
+ items_removed: [{
+ item_id: 'SKU-123',
+ item_name: 'Basic Package',
+ price: 99.99,
+ quantity: 1
+ }],
+ items_added: [{
+ item_id: 'SKU-456',
+ item_name: 'Premium Package',
+ price: 119.99,
+ quantity: 1
+ }]
+ }
+}
+```
+
+---
+
+### dl_upsell_purchase
+
+Upsell accepted (post-purchase).
+
+**When it fires:** When user accepts an upsell offer
+
+**Auto-tracked:** No (manual tracking required)
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_upsell_purchase',
+ transaction_id: 'ORD-12345-US1', // Format: {orderId}-US{number}
+ ecommerce: {
+ transaction_id: 'ORD-12345-US1',
+ currency: 'USD',
+ value: 29.99,
+ items: [{
+ item_id: 'UPSELL-789',
+ item_name: 'Upsell Package',
+ price: 29.99,
+ quantity: 1
+ }]
+ },
+ _willRedirect: true // Queued for post-redirect processing
+}
+```
+
+**Note:** Has `_willRedirect: true` flag - automatically queued and processed after page redirect.
+
+---
+
+### dl_view_search_results
+
+Search results page view.
+
+**When it fires:** When search results are displayed
+
+**Auto-tracked:** No (manual tracking required)
+
+**Example:**
+
+```javascript
+{
+ event: 'dl_view_search_results',
+ search_term: 'drone',
+ ecommerce: {
+ item_list_id: 'search-results',
+ item_list_name: 'Search Results',
+ currency: 'USD',
+ items: [...]
+ }
+}
+```
+
+---
+
+## Event Structure
+
+All events follow this GA4-compliant structure:
+
+```javascript
+{
+ // Event identification
+ event: string, // Event name (e.g., 'dl_add_to_cart')
+ event_id: string, // Unique ID: sessionId_sequence_timestamp
+ event_time: string, // ISO timestamp
+
+ // User properties (Elevar format)
+ user_properties: {
+ visitor_type: 'guest' | 'logged_in',
+ customer_id?: string,
+ customer_email?: string,
+ customer_phone?: string,
+ customer_first_name?: string,
+ customer_last_name?: string,
+ customer_address_1?: string,
+ customer_city?: string,
+ customer_province?: string,
+ customer_zip?: string,
+ customer_country?: string
+ },
+
+ // Ecommerce data (GA4 format)
+ ecommerce?: {
+ currency: string,
+ value?: number,
+ transaction_id?: string,
+ affiliation?: string,
+ tax?: number,
+ shipping?: number,
+ coupon?: string,
+ discount?: number,
+ item_list_id?: string,
+ item_list_name?: string,
+ shipping_tier?: string,
+ payment_type?: string,
+ items: [{
+ item_id: string,
+ item_name: string,
+ item_brand?: string,
+ item_category?: string,
+ item_variant?: string,
+ price: number,
+ quantity: number,
+ currency: string,
+ index?: number,
+ item_list_id?: string,
+ item_list_name?: string
+ }]
+ },
+
+ // Attribution (auto-added)
+ attribution?: {
+ utm_source?: string,
+ utm_medium?: string,
+ utm_campaign?: string,
+ utm_term?: string,
+ utm_content?: string,
+ gclid?: string,
+ funnel?: string,
+ affiliate?: string
+ },
+
+ // Context (auto-added)
+ page_location?: string,
+ page_title?: string,
+ page_referrer?: string,
+
+ // Internal metadata
+ _metadata: {
+ pushed_at: number,
+ session_id: string,
+ sequence_number: number,
+ source: 'next-campaign-cart',
+ version: '0.2.0'
+ }
+}
+```
+
+## Quick Reference Table
+
+| Event | When it Fires | Auto-Tracked | Manual Method |
+|-------|--------------|--------------|---------------|
+| `dl_user_data` | Every page load | Yes | - |
+| `dl_sign_up` | User registration | No | `next.trackSignUp()` |
+| `dl_login` | User login | No | `next.trackLogin()` |
+| `dl_view_item_list` | List page view | Yes | `next.trackViewItemList()` |
+| `dl_view_item` | Product page view | Yes | `next.trackViewItem()` |
+| `dl_add_to_cart` | Add to cart | Yes | `next.trackAddToCart()` |
+| `dl_remove_from_cart` | Remove from cart | Yes | `next.trackRemoveFromCart()` |
+| `dl_view_cart` | Cart page view | No | Manual |
+| `dl_begin_checkout` | Checkout start | Yes | `next.trackBeginCheckout()` |
+| `dl_add_shipping_info` | Shipping entered | Yes | Manual |
+| `dl_add_payment_info` | Payment entered | Yes | Manual |
+| `dl_purchase` | Order complete | Yes | `next.trackPurchase()` (optional) |
+| `dl_package_swapped` | Package swap | No | Manual |
+| `dl_upsell_purchase` | Upsell accepted | No | Manual |
+| `dl_view_search_results` | Search results | No | Manual |
+
+## Event Validation
+
+All events are automatically validated against schemas:
+
+```javascript
+import { EventValidator } from '@/utils/analytics';
+
+const validator = new EventValidator(true);
+
+// Validate event
+const result = validator.validateEvent(event);
+if (!result.valid) {
+ console.error('Invalid event:', result.errors);
+}
+
+// Get available schemas
+const schemas = validator.getAvailableSchemas();
+console.log(schemas);
+```
+
+## Related Documentation
+
+- [Analytics Overview](/docs/campaign-cart/analytics/) - Main analytics documentation
+- [Custom Events](/docs/campaign-cart/analytics/custom-events/) - Creating custom events
+- [Examples](/docs/campaign-cart/analytics/examples/) - Provider integration guides
diff --git a/docs/campaign-cart/analytics/examples/custom-analytics-triggers.md b/docs/campaign-cart/analytics/examples/custom-analytics-triggers.md
new file mode 100644
index 00000000..d74bb2b4
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/custom-analytics-triggers.md
@@ -0,0 +1,878 @@
+# Custom Analytics Triggers
+
+This external script modifies when `add_to_cart` and `begin_checkout` events fire for GTM and Facebook Pixel, allowing you to customize the timing of these critical ecommerce events.
+
+## Overview
+
+This script changes **when** events fire, but uses the **same event format and data structure** as the SDK's default events:
+
+- **`dl_add_to_cart`**: Fires when the checkout page loads (instead of when items are added to cart)
+- **`dl_begin_checkout`**: Fires when:
+ - Prospect cart is created (when name/email input triggers `carts.create`)
+ - OR when express checkout option is clicked (PayPal, Apple Pay, Google Pay)
+
+## Changes Made
+
+- **`add_to_cart`**: Now fires when the checkout page loads (instead of when items are added to cart)
+- **`begin_checkout`**: Now fires when:
+ - Prospect cart is created (when name/email input triggers `carts.create`)
+ - OR when express checkout option is clicked (PayPal, Apple Pay, Google Pay)
+
+## Requirements
+
+- SDK must be loaded and initialized
+- GTM `dataLayer` must be available (for GTM events)
+- Facebook Pixel `fbq` must be available (for Facebook events)
+- Default SDK events must be blocked in configuration (see Setup below)
+
+## Setup
+
+### 1. Configuration Setup
+
+Add `blockedEvents` to both GTM and Facebook providers in your `config.js`:
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: {
+ enabled: true,
+ providers: {
+ gtm: {
+ enabled: true,
+ settings: { ... },
+ blockedEvents: ['dl_add_to_cart', 'dl_begin_checkout']
+ },
+ facebook: {
+ enabled: true,
+ settings: { pixelId: 'xxx' },
+ blockedEvents: ['dl_add_to_cart', 'dl_begin_checkout']
+ }
+ }
+ }
+};
+```
+
+### 2. Include Script in HTML
+
+Include this script **after** the SDK loader but **before** the SDK initializes:
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 3. Ensure Cart Has Items
+
+- Add items to cart before testing
+- Cart must not be empty for events to fire
+
+## How It Works
+
+### Checkout Page Detection
+
+The script detects checkout pages by:
+- Looking for checkout form elements (`form[data-next-checkout]` or `form[os-checkout-form]`)
+- Checking for `meta[name="next-page-type"]` with value `checkout`
+- Checking if URL contains "checkout" or "cart"
+
+### add_to_cart Trigger
+
+- Fires when checkout page loads
+- Also listens for `checkout:form-initialized` event
+- Only fires once per page load (duplicate prevention)
+
+### begin_checkout Triggers
+
+- Listens for `next:prospect-cart-created` DOM event (fired when name/email input creates prospect cart)
+- Listens for express checkout button clicks (PayPal, Apple Pay, Google Pay buttons)
+- Listens for `express-checkout:started` SDK event
+- Only fires once per checkout session (duplicate prevention)
+
+## Event Format
+
+The script formats events according to:
+- **GTM**: GA4 ecommerce event format with `ecommerce` object, using `dl_` prefix (Campaign Cart SDK's standard naming convention)
+- **Facebook Pixel**: Standard Facebook event parameters
+- Events are pushed to both `ElevarDataLayer` (for Elevar compatibility) and `dataLayer` (standard GTM)
+
+:::note About Event Naming
+The `dl_` prefix is Campaign Cart SDK's standard event naming convention (e.g., `dl_add_to_cart`, `dl_begin_checkout`). This follows data layer conventions and is used by the SDK for all events, not specific to Elevar.
+
+`ElevarDataLayer` is a separate data layer specifically for Elevar compatibility. If you're not using Elevar, you can remove the `ElevarDataLayer` references from the script - events will still work with standard GTM via `window.dataLayer`.
+:::
+
+## Complete Script
+
+Here's the complete JavaScript code for the custom analytics triggers:
+
+```javascript
+/**
+ * Custom Analytics Triggers for GTM and Facebook Pixel
+ *
+ * This script modifies WHEN add_to_cart and begin_checkout events fire, but uses
+ * the SAME event format and data structure as the SDK's default events.
+ *
+ * Changes:
+ * - dl_add_to_cart: Fires when checkout page loads (instead of when items are added)
+ * - dl_begin_checkout: Fires when carts.create fires (name/email input) OR when express checkout is clicked
+ *
+ * The events use the same format as SDK defaults:
+ * - dl_ prefix (Campaign Cart SDK's standard naming convention)
+ * - Same ecommerce data structure
+ * - Pushed to both ElevarDataLayer (for Elevar compatibility) and dataLayer (standard GTM)
+ *
+ * Usage: Include this script after the SDK loader, and block the default events
+ * in your config.js: blockedEvents: ['dl_add_to_cart', 'dl_begin_checkout']
+ */
+
+(function() {
+ 'use strict';
+
+ // Flag to allow our script's InitiateCheckout events through
+ let isFiringFromOurScript = false;
+
+ // Wrap fbq immediately to block SDK's InitiateCheckout on page load
+ (function() {
+ const originalFbq = window.fbq;
+
+ // Create wrapper function
+ window.fbq = function() {
+ const args = Array.from(arguments);
+ const command = args[0];
+ const eventName = args[1];
+
+ // Block InitiateCheckout unless it's from our script
+ if (command === 'track' && eventName === 'InitiateCheckout' && !isFiringFromOurScript) {
+ console.log('🚫 Blocked SDK InitiateCheckout event (backup blocker)');
+ return;
+ }
+
+ // Allow our script's events through
+ if (command === 'track' && eventName === 'InitiateCheckout' && isFiringFromOurScript) {
+ isFiringFromOurScript = false; // Reset flag after allowing
+ }
+
+ // Call original fbq
+ if (typeof originalFbq === 'function') {
+ return originalFbq.apply(this, arguments);
+ }
+
+ // If originalFbq wasn't available, queue to _fbq
+ window._fbq = window._fbq || [];
+ window._fbq.push(args);
+ };
+
+ // Copy properties from original fbq if it exists
+ if (originalFbq) {
+ Object.keys(originalFbq).forEach(function(key) {
+ window.fbq[key] = originalFbq[key];
+ });
+ }
+ })();
+
+ // Track if events have been fired to prevent duplicates
+ let hasFiredAddToCart = false;
+ let hasFiredBeginCheckout = false;
+
+ /**
+ * Get cart data from SDK
+ */
+ function getCartData() {
+ try {
+ if (typeof window.next !== 'undefined' && window.next.getCartData) {
+ return window.next.getCartData();
+ }
+
+ // Fallback: try to access stores via debug API if available
+ if (typeof window.nextDebug !== 'undefined' && window.nextDebug.stores) {
+ const cartStore = window.nextDebug.stores.cart;
+ const campaignStore = window.nextDebug.stores.campaign;
+ if (cartStore && campaignStore) {
+ return {
+ cartLines: cartStore.getState().enrichedItems || cartStore.getState().items,
+ cartTotals: cartStore.getState().totals,
+ campaignData: campaignStore.getState().data,
+ appliedCoupons: cartStore.getState().appliedCoupons || []
+ };
+ }
+ }
+
+ return null;
+ } catch (error) {
+ console.warn('Could not get cart data:', error);
+ return null;
+ }
+ }
+
+ /**
+ * Get campaign data for currency and package info
+ */
+ function getCampaignData() {
+ try {
+ if (typeof window.next !== 'undefined' && window.next.getCampaignData) {
+ return window.next.getCampaignData();
+ }
+
+ // Fallback: try to access stores via debug API if available
+ if (typeof window.nextDebug !== 'undefined' && window.nextDebug.stores) {
+ const campaignStore = window.nextDebug.stores.campaign;
+ if (campaignStore) {
+ return campaignStore.getState().data;
+ }
+ }
+
+ return null;
+ } catch (error) {
+ console.warn('Could not get campaign data:', error);
+ return null;
+ }
+ }
+
+ /**
+ * Get package data by ID
+ */
+ function getPackage(packageId) {
+ try {
+ if (typeof window.next !== 'undefined' && window.next.getPackage) {
+ return window.next.getPackage(packageId);
+ }
+
+ // Fallback: try to access stores via debug API if available
+ if (typeof window.nextDebug !== 'undefined' && window.nextDebug.stores) {
+ const campaignStore = window.nextDebug.stores.campaign;
+ if (campaignStore && campaignStore.getState().getPackage) {
+ return campaignStore.getState().getPackage(packageId);
+ }
+ }
+
+ return null;
+ } catch (error) {
+ console.warn('Could not get package data:', error);
+ return null;
+ }
+ }
+
+ /**
+ * Format cart items for analytics
+ */
+ function formatCartItems(cartData, campaignData) {
+ if (!cartData || !cartData.cartLines || cartData.cartLines.length === 0) {
+ return [];
+ }
+
+ const currency = campaignData?.currency || cartData.campaignData?.currency || 'USD';
+
+ return cartData.cartLines.map((item, index) => {
+ // Extract packageId from enriched item (could be in different places)
+ const packageId = item.packageId || item.package_id || item.id;
+
+ // Try to get package data
+ let packageData = null;
+ if (packageId) {
+ packageData = getPackage(packageId);
+ }
+
+ return {
+ item_id: packageData?.external_id?.toString() || item.external_id?.toString() || packageId?.toString() || String(packageId),
+ item_name: packageData?.name || item.name || item.title || `Package ${packageId}`,
+ price: parseFloat(packageData?.price_total || item.price_total || item.price || '0'),
+ quantity: item.quantity || 1,
+ item_category: campaignData?.name || cartData.campaignData?.name || 'Campaign',
+ item_variant: packageData?.product_variant_name || item.variant_name || packageData?.product?.variant?.name,
+ item_brand: packageData?.product_name || item.product_name || packageData?.product?.name,
+ item_sku: packageData?.product_sku || item.sku || packageData?.product?.variant?.sku,
+ ...(packageData?.image && { item_image: packageData.image }),
+ ...(item.image && { item_image: item.image }),
+ index: index
+ };
+ });
+ }
+
+ /**
+ * Fire add_to_cart event to GTM and Facebook
+ */
+ function fireAddToCart() {
+ if (hasFiredAddToCart) {
+ return;
+ }
+
+ const cartData = getCartData();
+ const campaignData = getCampaignData();
+
+ if (!cartData || !cartData.cartLines || cartData.cartLines.length === 0) {
+ console.warn('Cannot fire add_to_cart: cart is empty');
+ return;
+ }
+
+ const items = formatCartItems(cartData, campaignData);
+ const currency = campaignData?.currency || cartData.campaignData?.currency || 'USD';
+ const totalValue = cartData.cartTotals?.total?.value || cartData.cartTotals?.total || 0;
+
+ // Calculate total value from items if not available
+ const calculatedValue = items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
+ const value = totalValue || calculatedValue;
+
+ // Fire to GTM (dataLayer) - using dl_ prefix (Campaign Cart SDK's standard naming convention)
+ if (typeof window.dataLayer !== 'undefined') {
+ // Ensure ElevarDataLayer exists (for Elevar compatibility - optional if not using Elevar)
+ window.ElevarDataLayer = window.ElevarDataLayer || [];
+
+ // Create event in SDK format (dl_ prefix is Campaign Cart SDK's standard)
+ const event = {
+ event: 'dl_add_to_cart',
+ ecommerce: {
+ currency: currency,
+ value: value,
+ items: items
+ },
+ timestamp: new Date().toISOString()
+ };
+
+ // Push to ElevarDataLayer first (for Elevar processing - optional if not using Elevar)
+ window.ElevarDataLayer.push(event);
+
+ // Clear previous ecommerce data and push to standard dataLayer
+ window.dataLayer.push({ ecommerce: null });
+ window.dataLayer.push(event);
+
+ console.log('✅ Fired dl_add_to_cart to GTM');
+ }
+
+ // Fire to Facebook Pixel - simple direct call
+ if (typeof window.fbq !== 'undefined') {
+ const fbParams = {
+ content_type: 'product',
+ currency: currency,
+ value: value,
+ content_ids: items.map(item => item.item_id),
+ contents: items.map(item => ({
+ id: item.item_id,
+ quantity: item.quantity,
+ item_price: item.price
+ })),
+ content_name: items.map(item => item.item_name).join(', '),
+ num_items: items.reduce((sum, item) => sum + item.quantity, 0)
+ };
+
+ window.fbq('track', 'AddToCart', fbParams);
+ console.log('✅ Fired add_to_cart to Facebook Pixel');
+ }
+
+ hasFiredAddToCart = true;
+ }
+
+ /**
+ * Fire begin_checkout event to GTM and Facebook
+ */
+ function fireBeginCheckout() {
+ if (hasFiredBeginCheckout) {
+ return;
+ }
+
+ const cartData = getCartData();
+ const campaignData = getCampaignData();
+
+ if (!cartData || !cartData.cartLines || cartData.cartLines.length === 0) {
+ console.warn('Cannot fire begin_checkout: cart is empty');
+ return;
+ }
+
+ const items = formatCartItems(cartData, campaignData);
+ const currency = campaignData?.currency || cartData.campaignData?.currency || 'USD';
+ const totalValue = cartData.cartTotals?.total?.value || cartData.cartTotals?.total || 0;
+
+ // Calculate total value from items if not available
+ const calculatedValue = items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
+ const value = totalValue || calculatedValue;
+
+ // Get coupon if available
+ const coupon = cartData.appliedCoupons?.[0]?.code || (Array.isArray(cartData.appliedCoupons) && cartData.appliedCoupons.length > 0 ? cartData.appliedCoupons[0] : null) || null;
+
+ // Fire to GTM (dataLayer) - using dl_ prefix (Campaign Cart SDK's standard naming convention)
+ if (typeof window.dataLayer !== 'undefined') {
+ // Ensure ElevarDataLayer exists (for Elevar compatibility - optional if not using Elevar)
+ window.ElevarDataLayer = window.ElevarDataLayer || [];
+
+ // Create event in SDK format (dl_ prefix is Campaign Cart SDK's standard)
+ const event = {
+ event: 'dl_begin_checkout',
+ ecommerce: {
+ currency: currency,
+ value: value,
+ items: items
+ },
+ cart_total: String(value),
+ timestamp: new Date().toISOString()
+ };
+
+ if (coupon) {
+ event.ecommerce.coupon = coupon;
+ }
+
+ // Push to ElevarDataLayer first (for Elevar processing - optional if not using Elevar)
+ window.ElevarDataLayer.push(event);
+
+ // Clear previous ecommerce data and push to standard dataLayer
+ window.dataLayer.push({ ecommerce: null });
+ window.dataLayer.push(event);
+
+ console.log('✅ Fired dl_begin_checkout to GTM');
+ }
+
+ // Fire to Facebook Pixel - set flag to allow through wrapper
+ if (typeof window.fbq !== 'undefined') {
+ const fbParams = {
+ content_type: 'product',
+ currency: currency,
+ value: value,
+ content_ids: items.map(item => item.item_id),
+ contents: items.map(item => ({
+ id: item.item_id,
+ quantity: item.quantity,
+ item_price: item.price
+ })),
+ num_items: items.reduce((sum, item) => sum + item.quantity, 0)
+ };
+
+ if (coupon) {
+ fbParams.coupon = coupon;
+ }
+
+ // Set flag to allow our event through the wrapper
+ isFiringFromOurScript = true;
+ window.fbq('track', 'InitiateCheckout', fbParams);
+ console.log('✅ Fired begin_checkout to Facebook Pixel');
+ }
+
+ hasFiredBeginCheckout = true;
+ }
+
+ /**
+ * Check if we're on a checkout page
+ */
+ function isCheckoutPage() {
+ // Check for checkout form
+ const checkoutForm = document.querySelector('form[data-next-checkout], form[os-checkout-form]');
+ if (checkoutForm) {
+ return true;
+ }
+
+ // Check for meta tag
+ const pageType = document.querySelector('meta[name="next-page-type"]');
+ if (pageType && pageType.getAttribute('content') === 'checkout') {
+ return true;
+ }
+
+ // Check URL
+ const url = window.location.pathname.toLowerCase();
+ if (url.includes('checkout') || url.includes('cart')) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Initialize the custom triggers
+ */
+ function initialize() {
+ // Wait for SDK to be ready
+ if (typeof window.nextReady !== 'undefined') {
+ window.nextReady.push(function() {
+ setupTriggers();
+ });
+ } else if (typeof window.next !== 'undefined') {
+ // SDK might already be loaded
+ setupTriggers();
+ } else {
+ // Wait for SDK initialization event
+ document.addEventListener('next:initialized', function() {
+ setupTriggers();
+ });
+ }
+ }
+
+ /**
+ * Setup event listeners for triggers
+ */
+ function setupTriggers() {
+ console.log('🔧 Setting up custom analytics triggers');
+
+ // 1. Fire add_to_cart when checkout page loads
+ if (isCheckoutPage()) {
+ // Wait a bit for cart to be populated
+ setTimeout(function() {
+ fireAddToCart();
+ }, 500);
+ }
+
+ // Also listen for checkout form initialization
+ document.addEventListener('checkout:form-initialized', function() {
+ if (isCheckoutPage()) {
+ setTimeout(function() {
+ fireAddToCart();
+ }, 100);
+ }
+ });
+
+ // 2. Fire begin_checkout when prospect cart is created (name/email input)
+ document.addEventListener('next:prospect-cart-created', function(event) {
+ // Check if form has user input (not page load)
+ const emailField = document.querySelector('[data-next-checkout-field="email"], [os-checkout-field="email"], input[type="email"]');
+
+ if (emailField && emailField.value && emailField.value.trim().length > 0) {
+ console.log('✅ Prospect cart created (user input detected), firing begin_checkout');
+ setTimeout(function() {
+ fireBeginCheckout();
+ }, 100);
+ } else {
+ console.log('⚠️ Prospect cart created but no user input - ignoring (likely page load)');
+ }
+ });
+
+ // 3. Fire begin_checkout when express checkout is clicked
+ document.addEventListener('click', function(event) {
+ const target = event.target;
+ if (!target) return;
+
+ // Check if it's an express checkout button
+ const button = target.closest('[data-next-express-checkout], [os-express-checkout], button[data-next-payment="paypal"], button[data-next-payment="apple_pay"], button[data-next-payment="google_pay"]');
+
+ if (button) {
+ console.log('✅ Express checkout clicked, firing begin_checkout');
+ setTimeout(function() {
+ fireBeginCheckout();
+ }, 100);
+ }
+ }, true); // Use capture phase to catch early
+
+ // Also listen for express checkout started event (if SDK emits it)
+ if (typeof window.next !== 'undefined' && window.next.on) {
+ window.next.on('express-checkout:started', function() {
+ console.log('✅ Express checkout started event, firing begin_checkout');
+ setTimeout(function() {
+ fireBeginCheckout();
+ }, 100);
+ });
+ }
+ }
+
+ // Initialize when DOM is ready
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', initialize);
+ } else {
+ initialize();
+ }
+
+})();
+```
+
+## Testing
+
+### Setup Checklist
+
+1. ✅ **Config.js Setup** - Add `blockedEvents` to both GTM and Facebook providers
+2. ✅ **Include Script in HTML** - Script included after SDK loader
+3. ✅ **Ensure Cart Has Items** - Cart must not be empty for events to fire
+
+### Test `add_to_cart` Event (Checkout Page Load)
+
+**What to test:** Event fires when checkout page loads
+
+**Steps:**
+1. Add items to cart on product/selection page
+2. Navigate to checkout page
+3. Open browser console (F12)
+4. Look for console log: `"✅ Fired dl_add_to_cart to GTM"` and `"✅ Fired add_to_cart to Facebook Pixel"`
+
+**Verify in Browser Console:**
+```javascript
+// Check dataLayer
+console.log(window.dataLayer.filter(e => e.event === 'dl_add_to_cart'));
+
+// Check ElevarDataLayer
+console.log(window.ElevarDataLayer.filter(e => e.event === 'dl_add_to_cart'));
+
+// Should see event with:
+// - event: 'dl_add_to_cart'
+// - ecommerce.currency
+// - ecommerce.value
+// - ecommerce.items[] (array of cart items)
+```
+
+**Verify in GTM Preview Mode:**
+1. Open GTM Preview mode
+2. Navigate to checkout page
+3. Look for `dl_add_to_cart` event
+4. Check that event has:
+ - `ecommerce.currency`
+ - `ecommerce.value`
+ - `ecommerce.items[]` with item details
+
+**Verify in Facebook Events Manager:**
+1. Go to Facebook Events Manager
+2. Navigate to checkout page
+3. Check for `AddToCart` event
+4. Verify event parameters (value, currency, content_ids, etc.)
+
+**Expected Behavior:**
+- ✅ Event fires ONCE when checkout page loads
+- ✅ Event does NOT fire when items are added to cart (that's blocked)
+- ✅ Event includes all cart items
+- ✅ Event has correct currency and value
+
+### Test `begin_checkout` Event (Prospect Cart Created)
+
+**What to test:** Event fires when name/email input triggers cart creation
+
+**Steps:**
+1. Navigate to checkout page (with items in cart)
+2. Open browser console (F12)
+3. Enter email address in checkout form
+4. Enter first name
+5. Enter last name
+6. Look for console log: `"✅ Prospect cart created (user input detected), firing begin_checkout"`
+7. Then: `"✅ Fired dl_begin_checkout to GTM"` and `"✅ Fired begin_checkout to Facebook Pixel"`
+
+**Verify in Browser Console:**
+```javascript
+// Check dataLayer
+console.log(window.dataLayer.filter(e => e.event === 'dl_begin_checkout'));
+
+// Check ElevarDataLayer
+console.log(window.ElevarDataLayer.filter(e => e.event === 'dl_begin_checkout'));
+
+// Should see event with:
+// - event: 'dl_begin_checkout'
+// - ecommerce.currency
+// - ecommerce.value
+// - ecommerce.items[]
+// - cart_total (string)
+// - ecommerce.coupon (if coupon applied)
+```
+
+**Expected Behavior:**
+- ✅ Event fires when prospect cart is created (after email/name entry)
+- ✅ Event fires only ONCE per checkout session
+- ✅ Event includes all cart items
+- ✅ Event has correct currency, value, and coupon (if applicable)
+
+### Test `begin_checkout` Event (Express Checkout Click)
+
+**What to test:** Event fires when express checkout button is clicked
+
+**Steps:**
+1. Navigate to checkout page (with items in cart)
+2. Open browser console (F12)
+3. Click PayPal, Apple Pay, or Google Pay button
+4. Look for console log: `"✅ Express checkout clicked, firing begin_checkout"`
+5. Then: `"✅ Fired dl_begin_checkout to GTM"` and `"✅ Fired begin_checkout to Facebook Pixel"`
+
+**Verify:**
+- Same verification steps as above
+- Event should fire immediately when express checkout button is clicked
+- Event should NOT fire again if already fired (duplicate prevention)
+
+## Console Debugging
+
+### Check if Script Loaded
+```javascript
+// Should see in console when script initializes:
+"🔧 Setting up custom analytics triggers"
+```
+
+### Check Event Firing
+```javascript
+// Monitor all events
+window.dataLayer.forEach(e => {
+ if (e.event === 'dl_add_to_cart' || e.event === 'dl_begin_checkout') {
+ console.log('Event fired:', e);
+ }
+});
+```
+
+### Check if SDK Events are Blocked
+```javascript
+// If SDK events are properly blocked, you should NOT see:
+// - dl_add_to_cart when items are added to cart
+// - dl_begin_checkout when checkout form initializes
+
+// Only see:
+// - dl_add_to_cart when checkout page loads
+// - dl_begin_checkout when prospect cart created OR express checkout clicked
+```
+
+### Quick Test Script
+
+Add this to browser console for quick testing:
+
+```javascript
+// Test if script is working
+function testCustomTriggers() {
+ console.log('=== Custom Triggers Test ===');
+
+ // Check if script loaded
+ console.log('Script loaded:', typeof window.dataLayer !== 'undefined');
+
+ // Check SDK
+ console.log('SDK ready:', typeof window.next !== 'undefined');
+
+ // Check cart
+ if (window.next) {
+ const cart = window.next.getCartData();
+ console.log('Cart items:', cart?.cartLines?.length || 0);
+ console.log('Cart total:', cart?.cartTotals?.total?.value || 0);
+ }
+
+ // Check recent events
+ const recentEvents = window.dataLayer.slice(-10);
+ const customEvents = recentEvents.filter(e =>
+ e.event === 'dl_add_to_cart' || e.event === 'dl_begin_checkout'
+ );
+ console.log('Recent custom events:', customEvents);
+
+ // Check if on checkout page
+ const isCheckout = document.querySelector('form[data-next-checkout], form[os-checkout-form]') !== null;
+ console.log('On checkout page:', isCheckout);
+}
+
+testCustomTriggers();
+```
+
+## GTM Preview Mode Testing
+
+1. **Open GTM Preview Mode**
+ - Go to GTM → Preview
+ - Enter your site URL
+
+2. **Test add_to_cart**
+ - Navigate to checkout page
+ - In GTM Preview, look for `dl_add_to_cart` event
+ - Click on event to see details
+ - Verify `ecommerce` object has correct data
+
+3. **Test begin_checkout**
+ - Enter email/name OR click express checkout
+ - In GTM Preview, look for `dl_begin_checkout` event
+ - Verify event data
+
+4. **Verify Events are Blocked**
+ - Add item to cart (should NOT see `dl_add_to_cart`)
+ - Load checkout page (SHOULD see `dl_add_to_cart`)
+ - Initialize checkout form (should NOT see `dl_begin_checkout` from SDK)
+
+## Facebook Events Manager Testing
+
+1. **Open Facebook Events Manager**
+ - Go to Events Manager → Test Events
+ - Enter your site URL
+
+2. **Test Events**
+ - Navigate checkout page → Should see `AddToCart`
+ - Enter email/name OR click express checkout → Should see `InitiateCheckout`
+
+3. **Verify Event Parameters**
+ - Check `value` matches cart total
+ - Check `currency` is correct
+ - Check `content_ids` has all product IDs
+ - Check `num_items` matches cart quantity
+
+## Troubleshooting
+
+### Issue: Events Not Firing
+
+**Check:**
+1. ✅ Script is included after SDK loader
+2. ✅ Cart has items (not empty)
+3. ✅ Console shows "🔧 Setting up custom analytics triggers"
+4. ✅ No JavaScript errors in console
+5. ✅ SDK is initialized (`window.next` exists)
+
+**Debug:**
+```javascript
+// Check if SDK is ready
+console.log('SDK ready:', typeof window.next !== 'undefined');
+
+// Check cart data
+if (window.next) {
+ const cart = window.next.getCartData();
+ console.log('Cart data:', cart);
+ console.log('Cart has items:', cart?.cartLines?.length > 0);
+}
+```
+
+### Issue: Events Firing Multiple Times
+
+**Check:**
+- Script should prevent duplicates with `hasFiredAddToCart` and `hasFiredBeginCheckout` flags
+- If seeing duplicates, check if script is included multiple times in HTML
+
+### Issue: Wrong Event Format
+
+**Check:**
+- Events should use `dl_` prefix (not `add_to_cart`, but `dl_add_to_cart`) - this is Campaign Cart SDK's standard naming convention
+- Events should be pushed to `dataLayer` (required for GTM)
+- Events can optionally be pushed to `ElevarDataLayer` if using Elevar
+- Events should have `ecommerce` object with `currency`, `value`, and `items`
+
+### Issue: Missing Data in Events
+
+**Check:**
+- Cart must have items before events fire
+- Campaign data must be loaded (for currency, package info)
+- Check console for warnings: `"Cannot fire add_to_cart: cart is empty"`
+
+## Success Criteria
+
+✅ **add_to_cart:**
+- Fires when checkout page loads
+- Does NOT fire when items added to cart
+- Includes all cart items
+- Has correct currency and value
+
+✅ **begin_checkout:**
+- Fires when prospect cart created (email/name entry)
+- Fires when express checkout clicked
+- Does NOT fire when checkout form initializes
+- Includes all cart items
+- Has correct currency, value, and coupon (if applicable)
+
+✅ **No Duplicates:**
+- Each event fires only once per session
+- SDK's default events are blocked
+- Only custom script events fire
+
+## Debugging
+
+The script logs to console when events are fired:
+- `✅ Fired dl_add_to_cart to GTM`
+- `✅ Fired add_to_cart to Facebook Pixel`
+- `✅ Fired dl_begin_checkout to GTM`
+- `✅ Fired begin_checkout to Facebook Pixel`
+
+Open browser console to see these messages and verify events are firing correctly.
+
+## Notes
+
+- Events are only fired once per page load (duplicate prevention)
+- Script waits for SDK to be ready before setting up listeners
+- Cart must have items for events to fire
+- Script gracefully handles missing SDK or analytics tools
+- Events use the same format as SDK defaults for consistency
+
diff --git a/docs/campaign-cart/analytics/examples/custom-webhook.md b/docs/campaign-cart/analytics/examples/custom-webhook.md
new file mode 100644
index 00000000..4f287684
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/custom-webhook.md
@@ -0,0 +1,814 @@
+---
+title: "Custom Webhook Integration"
+description: "Send analytics events to your own backend with batching, retry logic, and custom transformations."
+---
+
+Send events to your own backend or third-party APIs with control over data transformation, batching, and delivery.
+
+## Configuration
+
+Configure the custom webhook provider with your endpoint and optional settings:
+
+```javascript
+providers: {
+ custom: {
+ enabled: true,
+ settings: {
+ // Required
+ endpoint: 'https://api.yourapp.com/analytics',
+
+ // Optional headers
+ headers: {
+ 'Authorization': 'Bearer YOUR_TOKEN',
+ 'Content-Type': 'application/json',
+ 'X-Store-ID': 'store-123'
+ },
+
+ // Batching settings
+ batchSize: 10, // Events per batch
+ batchIntervalMs: 5000, // Max time before sending
+
+ // Retry configuration
+ maxRetries: 3,
+ retryDelayMs: 1000, // Exponential backoff: 1s, 2s, 4s
+
+ // Transform events before sending
+ transformFunction: (event) => {
+ return {
+ ...event,
+ app_version: '1.0.0',
+ environment: 'production',
+ timestamp: new Date().toISOString()
+ };
+ }
+ }
+ }
+}
+```
+
+### Configuration Options
+
+| Option | Type | Required | Default | Description |
+|--------|------|----------|---------|-------------|
+| `endpoint` | string | Yes | - | The URL of your backend endpoint that receives analytics events |
+| `headers` | object | No | `{}` | Custom HTTP headers to include in each request (e.g., auth tokens) |
+| `batchSize` | number | No | 10 | Number of events to accumulate before sending a batch |
+| `batchIntervalMs` | number | No | 5000 | Maximum milliseconds to wait before sending a batch, regardless of size |
+| `maxRetries` | number | No | 3 | Number of times to retry failed requests |
+| `retryDelayMs` | number | No | 1000 | Initial delay in milliseconds for retry attempts (exponential backoff) |
+| `transformFunction` | function | No | - | Function to transform each event before sending (receives event, returns modified event) |
+
+## Request Format
+
+Events are sent as POST requests in batches to your endpoint:
+
+```
+POST https://api.yourapp.com/analytics
+Content-Type: application/json
+Authorization: Bearer YOUR_TOKEN
+
+{
+ "events": [
+ {
+ "event": "dl_add_to_cart",
+ "event_id": "sess_123_1_1234567890",
+ "event_time": "2025-01-12T10:30:00Z",
+ "ecommerce": {
+ "items": [
+ {
+ "item_id": "SKU123",
+ "item_name": "Product Name",
+ "price": 29.99,
+ "quantity": 1
+ }
+ ],
+ "value": 29.99,
+ "currency": "USD"
+ },
+ "user_properties": {
+ "user_id": "user_123",
+ "session_id": "sess_123",
+ "country": "US"
+ },
+ "attribution": {
+ "source": "google",
+ "medium": "cpc",
+ "campaign": "summer_sale"
+ }
+ },
+ {
+ "event": "dl_view_item",
+ "event_id": "sess_123_2_1234567891",
+ "event_time": "2025-01-12T10:30:02Z",
+ ...
+ }
+ ],
+ "batch_info": {
+ "size": 2,
+ "timestamp": "2025-01-12T10:30:05Z",
+ "source": "next-campaign-cart"
+ }
+}
+```
+
+### Request Body Fields
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `events` | array | Array of event objects (max 100 per batch) |
+| `batch_info.size` | number | Number of events in this batch |
+| `batch_info.timestamp` | string | ISO 8601 timestamp when batch was sent |
+| `batch_info.source` | string | Always "next-campaign-cart" |
+
+## Response Expected
+
+Your endpoint should return appropriate HTTP status codes:
+
+- **`200 OK`** - Events processed successfully
+- **`201 Created`** - Events created successfully
+- **`202 Accepted`** - Events accepted for processing (recommended)
+- **`4xx`** - Client error (SDK will retry based on specific status)
+- **`5xx`** - Server error (SDK will retry with exponential backoff)
+
+### Response Body (Optional)
+
+While not required, you can return a response body:
+
+```json
+{
+ "success": true,
+ "message": "Analytics events received",
+ "batch_id": "batch_abc123xyz",
+ "events_processed": 2
+}
+```
+
+## Batching Behavior
+
+Events are batched to reduce network requests and server load. Batches are sent when:
+
+1. **Size Threshold**: `batchSize` events have been queued
+2. **Time Threshold**: `batchIntervalMs` milliseconds have elapsed since the first event in the batch
+3. **Page Unload**: Immediately before navigation or window close to ensure data is not lost
+4. **Manual Flush**: When explicitly requested through the SDK API (if available)
+
+### Example Batching Timeline
+
+With `batchSize: 10` and `batchIntervalMs: 5000`:
+
+```
+Time Event Batch Status
+0ms Event 1 arrives Queue: [1] → Start 5s timer
+100ms Event 2 arrives Queue: [1, 2]
+500ms Event 3 arrives Queue: [1, 2, 3]
+1000ms Event 4 arrives Queue: [1, 2, 3, 4]
+1500ms Event 5 arrives Queue: [1, 2, 3, 4, 5]
+2000ms Event 6 arrives Queue: [1, 2, 3, 4, 5, 6]
+2500ms Event 7 arrives Queue: [1, 2, 3, 4, 5, 6, 7]
+3000ms Event 8 arrives Queue: [1, 2, 3, 4, 5, 6, 7, 8]
+3500ms Event 9 arrives Queue: [1, 2, 3, 4, 5, 6, 7, 8, 9]
+4000ms Event 10 arrives Queue: [1-10] → SEND BATCH (size threshold met)
+4050ms Event 11 arrives Queue: [11] → Start new 5s timer
+5000ms (5s elapsed) Queue: [11-15] → SEND BATCH (time threshold met)
+```
+
+## Retry Logic
+
+Failed requests retry with exponential backoff to prevent overwhelming your server during temporary outages.
+
+### Retry Schedule
+
+- **Attempt 1**: Immediate, no delay
+- **Attempt 2**: Wait `retryDelayMs` (default: 1s)
+- **Attempt 3**: Wait `retryDelayMs * 2` (default: 2s)
+- **Attempt 4**: Wait `retryDelayMs * 4` (default: 4s)
+
+After `maxRetries` attempts, events are dropped and logged.
+
+### Example with Default Settings
+
+```
+Time Event Status
+0ms Send batch Fails (500 error)
+0ms Schedule retry 1
+1000ms Retry attempt 1 Fails (500 error)
+1000ms Schedule retry 2
+3000ms Retry attempt 2 Fails (503 timeout)
+3000ms Schedule retry 3
+7000ms Retry attempt 3 Succeeds (200 OK)
+ Batch sent!
+```
+
+### Retry Configuration Examples
+
+**Aggressive Retries** (for critical analytics):
+```javascript
+maxRetries: 5,
+retryDelayMs: 500, // 0.5s, 1s, 2s, 4s, 8s = 15.5s total
+```
+
+**Conservative Retries** (for high-volume events):
+```javascript
+maxRetries: 2,
+retryDelayMs: 2000, // 2s, 4s = 6s total
+```
+
+**No Retries** (if endpoint is highly available):
+```javascript
+maxRetries: 0, // Send once, drop on failure
+```
+
+## Transform Function
+
+The `transformFunction` option allows you to modify, filter, or enrich events before they're sent to your backend. This function is called once for each event.
+
+### Basic Transform Function
+
+```javascript
+transformFunction: (event) => {
+ // Add custom fields
+ event.app_version = '1.0.0';
+ event.environment = 'production';
+ event.server_timestamp = Date.now();
+
+ // Filter sensitive data
+ if (event.user_properties) {
+ delete event.user_properties.customer_phone;
+ }
+
+ // Add business context
+ if (event.event === 'dl_purchase') {
+ event.custom_order_type = 'online';
+ event.fulfillment_center = 'US-WEST';
+ }
+
+ return event;
+}
+```
+
+### Advanced Transform Examples
+
+#### Conditional Field Addition
+
+```javascript
+transformFunction: (event) => {
+ // Add fields only for specific events
+ if (event.event === 'dl_purchase') {
+ event.revenue_category = event.ecommerce?.value > 100 ? 'high' : 'normal';
+ }
+
+ // Add user tier information
+ if (event.user_properties?.user_id) {
+ event.user_tier = calculateUserTier(event.user_properties.user_id);
+ }
+
+ return event;
+}
+```
+
+#### Data Validation and Sanitization
+
+```javascript
+transformFunction: (event) => {
+ // Ensure required fields
+ if (!event.event_time) {
+ event.event_time = new Date().toISOString();
+ }
+
+ // Sanitize strings
+ if (event.user_properties?.session_id) {
+ event.user_properties.session_id =
+ event.user_properties.session_id.replace(/[^a-zA-Z0-9_-]/g, '');
+ }
+
+ // Convert currencies
+ if (event.ecommerce?.currency === 'EUR') {
+ event.ecommerce.value_usd = event.ecommerce.value * 0.92;
+ }
+
+ return event;
+}
+```
+
+#### PII Redaction
+
+```javascript
+transformFunction: (event) => {
+ const sensitiveFields = ['email', 'phone', 'ssn', 'credit_card'];
+
+ if (event.user_properties) {
+ sensitiveFields.forEach(field => {
+ if (event.user_properties[field]) {
+ delete event.user_properties[field];
+ }
+ });
+ }
+
+ return event;
+}
+```
+
+#### Event Sampling
+
+```javascript
+transformFunction: (event) => {
+ // Sample non-purchase events at 10% to reduce volume
+ if (event.event !== 'dl_purchase') {
+ if (Math.random() > 0.1) {
+ return null; // Drop this event
+ }
+ }
+
+ return event;
+}
+```
+
+#### Regional Routing
+
+```javascript
+transformFunction: (event) => {
+ const region = getUserRegion();
+ event.endpoint_region = region;
+
+ // Set processing priority
+ event.processing_priority = event.event === 'dl_purchase' ? 'high' : 'normal';
+
+ // Add regional context
+ event.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
+
+ return event;
+}
+```
+
+## Use Cases
+
+### Data Warehouse Integration
+
+Forward events to your data warehouse for long-term analysis and reporting:
+
+```javascript
+endpoint: 'https://api.yourdata.com/ingest/analytics',
+headers: {
+ 'Authorization': 'Bearer warehouse-token',
+ 'X-Dataset-ID': 'campaign-cart-events'
+},
+batchSize: 50, // Larger batches for warehouse efficiency
+batchIntervalMs: 10000,
+transformFunction: (event) => {
+ return {
+ ...event,
+ warehouse_partition: new Date().toISOString().split('T')[0],
+ ingestion_source: 'campaign-cart'
+ };
+}
+```
+
+**Supported**: Snowflake, BigQuery, Redshift, Databricks, etc.
+
+### Custom Analytics Platform
+
+Send events to your own analytics infrastructure:
+
+```javascript
+endpoint: 'https://analytics.yourcompany.com/api/v1/events',
+headers: {
+ 'Authorization': 'Bearer api-key',
+ 'X-App-ID': 'campaign-cart'
+},
+maxRetries: 3,
+transformFunction: (event) => {
+ return {
+ ...event,
+ event_version: '2.0',
+ company_id: 'comp_123',
+ received_at: new Date().toISOString()
+ };
+}
+```
+
+### Marketing Automation
+
+Trigger marketing workflows based on analytics events:
+
+```javascript
+endpoint: 'https://api.marketing-platform.com/webhooks/events',
+headers: {
+ 'Authorization': 'Bearer webhook-key',
+ 'X-Integration-ID': 'cart-system'
+},
+batchSize: 1, // Send events immediately
+batchIntervalMs: 100,
+transformFunction: (event) => {
+ // Only send customer conversion events
+ if (!['dl_purchase', 'dl_view_item'].includes(event.event)) {
+ return null;
+ }
+
+ return {
+ ...event,
+ trigger_type: event.event === 'dl_purchase' ? 'purchase' : 'view',
+ automation_enabled: true
+ };
+}
+```
+
+**Platforms**: HubSpot, Klaviyo, Braze, Marketo, etc.
+
+### Real-time Processing
+
+Process events in real-time systems for immediate action:
+
+```javascript
+endpoint: 'https://streaming.yourcompany.com/events',
+headers: {
+ 'Authorization': 'Bearer stream-key'
+},
+batchSize: 5,
+batchIntervalMs: 1000,
+transformFunction: (event) => {
+ return {
+ ...event,
+ processing_timestamp: Date.now(),
+ priority: ['dl_purchase', 'dl_error'].includes(event.event) ? 'high' : 'normal'
+ };
+}
+```
+
+**Platforms**: Kafka, RabbitMQ, Apache Pulsar, AWS Kinesis, etc.
+
+### Multi-region Distribution
+
+Send different events to different regional endpoints:
+
+```javascript
+endpoint: 'https://api.yourapp.com/analytics',
+transformFunction: (event) => {
+ // Determine user region
+ const region = getUserRegion(); // 'us', 'eu', 'apac'
+
+ return {
+ ...event,
+ target_region: region,
+ regional_endpoint: `https://api-${region}.yourapp.com/analytics`,
+ processing_priority: event.event === 'dl_purchase' ? 'high' : 'normal',
+ is_critical_event: ['dl_purchase', 'dl_error'].includes(event.event)
+ };
+}
+```
+
+## Example: Multi-endpoint Setup
+
+For advanced scenarios where you need to send events to multiple endpoints or route them based on event type:
+
+```javascript
+import { useAnalytics } from '@campaign-cart/analytics';
+
+const analytics = useAnalytics({
+ providers: {
+ custom: {
+ enabled: true,
+ settings: {
+ endpoint: 'https://api.yourapp.com/analytics',
+ headers: {
+ 'Authorization': 'Bearer YOUR_TOKEN',
+ 'Content-Type': 'application/json'
+ },
+ batchSize: 10,
+ batchIntervalMs: 5000,
+ maxRetries: 3,
+ retryDelayMs: 1000,
+
+ // Advanced routing based on event type and attributes
+ transformFunction: (event) => {
+ const transformed = {
+ ...event,
+ app_version: '1.0.0',
+ environment: process.env.NODE_ENV
+ };
+
+ // Route purchase events to high-priority endpoint
+ if (event.event === 'dl_purchase') {
+ transformed.endpoint_priority = 'high';
+ transformed.endpoint_type = 'purchases';
+ transformed.requires_acknowledgment = true;
+ }
+
+ // Route behavioral events normally
+ else if (['dl_view_item', 'dl_add_to_cart', 'dl_remove_from_cart'].includes(event.event)) {
+ transformed.endpoint_priority = 'normal';
+ transformed.endpoint_type = 'behaviors';
+ }
+
+ // Route errors to special endpoint
+ else if (event.event === 'dl_error') {
+ transformed.endpoint_priority = 'critical';
+ transformed.endpoint_type = 'errors';
+ transformed.alert_on_receipt = true;
+ }
+
+ // Add regional information
+ const userRegion = detectUserRegion();
+ transformed.region = userRegion;
+ transformed.regional_endpoint = `https://api-${userRegion}.yourapp.com/analytics`;
+
+ return transformed;
+ }
+ }
+ }
+ }
+});
+
+// Helper function to detect user region
+function detectUserRegion() {
+ if (typeof window === 'undefined') return 'default';
+
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
+
+ if (timezone.includes('America')) return 'us';
+ if (timezone.includes('Europe')) return 'eu';
+ if (timezone.includes('Asia') || timezone.includes('Australia')) return 'apac';
+
+ return 'default';
+}
+
+// In your component
+analytics.track('dl_purchase', {
+ ecommerce: {
+ value: 99.99,
+ currency: 'USD',
+ items: [
+ { item_id: 'SKU123', item_name: 'Product', quantity: 1, price: 99.99 }
+ ]
+ }
+});
+```
+
+## Troubleshooting
+
+### Events Not Being Sent
+
+**Problem**: Analytics events are not reaching your endpoint.
+
+**Solutions**:
+1. **Check endpoint URL**: Ensure the `endpoint` is correct and accessible
+ ```javascript
+ // Test in browser console
+ fetch('https://api.yourapp.com/analytics', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ test: true })
+ })
+ ```
+
+2. **Verify CORS headers**: Ensure your endpoint allows requests from your domain
+ ```
+ Access-Control-Allow-Origin: *
+ Access-Control-Allow-Methods: POST, OPTIONS
+ Access-Control-Allow-Headers: Content-Type, Authorization
+ ```
+
+3. **Check browser console**: Look for network errors (404, 403, CORS errors)
+ - Open DevTools → Network tab → Filter for your endpoint
+ - Check Request/Response headers and body
+
+4. **Verify configuration**: Ensure custom provider is enabled
+ ```javascript
+ providers: {
+ custom: {
+ enabled: true, // Must be true
+ settings: { ... }
+ }
+ }
+ ```
+
+### 401 Unauthorized Errors
+
+**Problem**: Requests are rejected with 401 status.
+
+**Solutions**:
+1. **Check authorization header**:
+ ```javascript
+ headers: {
+ 'Authorization': 'Bearer YOUR_VALID_TOKEN' // Use actual token
+ }
+ ```
+
+2. **Verify token expiration**: Ensure tokens are refreshed periodically
+ ```javascript
+ headers: {
+ 'Authorization': `Bearer ${getValidToken()}`
+ }
+ ```
+
+3. **Test endpoint authentication**:
+ ```bash
+ curl -X POST https://api.yourapp.com/analytics \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"events": [], "batch_info": {}}'
+ ```
+
+### Retries Not Working
+
+**Problem**: Failed requests are not being retried.
+
+**Solutions**:
+1. **Check retry configuration**:
+ ```javascript
+ maxRetries: 3, // Must be > 0
+ retryDelayMs: 1000 // Must be positive
+ ```
+
+2. **Check status codes**: SDK only retries on 5xx, timeouts, and network errors
+ - 4xx errors (except some specific cases) are not retried
+ - 2xx responses are considered success
+
+3. **Monitor retry logs**: Enable debug logging (if available)
+ ```javascript
+ // Check browser DevTools console for messages like:
+ // "Analytics: Retrying batch (attempt 2 of 3)..."
+ ```
+
+### High Event Loss
+
+**Problem**: Events are being dropped before reaching your endpoint.
+
+**Solutions**:
+1. **Increase batch time limits**:
+ ```javascript
+ // Give more time before dropping
+ batchIntervalMs: 10000, // Increased from 5000
+ maxRetries: 5 // More retry attempts
+ ```
+
+2. **Implement page unload handler** (SDK should handle this automatically)
+
+3. **Check transform function**: Ensure it's not filtering out events
+ ```javascript
+ transformFunction: (event) => {
+ console.log('Event:', event); // Debug what's being sent
+ return event;
+ }
+ ```
+
+### Transform Function Issues
+
+**Problem**: Events are being modified incorrectly or transform function has errors.
+
+**Solutions**:
+1. **Add error handling**:
+ ```javascript
+ transformFunction: (event) => {
+ try {
+ // Your transform logic
+ return {
+ ...event,
+ custom_field: calculateValue(event)
+ };
+ } catch (error) {
+ console.error('Transform error:', error);
+ return event; // Return original if transform fails
+ }
+ }
+ ```
+
+2. **Validate return value**: Always return an event object or null
+ ```javascript
+ transformFunction: (event) => {
+ // WRONG: return undefined
+ // CORRECT: return event or null
+
+ if (shouldDropEvent(event)) {
+ return null;
+ }
+
+ return modifiedEvent;
+ }
+ ```
+
+3. **Test transform function independently**:
+ ```javascript
+ const testEvent = { event: 'dl_view_item', ... };
+ const result = transformFunction(testEvent);
+ console.log('Transform result:', result);
+ ```
+
+### Endpoint Timeouts
+
+**Problem**: Requests are timing out and being retried excessively.
+
+**Solutions**:
+1. **Reduce batch size**:
+ ```javascript
+ batchSize: 5, // Smaller payloads = faster processing
+ ```
+
+2. **Increase request timeout** (if configurable):
+ ```javascript
+ requestTimeoutMs: 10000 // 10 second timeout
+ ```
+
+3. **Check backend performance**:
+ ```bash
+ # Monitor endpoint response times
+ curl -w "@curl-format.txt" -o /dev/null -s \
+ https://api.yourapp.com/analytics
+ ```
+
+4. **Verify network connectivity**: Check if your server can reach the endpoint
+
+### Duplicate Events at Endpoint
+
+**Problem**: Events appear to be received multiple times.
+
+**Solutions**:
+1. **Implement idempotency**:
+ - Use `event_id` field (already unique per event)
+ - Store processed event IDs to detect duplicates
+ ```javascript
+ // In your backend
+ const processedEventIds = new Set();
+
+ if (processedEventIds.has(event.event_id)) {
+ return { success: true }; // Already processed
+ }
+
+ processedEventIds.add(event.event_id);
+ // Process event...
+ ```
+
+2. **Check batch_info**: Events in same batch have unique IDs
+ ```javascript
+ const eventIds = batch.events.map(e => e.event_id);
+ const uniqueIds = new Set(eventIds);
+
+ if (uniqueIds.size !== eventIds.length) {
+ // Handle duplicate detection
+ }
+ ```
+
+3. **Verify retry handling**: Ensure retried batches aren't duplicated
+ - Use batch IDs if implementing retry deduplication
+
+### Backend Not Receiving Headers
+
+**Problem**: Custom headers aren't appearing in requests.
+
+**Solutions**:
+1. **Check header configuration**:
+ ```javascript
+ headers: {
+ 'Authorization': 'Bearer token',
+ 'X-Custom-Header': 'value'
+ }
+ ```
+
+2. **Verify CORS headers** (for browser requests):
+ - `Access-Control-Allow-Headers` must include custom header names
+ ```
+ Access-Control-Allow-Headers: Authorization, Content-Type, X-Custom-Header
+ ```
+
+3. **Check header case sensitivity**: Some servers normalize headers
+ ```javascript
+ // Both work, but be consistent
+ 'Authorization': 'Bearer token'
+ 'authorization': 'Bearer token'
+ ```
+
+### Memory Leaks with Events
+
+**Problem**: Memory usage increases continuously.
+
+**Solutions**:
+1. **Limit batch size**:
+ ```javascript
+ batchSize: 20, // Don't queue too many
+ batchIntervalMs: 3000 // Send more frequently
+ ```
+
+2. **Implement event sampling** in transform function:
+ ```javascript
+ transformFunction: (event) => {
+ // Sample down high-volume events
+ if (event.event === 'dl_page_view' && Math.random() > 0.1) {
+ return null; // Drop 90% of page views
+ }
+ return event;
+ }
+ ```
+
+3. **Check for event listener leaks**: Ensure analytics instance is properly cleaned up
+
+## Best Practices
+
+1. **Always return a 2xx status** from your endpoint when events are received
+2. **Make endpoints idempotent** using event IDs to handle retries safely
+3. **Log all received events** for debugging and auditing
+4. **Monitor endpoint performance** to catch issues early
+5. **Use appropriate batch sizes** based on your network and server capacity
+6. **Implement rate limiting** on your endpoint to prevent abuse
+7. **Validate incoming data** to ensure it matches your schema
+8. **Archive analytics data** for historical analysis
+9. **Alert on errors** (via email, Slack, etc.) for critical endpoints
+10. **Version your endpoint** (e.g., `/api/v1/analytics`) for backward compatibility
diff --git a/docs/campaign-cart/analytics/examples/direct-ga4.md b/docs/campaign-cart/analytics/examples/direct-ga4.md
new file mode 100644
index 00000000..fa8e2964
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/direct-ga4.md
@@ -0,0 +1,465 @@
+---
+title: "Direct GA4 Integration (No GTM)"
+description: "Send events directly to Google Analytics 4 without using Google Tag Manager using an event transformer."
+---
+
+
+## Overview
+
+This guide shows how to send Campaign Cart SDK events directly to Google Analytics 4 **without using Google Tag Manager** by using an event transformer script.
+
+:::tip
+This is a specific implementation of the general [Event Transformers](/docs/campaign-cart/analytics/examples/event-transformers/) pattern. You can use the same approach for TikTok, Snapchat, Pinterest, or any other platform.
+:::
+
+## When to Use This
+
+Use the GA4 Bridge when:
+- You want to send events directly to GA4 without GTM
+- You're already using GA4 and don't want to set up GTM
+- You need simpler setup with fewer moving parts
+- You want to avoid GTM's additional layer
+
+:::tip
+If you're using Google Tag Manager, you don't need this script - the SDK already pushes events to `window.dataLayer` that GTM can consume.
+:::
+
+## Setup
+
+1. **Add Google Analytics 4**
+
+ Add the GA4 tracking code to your page:
+
+ ```html
+
+
+
+ ```
+
+ Replace `G-XXXXXXXXXX` with your GA4 Measurement ID.
+
+2. **Add the Bridge Script**
+
+ Add the NextDataLayer GA4 Bridge script **after** the Campaign Cart SDK:
+
+ ```html
+
+
+
+
+
+ ```
+
+3. **Enable Analytics in SDK Config**
+
+ ```javascript
+ window.nextConfig = {
+ apiKey: 'your-api-key',
+ analytics: {
+ enabled: true,
+ mode: 'auto'
+ }
+ };
+ ```
+
+
+
+That's it! Events will automatically flow from Campaign Cart SDK → NextDataLayer → GA4.
+
+## How It Works
+
+The bridge script:
+
+1. **Waits for NextDataLayer** to be available
+2. **Intercepts events** pushed to `window.NextDataLayer`
+3. **Converts event names** from `dl_*` format to standard GA4 format
+4. **Formats ecommerce data** according to GA4 specification
+5. **Pushes to window.dataLayer** for GA4 to consume
+6. **Prevents duplicates** using event deduplication
+7. **Handles upsells** by converting them to purchase events
+
+### Event Conversion Flow
+
+```
+Campaign Cart SDK Event
+ ↓
+NextDataLayer (dl_add_to_cart)
+ ↓
+GA4 Bridge Script (converts)
+ ↓
+window.dataLayer (add_to_cart)
+ ↓
+Google Analytics 4
+```
+
+## Event Mapping
+
+The bridge automatically converts SDK events to GA4 standard events:
+
+### E-commerce Events
+
+| SDK Event | GA4 Event | Description |
+|-----------|-----------|-------------|
+| `dl_view_item` | `view_item` | Product viewed |
+| `dl_view_item_list` | `view_item_list` | Product list viewed |
+| `dl_add_to_cart` | `add_to_cart` | Item added to cart |
+| `dl_remove_from_cart` | `remove_from_cart` | Item removed from cart |
+| `dl_view_cart` | `view_cart` | Cart page viewed |
+| `dl_begin_checkout` | `begin_checkout` | Checkout started |
+| `dl_add_shipping_info` | `add_shipping_info` | Shipping info added |
+| `dl_add_payment_info` | `add_payment_info` | Payment info added |
+| `dl_purchase` | `purchase` | Order completed |
+
+### Upsell Events
+
+| SDK Event | GA4 Event | Special Handling |
+|-----------|-----------|------------------|
+| `dl_viewed_upsell` | `view_item` | Upsell viewed as product view |
+| `dl_accepted_upsell` | `purchase` | **Upsell converted to purchase with same transaction_id** |
+
+:::caution
+Upsell events are converted to `purchase` events using the **same transaction_id** as the original purchase. This allows GA4 to track upsells as additional revenue on the same order.
+:::
+
+### User Events
+
+| SDK Event | GA4 Event |
+|-----------|-----------|
+| `dl_sign_up` | `sign_up` |
+| `dl_login` | `login` |
+
+## Features
+
+### 1. Duplicate Prevention
+
+The bridge tracks processed events and prevents duplicates:
+
+```javascript
+// Events are deduplicated using:
+// - Event name
+// - Sequence number
+// - Item ID
+// - Order ID
+```
+
+### 2. Upsell Tracking
+
+Upsells are automatically converted to purchase events with the original transaction ID:
+
+```javascript
+// Original purchase
+{
+ event: 'purchase',
+ transaction_id: 'ORD-12345',
+ value: 99.99
+}
+
+// Upsell (automatically uses same transaction_id)
+{
+ event: 'purchase',
+ transaction_id: 'ORD-12345', // Same as original!
+ value: 29.99,
+ items: [{ item_category: 'Upsell', ... }]
+}
+```
+
+This allows GA4 to track total order value including upsells.
+
+### 3. Ecommerce Object Clearing
+
+The bridge follows GA4 best practices by clearing the ecommerce object before each event:
+
+```javascript
+// Clear ecommerce first
+window.dataLayer.push({ ecommerce: null });
+
+// Then push new event
+window.dataLayer.push({
+ event: 'add_to_cart',
+ ecommerce: { ... }
+});
+```
+
+### 4. Memory Management
+
+Automatically cleans up old data to prevent memory leaks:
+- Keeps last 500 processed events
+- Keeps last 50 transaction IDs
+- Runs cleanup every 60 seconds
+
+### 5. Debug Mode
+
+Debug logging is automatically enabled on:
+- `localhost`
+- URLs with `?debug=true`
+
+View logs in browser console:
+
+```
+[GA4 Bridge] Initializing dataLayer bridge
+[GA4 Bridge] Converted dl_add_to_cart → add_to_cart
+[GA4 Bridge] Upsell converted to purchase with transaction_id: ORD-12345
+```
+
+## Bridge API
+
+The bridge exposes debugging utilities on `window.GA4Bridge`:
+
+### Get Processed Event Count
+
+```javascript
+const count = window.GA4Bridge.getProcessedCount();
+console.log(`Processed ${count} events`);
+```
+
+### View Event Mapping
+
+```javascript
+const mapping = window.GA4Bridge.getEventMap();
+console.log(mapping);
+// {
+// 'dl_add_to_cart': 'add_to_cart',
+// 'dl_purchase': 'purchase',
+// ...
+// }
+```
+
+### View Transaction Map
+
+```javascript
+const transactions = window.GA4Bridge.getTransactionMap();
+console.log(transactions);
+// {
+// '123': { transaction_id: 'ORD-12345', order_number: '12345' },
+// ...
+// }
+```
+
+### Check Bridge Status
+
+```javascript
+const isActive = window.GA4Bridge.isActive();
+console.log(`Bridge active: ${isActive}`);
+```
+
+## Example Event Flow
+
+### Cart Event
+
+SDK fires:
+```javascript
+window.NextDataLayer.push({
+ event: 'dl_add_to_cart',
+ event_id: '1234567890_abc123',
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [{
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1
+ }]
+ }
+});
+```
+
+Bridge converts to:
+```javascript
+window.dataLayer.push({ ecommerce: null }); // Clear first
+window.dataLayer.push({
+ event: 'add_to_cart',
+ event_id: '1234567890_abc123',
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [{
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1
+ }]
+ }
+});
+```
+
+### Purchase Event
+
+SDK fires:
+```javascript
+window.NextDataLayer.push({
+ event: 'dl_purchase',
+ ecommerce: {
+ transaction_id: 'ORD-12345',
+ order_number: '12345',
+ value: 159.99,
+ currency: 'USD',
+ tax: 9.99,
+ shipping: 10.00,
+ items: [...]
+ }
+});
+```
+
+Bridge stores transaction ID and converts to:
+```javascript
+window.dataLayer.push({ ecommerce: null });
+window.dataLayer.push({
+ event: 'purchase',
+ ecommerce: {
+ transaction_id: 'ORD-12345',
+ order_number: '12345',
+ value: 159.99,
+ currency: 'USD',
+ tax: 9.99,
+ shipping: 10.00,
+ items: [...]
+ }
+});
+```
+
+### Upsell Event
+
+SDK fires:
+```javascript
+window.NextDataLayer.push({
+ event: 'dl_accepted_upsell',
+ order_id: '123',
+ upsell: {
+ package_id: 'warranty-extended',
+ package_name: 'Extended Warranty',
+ price: 29.99,
+ quantity: 1
+ }
+});
+```
+
+Bridge converts to:
+```javascript
+window.dataLayer.push({ ecommerce: null });
+window.dataLayer.push({
+ event: 'purchase', // Converted to purchase!
+ ecommerce: {
+ transaction_id: 'ORD-12345', // Same as original purchase
+ order_number: '12345',
+ value: 29.99,
+ currency: 'USD',
+ items: [{
+ item_id: 'warranty-extended',
+ item_name: 'Extended Warranty',
+ price: 29.99,
+ quantity: 1,
+ item_category: 'Upsell'
+ }]
+ }
+});
+```
+
+## Troubleshooting
+
+### Events Not Appearing in GA4
+
+1. **Check GA4 is loaded**
+ ```javascript
+ console.log(typeof gtag); // Should be 'function'
+ ```
+
+2. **Check bridge is active**
+ ```javascript
+ console.log(window.GA4Bridge.isActive()); // Should be true
+ ```
+
+3. **Check events are being converted**
+ - Open browser console
+ - Add `?debug=true` to URL
+ - Look for `[GA4 Bridge]` log messages
+
+4. **Verify NextDataLayer exists**
+ ```javascript
+ console.log(window.NextDataLayer); // Should be an array
+ ```
+
+### Duplicate Events
+
+The bridge automatically prevents duplicates, but if you see duplicates:
+
+1. Make sure you're only loading the bridge script once
+2. Check that you're not also pushing events to `window.dataLayer` manually
+3. Verify the bridge is loaded after the SDK
+
+### Upsells Not Tracking
+
+If upsells aren't showing up as purchases:
+
+1. **Check transaction map**
+ ```javascript
+ console.log(window.GA4Bridge.getTransactionMap());
+ ```
+
+2. **Verify purchase event fired first**
+ - The initial purchase must fire before upsells
+ - Transaction ID is stored from the purchase event
+
+3. **Check order_id is present**
+ - Upsell events need `order_id` to look up transaction_id
+
+### Missing Transaction IDs
+
+If upsells show `undefined` transaction_id:
+
+- The initial `dl_purchase` event must include `ecommerce.transaction_id`
+- The upsell event must include `order_id` matching the purchase
+- Check the transaction map: `window.GA4Bridge.getTransactionMap()`
+
+## Performance
+
+The bridge is lightweight and efficient:
+- **~5KB** minified
+- Processes events in **<1ms**
+- Memory-safe with automatic cleanup
+- No external dependencies
+
+## Comparison: Bridge vs GTM
+
+| Feature | GA4 Bridge | Google Tag Manager |
+|---------|------------|-------------------|
+| Setup complexity | Simple (1 script) | Complex (container setup) |
+| Event conversion | Automatic | Manual triggers/tags |
+| Upsell handling | Built-in | Manual configuration |
+| Deduplication | Automatic | Must configure |
+| Additional tracking | Limited | Unlimited |
+| Tag management | None | Full tag management |
+| Best for | Direct GA4 | Multiple platforms |
+
+## When NOT to Use This
+
+Don't use the GA4 Bridge if:
+- You're already using GTM successfully
+- You need to send data to multiple platforms (Facebook, TikTok, etc.)
+- You need complex tag management and triggering
+- You want to manage tags without code deployments
+
+In these cases, use Google Tag Manager instead. See [Google Tag Manager Setup](/docs/campaign-cart/analytics/examples/google-tag-manager/).
+
+## Build Your Own Transformer
+
+Want to adapt this pattern for other platforms (TikTok, Snapchat, Pinterest)?
+
+See **[Event Transformers](/docs/campaign-cart/analytics/examples/event-transformers/)** for:
+- Generic transformer template
+- Examples for TikTok, Snapchat, Pinterest
+- Multi-platform routing
+- Best practices and patterns
+
+## Related Documentation
+
+- **[Event Transformers](/docs/campaign-cart/analytics/examples/event-transformers/)** - General pattern for any platform
+- [Google Tag Manager Setup](/docs/campaign-cart/analytics/examples/google-tag-manager/) - Alternative using GTM
+- [Analytics Overview](/docs/campaign-cart/analytics/) - Main analytics documentation
+- [Event Reference](/docs/campaign-cart/analytics/events/) - All available events
+- [Configuration](/docs/campaign-cart/analytics/configuration/) - SDK configuration options
diff --git a/docs/campaign-cart/analytics/examples/event-transformers.md b/docs/campaign-cart/analytics/examples/event-transformers.md
new file mode 100644
index 00000000..575b81c8
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/event-transformers.md
@@ -0,0 +1,681 @@
+---
+title: "Event Transformers"
+description: "Build custom event transformers to convert NextDataLayer events to any platform's format."
+sidebar_position: 13
+---
+
+## Overview
+
+Event transformers are scripts that intercept events from `window.NextDataLayer` and convert them to formats required by different analytics platforms. This pattern allows you to:
+
+- Send events to platforms not natively supported by the SDK
+- Convert SDK events to platform-specific formats
+- Add custom logic for event processing
+- Route events to multiple destinations with different formats
+
+## How It Works
+
+The transformer pattern:
+
+1. **Waits** for `window.NextDataLayer` to be available
+2. **Intercepts** events by overriding the `push()` method
+3. **Transforms** events to platform-specific format
+4. **Routes** transformed events to the destination
+5. **Prevents duplicates** using event deduplication
+
+### Basic Flow
+
+```
+Campaign Cart SDK
+ ↓
+window.NextDataLayer.push()
+ ↓
+Transformer (intercepts)
+ ↓
+Convert format
+ ↓
+window.platformLayer.push()
+ ↓
+Platform (GA4, TikTok, etc.)
+```
+
+## Basic Transformer Template
+
+Here's a generic template you can adapt for any platform:
+
+```javascript
+(function() {
+ 'use strict';
+
+ // Track processed events to avoid duplicates
+ const processedEvents = new Set();
+
+ // Your event mapping
+ const EVENT_MAP = {
+ 'dl_view_item': 'ViewContent', // Platform-specific name
+ 'dl_add_to_cart': 'AddToCart',
+ 'dl_purchase': 'Purchase'
+ // Add more mappings...
+ };
+
+ // Wait for NextDataLayer
+ const initTransformer = () => {
+ if (!window.NextDataLayer) {
+ setTimeout(initTransformer, 100);
+ return;
+ }
+
+ console.log('[Transformer] Initializing...');
+
+ // Override the push method
+ const originalPush = window.NextDataLayer.push;
+
+ window.NextDataLayer.push = function(...args) {
+ // Call original push first
+ const result = originalPush.apply(window.NextDataLayer, args);
+
+ // Process each pushed item
+ args.forEach(item => {
+ if (item && typeof item === 'object' && item.event) {
+ processEvent(item);
+ }
+ });
+
+ return result;
+ };
+
+ // Process existing events
+ window.NextDataLayer.forEach(item => {
+ if (item && typeof item === 'object' && item.event) {
+ processEvent(item);
+ }
+ });
+
+ console.log('[Transformer] Initialized successfully');
+ };
+
+ // Process individual events
+ const processEvent = (event) => {
+ // Skip if not mapped
+ if (!EVENT_MAP[event.event]) {
+ return;
+ }
+
+ // Create unique ID to prevent duplicates
+ const eventId = `${event.event}_${event._metadata?.sequence_number || Date.now()}`;
+
+ if (processedEvents.has(eventId)) {
+ return;
+ }
+
+ processedEvents.add(eventId);
+
+ // Get platform-specific event name
+ const platformEventName = EVENT_MAP[event.event];
+
+ // Build platform-specific event
+ const platformEvent = {
+ event: platformEventName,
+ // Add your platform-specific fields...
+ };
+
+ // Send to platform (customize this!)
+ window.yourPlatformLayer = window.yourPlatformLayer || [];
+ window.yourPlatformLayer.push(platformEvent);
+
+ console.log(`[Transformer] Converted ${event.event} → ${platformEventName}`, platformEvent);
+ };
+
+ // Clean up old events periodically (prevent memory leak)
+ setInterval(() => {
+ if (processedEvents.size > 1000) {
+ const entriesToKeep = Array.from(processedEvents).slice(-500);
+ processedEvents.clear();
+ entriesToKeep.forEach(entry => processedEvents.add(entry));
+ }
+ }, 60000);
+
+ // Start the transformer
+ initTransformer();
+})();
+```
+
+## Platform-Specific Examples
+
+### GA4 Transformer
+
+Convert events to Google Analytics 4 format and send to `window.dataLayer`:
+
+```javascript
+const EVENT_MAP = {
+ 'dl_add_to_cart': 'add_to_cart',
+ 'dl_remove_from_cart': 'remove_from_cart',
+ 'dl_view_item': 'view_item',
+ 'dl_view_item_list': 'view_item_list',
+ 'dl_begin_checkout': 'begin_checkout',
+ 'dl_purchase': 'purchase',
+ 'dl_add_payment_info': 'add_payment_info',
+ 'dl_add_shipping_info': 'add_shipping_info',
+ 'dl_login': 'login',
+ 'dl_sign_up': 'sign_up'
+};
+
+const processEvent = (event) => {
+ if (!EVENT_MAP[event.event]) return;
+
+ const ga4Event = {
+ event: EVENT_MAP[event.event],
+ event_id: event.event_id
+ };
+
+ // Handle ecommerce events
+ if (event.ecommerce) {
+ // Clear ecommerce first (GTM best practice)
+ window.dataLayer.push({ ecommerce: null });
+
+ ga4Event.ecommerce = {
+ ...event.ecommerce,
+ items: event.ecommerce.items?.map(item => ({
+ item_id: item.item_id || item.id,
+ item_name: item.item_name || item.name,
+ price: item.price,
+ quantity: item.quantity,
+ currency: item.currency
+ }))
+ };
+ }
+
+ window.dataLayer.push(ga4Event);
+};
+```
+
+### TikTok Pixel Transformer
+
+Convert events to TikTok Pixel format:
+
+```javascript
+const EVENT_MAP = {
+ 'dl_view_item': 'ViewContent',
+ 'dl_add_to_cart': 'AddToCart',
+ 'dl_begin_checkout': 'InitiateCheckout',
+ 'dl_purchase': 'CompletePayment',
+ 'dl_view_item_list': 'ViewContent'
+};
+
+const processEvent = (event) => {
+ if (!EVENT_MAP[event.event]) return;
+
+ const tiktokEventName = EVENT_MAP[event.event];
+
+ // Build TikTok event data
+ const tiktokData = {
+ content_type: 'product'
+ };
+
+ if (event.ecommerce) {
+ tiktokData.currency = event.ecommerce.currency;
+ tiktokData.value = event.ecommerce.value;
+
+ if (event.ecommerce.items?.[0]) {
+ tiktokData.content_id = event.ecommerce.items[0].item_id;
+ tiktokData.content_name = event.ecommerce.items[0].item_name;
+ }
+
+ // For purchase events
+ if (event.event === 'dl_purchase') {
+ tiktokData.content_ids = event.ecommerce.items?.map(i => i.item_id);
+ tiktokData.contents = event.ecommerce.items?.map(i => ({
+ content_id: i.item_id,
+ content_name: i.item_name,
+ quantity: i.quantity,
+ price: i.price
+ }));
+ }
+ }
+
+ // Send to TikTok Pixel
+ if (window.ttq) {
+ window.ttq.track(tiktokEventName, tiktokData);
+ console.log(`[TikTok] ${event.event} → ${tiktokEventName}`, tiktokData);
+ }
+};
+```
+
+### Snapchat Pixel Transformer
+
+Convert events to Snapchat Pixel format:
+
+```javascript
+const EVENT_MAP = {
+ 'dl_view_item': 'VIEW_CONTENT',
+ 'dl_add_to_cart': 'ADD_CART',
+ 'dl_begin_checkout': 'START_CHECKOUT',
+ 'dl_purchase': 'PURCHASE',
+ 'dl_sign_up': 'SIGN_UP'
+};
+
+const processEvent = (event) => {
+ if (!EVENT_MAP[event.event]) return;
+
+ const snapEventName = EVENT_MAP[event.event];
+
+ const snapData = {};
+
+ if (event.ecommerce) {
+ snapData.currency = event.ecommerce.currency;
+ snapData.price = event.ecommerce.value;
+
+ if (event.ecommerce.transaction_id) {
+ snapData.transaction_id = event.ecommerce.transaction_id;
+ }
+
+ if (event.ecommerce.items?.length > 0) {
+ snapData.item_ids = event.ecommerce.items.map(i => i.item_id);
+ snapData.item_category = event.ecommerce.items[0].item_category;
+ snapData.number_items = event.ecommerce.items.length;
+ }
+ }
+
+ // Send to Snapchat Pixel
+ if (window.snaptr) {
+ window.snaptr('track', snapEventName, snapData);
+ console.log(`[Snapchat] ${event.event} → ${snapEventName}`, snapData);
+ }
+};
+```
+
+### Pinterest Tag Transformer
+
+Convert events to Pinterest Tag format:
+
+```javascript
+const EVENT_MAP = {
+ 'dl_view_item': 'pagevisit',
+ 'dl_add_to_cart': 'addtocart',
+ 'dl_begin_checkout': 'checkout',
+ 'dl_purchase': 'checkout',
+ 'dl_sign_up': 'signup',
+ 'dl_view_item_list': 'viewcategory'
+};
+
+const processEvent = (event) => {
+ if (!EVENT_MAP[event.event]) return;
+
+ const pinterestEventName = EVENT_MAP[event.event];
+
+ const pinterestData = {};
+
+ if (event.ecommerce) {
+ pinterestData.currency = event.ecommerce.currency;
+ pinterestData.value = event.ecommerce.value;
+
+ if (event.ecommerce.items?.length > 0) {
+ pinterestData.line_items = event.ecommerce.items.map(item => ({
+ product_name: item.item_name,
+ product_id: item.item_id,
+ product_price: item.price,
+ product_quantity: item.quantity
+ }));
+ }
+
+ if (event.event === 'dl_purchase' && event.ecommerce.transaction_id) {
+ pinterestData.order_id = event.ecommerce.transaction_id;
+ pinterestData.order_quantity = event.ecommerce.items?.reduce((sum, i) => sum + i.quantity, 0);
+ }
+ }
+
+ // Send to Pinterest Tag
+ if (window.pintrk) {
+ window.pintrk('track', pinterestEventName, pinterestData);
+ console.log(`[Pinterest] ${event.event} → ${pinterestEventName}`, pinterestData);
+ }
+};
+```
+
+## Advanced Patterns
+
+### Multi-Platform Transformer
+
+Send events to multiple platforms from one transformer:
+
+```javascript
+const processEvent = (event) => {
+ // Send to GA4
+ if (window.dataLayer && GA4_EVENT_MAP[event.event]) {
+ const ga4Event = buildGA4Event(event);
+ window.dataLayer.push(ga4Event);
+ }
+
+ // Send to TikTok
+ if (window.ttq && TIKTOK_EVENT_MAP[event.event]) {
+ const tiktokData = buildTikTokEvent(event);
+ window.ttq.track(TIKTOK_EVENT_MAP[event.event], tiktokData);
+ }
+
+ // Send to Snapchat
+ if (window.snaptr && SNAP_EVENT_MAP[event.event]) {
+ const snapData = buildSnapEvent(event);
+ window.snaptr('track', SNAP_EVENT_MAP[event.event], snapData);
+ }
+};
+```
+
+### Conditional Routing
+
+Route events based on conditions:
+
+```javascript
+const processEvent = (event) => {
+ // Only send high-value purchases to premium platforms
+ if (event.event === 'dl_purchase' && event.ecommerce?.value > 1000) {
+ sendToPremiumPlatform(event);
+ }
+
+ // Send all events to GA4
+ sendToGA4(event);
+
+ // Filter test users
+ if (event.user_properties?.customer_email?.includes('@test.com')) {
+ return; // Don't send to paid platforms
+ }
+
+ sendToFacebookPixel(event);
+};
+```
+
+### Event Enrichment
+
+Add additional data before sending:
+
+```javascript
+const processEvent = (event) => {
+ // Enrich with custom data
+ const enrichedEvent = {
+ ...event,
+ app_version: window.APP_VERSION,
+ environment: window.ENV,
+ user_segment: getUserSegment(),
+ ab_test_variant: getActiveVariant()
+ };
+
+ // Send enriched event
+ sendToPlatform(enrichedEvent);
+};
+```
+
+## Installation
+
+1. **Create transformer script**
+
+ Save your transformer as a `.js` file (e.g., `transformer-tiktok.js`)
+
+2. **Add to page after SDK**
+
+ ```html
+
+
+
+
+
+ ```
+
+3. **Load platform script**
+
+ Ensure the target platform's script loads before the transformer:
+
+ ```html
+
+
+
+
+
+
+
+
+ ```
+
+## Best Practices
+
+### 1. Deduplicate Events
+
+Always track processed events to prevent duplicates:
+
+```javascript
+const processedEvents = new Set();
+
+const processEvent = (event) => {
+ const eventId = `${event.event}_${event._metadata?.sequence_number}`;
+
+ if (processedEvents.has(eventId)) {
+ return; // Skip duplicate
+ }
+
+ processedEvents.add(eventId);
+ // Process event...
+};
+```
+
+### 2. Clean Up Memory
+
+Prevent memory leaks by periodically cleaning old data:
+
+```javascript
+setInterval(() => {
+ if (processedEvents.size > 1000) {
+ const entriesToKeep = Array.from(processedEvents).slice(-500);
+ processedEvents.clear();
+ entriesToKeep.forEach(entry => processedEvents.add(entry));
+ }
+}, 60000); // Every minute
+```
+
+### 3. Handle Missing Data
+
+Gracefully handle missing or malformed data:
+
+```javascript
+const processEvent = (event) => {
+ if (!event || !event.event) {
+ console.warn('[Transformer] Invalid event', event);
+ return;
+ }
+
+ const value = event.ecommerce?.value ?? 0;
+ const items = event.ecommerce?.items || [];
+
+ // Use defaults...
+};
+```
+
+### 4. Debug Logging
+
+Add conditional debug logging:
+
+```javascript
+const DEBUG = window.location.hostname === 'localhost' ||
+ window.location.search.includes('debug=true');
+
+const processEvent = (event) => {
+ // Process event...
+
+ if (DEBUG) {
+ console.log(`[Transformer] Converted ${event.event}`, platformEvent);
+ }
+};
+```
+
+### 5. Error Handling
+
+Wrap platform calls in try-catch:
+
+```javascript
+const processEvent = (event) => {
+ try {
+ const platformEvent = buildEvent(event);
+ window.platform.track(platformEvent);
+ } catch (error) {
+ console.error('[Transformer] Error processing event:', error, event);
+ // Don't throw - let other code continue
+ }
+};
+```
+
+## Debugging
+
+### Check Transformer Status
+
+```javascript
+// Check if NextDataLayer exists
+console.log(window.NextDataLayer);
+
+// Check if transformer modified push
+console.log(window.NextDataLayer.push.toString());
+
+// View all events
+console.log(window.NextDataLayer);
+```
+
+### Enable Debug Mode
+
+Add `?debug=true` to your URL to see console logs:
+
+```
+https://yoursite.com?debug=true
+```
+
+### Verify Platform Script Loaded
+
+```javascript
+// TikTok
+console.log(typeof window.ttq); // Should be 'object'
+
+// Snapchat
+console.log(typeof window.snaptr); // Should be 'function'
+
+// Pinterest
+console.log(typeof window.pintrk); // Should be 'function'
+
+// GA4
+console.log(typeof window.gtag); // Should be 'function'
+```
+
+## Full Example: TikTok Transformer
+
+Complete working example for TikTok Pixel:
+
+```javascript
+(function() {
+ 'use strict';
+
+ const processedEvents = new Set();
+ const DEBUG = window.location.search.includes('debug=true');
+
+ const EVENT_MAP = {
+ 'dl_view_item': 'ViewContent',
+ 'dl_add_to_cart': 'AddToCart',
+ 'dl_begin_checkout': 'InitiateCheckout',
+ 'dl_purchase': 'CompletePayment'
+ };
+
+ const initTransformer = () => {
+ if (!window.NextDataLayer) {
+ setTimeout(initTransformer, 100);
+ return;
+ }
+
+ if (DEBUG) console.log('[TikTok Transformer] Initializing...');
+
+ const originalPush = window.NextDataLayer.push;
+
+ window.NextDataLayer.push = function(...args) {
+ const result = originalPush.apply(window.NextDataLayer, args);
+
+ args.forEach(item => {
+ if (item && typeof item === 'object' && item.event) {
+ processEvent(item);
+ }
+ });
+
+ return result;
+ };
+
+ window.NextDataLayer.forEach(item => {
+ if (item && typeof item === 'object' && item.event) {
+ processEvent(item);
+ }
+ });
+
+ if (DEBUG) console.log('[TikTok Transformer] Initialized');
+ };
+
+ const processEvent = (event) => {
+ if (!EVENT_MAP[event.event]) return;
+
+ const eventId = `${event.event}_${event._metadata?.sequence_number || Date.now()}`;
+ if (processedEvents.has(eventId)) return;
+ processedEvents.add(eventId);
+
+ const tiktokEventName = EVENT_MAP[event.event];
+ const tiktokData = {
+ content_type: 'product'
+ };
+
+ if (event.ecommerce) {
+ tiktokData.currency = event.ecommerce.currency || 'USD';
+ tiktokData.value = event.ecommerce.value || 0;
+
+ if (event.ecommerce.items?.length > 0) {
+ tiktokData.content_id = event.ecommerce.items[0].item_id;
+ tiktokData.content_name = event.ecommerce.items[0].item_name;
+
+ if (event.event === 'dl_purchase') {
+ tiktokData.content_ids = event.ecommerce.items.map(i => i.item_id);
+ tiktokData.contents = event.ecommerce.items.map(i => ({
+ content_id: i.item_id,
+ content_name: i.item_name,
+ quantity: i.quantity,
+ price: i.price
+ }));
+ }
+ }
+ }
+
+ try {
+ if (window.ttq) {
+ window.ttq.track(tiktokEventName, tiktokData);
+ if (DEBUG) {
+ console.log(`[TikTok] ${event.event} → ${tiktokEventName}`, tiktokData);
+ }
+ }
+ } catch (error) {
+ console.error('[TikTok Transformer] Error:', error);
+ }
+ };
+
+ setInterval(() => {
+ if (processedEvents.size > 1000) {
+ const entriesToKeep = Array.from(processedEvents).slice(-500);
+ processedEvents.clear();
+ entriesToKeep.forEach(entry => processedEvents.add(entry));
+ }
+ }, 60000);
+
+ initTransformer();
+})();
+```
+
+## Download Example Scripts
+
+Get ready-to-use transformer scripts:
+- **[Analytics Overview](/docs/campaign-cart/analytics/)** - Analytics setup and configuration
+- **TikTok Transformer** - Copy from example above
+- **Snapchat Transformer** - Copy from example above
+- **Pinterest Transformer** - Copy from example above
+
+## Related Documentation
+
+- [Analytics Overview](/docs/campaign-cart/analytics/) - Main analytics documentation
+- [Custom Events](/docs/campaign-cart/analytics/custom-events/) - Creating custom events
+- [Examples](/docs/campaign-cart/analytics/examples/) - Built-in provider integrations
+- [Configuration](/docs/campaign-cart/analytics/configuration/) - SDK configuration options
+
diff --git a/docs/campaign-cart/analytics/examples/facebook-pixel.md b/docs/campaign-cart/analytics/examples/facebook-pixel.md
new file mode 100644
index 00000000..7d732729
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/facebook-pixel.md
@@ -0,0 +1,170 @@
+---
+title: "Facebook Pixel Setup"
+description: "Integrate Facebook Pixel with automatic event mapping and purchase deduplication."
+---
+
+
+## Setup
+
+1. **Add Facebook Pixel Base Code**
+
+ ```html
+
+
+ ```
+
+2. **Configure SDK**
+
+ ```javascript
+ window.nextConfig = {
+ storeName: 'my-store', // IMPORTANT for deduplication!
+ analytics: {
+ providers: {
+ facebook: {
+ enabled: true,
+ settings: {
+ pixelId: 'YOUR_PIXEL_ID'
+ },
+ blockedEvents: [] // Optional
+ }
+ }
+ }
+ };
+ ```
+
+
+
+:::tip
+Make sure to replace `YOUR_PIXEL_ID` with your actual Facebook Pixel ID from your Meta Business Manager account.
+:::
+
+## Event Mapping
+
+SDK events are automatically mapped to Facebook standard events:
+
+| SDK Event | Facebook Event | Type |
+|-----------|----------------|------|
+| `dl_view_item` | `ViewContent` | Standard |
+| `dl_add_to_cart` | `AddToCart` | Standard |
+| `dl_begin_checkout` | `InitiateCheckout` | Standard |
+| `dl_add_shipping_info` | `AddShippingInfo` | Custom |
+| `dl_add_payment_info` | `AddPaymentInfo` | Standard |
+| `dl_purchase` | `Purchase` | Standard |
+| `dl_sign_up` | `CompleteRegistration` | Standard |
+
+This mapping tracks store events in Facebook Analytics without additional configuration.
+
+## Purchase Deduplication
+
+The SDK uses `eventID` to prevent duplicate purchase tracking:
+
+```javascript
+// SDK automatically generates eventID
+fbq('track', 'Purchase', {
+ value: 159.99,
+ currency: 'USD'
+}, {
+ eventID: 'my-store-12345' // Format: {storeName}-{orderNumber}
+});
+```
+
+**Why storeName is required:**
+- Creates unique eventIDs across different stores
+- Prevents Facebook from counting the same purchase twice
+- Required for server-side API deduplication
+- Without it, deduplication may fail
+
+:::caution
+The `storeName` configuration is required for Facebook Pixel purchase deduplication. Without it, Facebook may count the same purchase multiple times across your sales channels (web, mobile, server-side events). Set `storeName` to a unique identifier for your store before deploying to production.
+:::
+
+## Event Format Example
+
+Facebook Pixel events are formatted with these properties:
+
+```javascript
+fbq('track', 'AddToCart', {
+ content_type: 'product',
+ content_ids: ['SKU-123'],
+ content_name: 'Product Name',
+ value: 99.99,
+ currency: 'USD',
+ contents: [{
+ id: 'SKU-123',
+ quantity: 1,
+ item_price: 99.99
+ }]
+});
+```
+
+### Event Property Details
+
+- **content_type**: Type of content (e.g., 'product', 'product_group')
+- **content_ids**: Array of product SKUs or IDs
+- **content_name**: Name of the product or content
+- **value**: Total value of the event
+- **currency**: Currency code (e.g., 'USD', 'EUR')
+- **contents**: Array of items with quantity and pricing details
+
+## Blocked Events
+
+Prevent specific events from being sent to Facebook Pixel using the `blockedEvents` configuration:
+
+```javascript
+facebook: {
+ enabled: true,
+ settings: { pixelId: 'xxx' },
+ blockedEvents: ['dl_test_event', 'internal_event']
+}
+```
+
+This is useful for:
+- Preventing test events from affecting analytics
+- Blocking internal tracking events not relevant to Facebook
+- Reducing event volume and optimizing tracking
+
+## Troubleshooting
+
+### Events Not Appearing in Facebook Analytics
+
+1. **Verify Pixel ID**: Ensure your `pixelId` is correct in the configuration
+2. **Check storeName**: Confirm that `storeName` is set in your config - missing this can cause events to be blocked or deduplicated unexpectedly
+3. **Test with Facebook Pixel Helper**: Use the [Facebook Pixel Helper Chrome extension](https://chrome.google.com/webstore/detail/facebook-pixel-helper/fdgodlnavgvnoonakpplpknkeae6764d) to verify events are firing
+4. **Review Browser Console**: Check for JavaScript errors that might prevent events from sending
+
+### Purchase Deduplication Not Working
+
+- **Ensure storeName is configured**: This is the primary reason deduplication fails
+- **Verify eventID format**: Should be `{storeName}-{orderNumber}` (e.g., `my-store-12345`)
+- **Check server-side events**: If you're also sending events server-side, ensure consistent storeName and eventID
+- **Allow time for deduplication**: Facebook's deduplication can take up to 24 hours to process
+
+### Low Purchase Conversion Events
+
+- **Verify currency code**: Ensure the currency matches your Facebook Pixel settings
+- **Check content details**: Make sure `contents` array includes all required item information
+- **Review blocked events**: Ensure `dl_purchase` is not in your `blockedEvents` list
+- **Validate event values**: Confirm that transaction values are being passed correctly
+
+### Multiple Events Firing for Same Action
+
+1. Check that you're not initializing the Facebook Pixel multiple times
+2. Verify that duplicate SDK instances aren't running
+3. Review your `blockedEvents` configuration to filter unwanted duplicates
+
+### Contact Support
+
+If you continue experiencing issues:
+- Check your Meta Business Manager logs for event validation errors
+- Consult the [Facebook Pixel documentation](https://developers.facebook.com/docs/facebook-pixel)
+- Reach out to your analytics support team with event payloads for investigation
diff --git a/docs/campaign-cart/analytics/examples/google-tag-manager.md b/docs/campaign-cart/analytics/examples/google-tag-manager.md
new file mode 100644
index 00000000..0d42d460
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/google-tag-manager.md
@@ -0,0 +1,325 @@
+---
+title: "Google Tag Manager Setup"
+description: "Complete guide to integrating Google Tag Manager with Campaign Cart SDK analytics."
+---
+
+
+## Overview
+
+Google Tag Manager (GTM) is a tag management system that manages marketing tags without modifying code directly. Campaign Cart SDK integrates with GTM by pushing analytics events to the standard data layer.
+
+## Setup
+
+1. **Add GTM Container**
+
+ Add the GTM container snippet to your page **before** the Campaign Cart SDK:
+
+ ```html
+
+
+
+ ```
+
+ Replace `GTM-XXXXXX` with your actual GTM container ID.
+
+2. **Enable GTM in SDK Config**
+
+ ```javascript
+ analytics: {
+ providers: {
+ gtm: {
+ enabled: true,
+ blockedEvents: ['dl_test_event'] // Optional
+ }
+ }
+ }
+ ```
+
+3. **Create GTM Triggers**
+
+ In Google Tag Manager:
+ - Trigger Type: **Custom Event**
+ - Event Name: `dl_*` (matches all events) or specific events like `dl_add_to_cart`
+
+
+
+## Where Events Are Pushed
+
+Events are automatically pushed to **two data layers**:
+
+1. **window.dataLayer** - Standard GTM data layer
+2. **window.ElevarDataLayer** - Elevar-compatible format
+
+This dual-layer approach provides compatibility with both standard GTM implementations and ecommerce tracking platforms.
+
+## Event Format
+
+All events follow this standardized format in the data layer:
+
+```javascript
+{
+ event: 'dl_add_to_cart',
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [...]
+ },
+ user_properties: {
+ visitor_type: 'guest',
+ customer_email: 'user@example.com'
+ },
+ // Attribution fields at root level for easy GTM access
+ utm_source: 'google',
+ utm_medium: 'cpc',
+ funnel: 'main',
+ affiliate: 'partner-123'
+}
+```
+
+### Common Events
+
+The SDK pushes the following event types:
+
+- `dl_view_item` - User views a product
+- `dl_add_to_cart` - Item added to shopping cart
+- `dl_remove_from_cart` - Item removed from cart
+- `dl_view_cart` - User views the cart
+- `dl_begin_checkout` - Checkout process initiated
+- `dl_add_shipping_info` - Shipping information provided
+- `dl_add_payment_info` - Payment information provided
+- `dl_purchase` - Order completed
+
+## GTM Variables
+
+Create these variables in GTM for easy access to event data:
+
+| Variable Name | Type | Value |
+|--------------|------|-------|
+| DL - Event | Data Layer Variable | `event` |
+| DL - Ecommerce | Data Layer Variable | `ecommerce` |
+| DL - User Properties | Data Layer Variable | `user_properties` |
+| DL - UTM Source | Data Layer Variable | `utm_source` |
+| DL - UTM Medium | Data Layer Variable | `utm_medium` |
+| DL - Funnel | Data Layer Variable | `funnel` |
+| DL - Currency | Data Layer Variable | `ecommerce.currency` |
+| DL - Value | Data Layer Variable | `ecommerce.value` |
+| DL - Items | Data Layer Variable | `ecommerce.items` |
+
+### Creating Variables in GTM
+
+1. Open your GTM container
+2. Navigate to **Variables** → **User-Defined Variables**
+3. Click **New** for each variable
+4. Select **Data Layer Variable** as the type
+5. Enter the variable name and path
+6. Save and publish your changes
+
+## GA4 Tag Setup
+
+To send Campaign Cart analytics events to Google Analytics 4:
+
+1. Create GA4 Event Tag
+2. Event Name: `{{DL - Event}}`
+3. Event Parameters:
+ - `currency`: `{{ecommerce.currency}}`
+ - `value`: `{{ecommerce.value}}`
+ - `items`: `{{ecommerce.items}}`
+4. Trigger: Custom Event `dl_*`
+
+### Complete GA4 Configuration Example
+
+```
+Tag Type: Google Analytics: GA4 Event
+Measurement ID: G-XXXXXXXXXX
+Event Name: {{DL - Event}}
+Event Parameters:
+ - currency: {{ecommerce.currency}}
+ - value: {{ecommerce.value}}
+ - items: {{ecommerce.items}}
+ - user_id: {{user_properties.user_id}}
+Trigger: Custom Event matching dl_*
+```
+
+## Blocked Events
+
+Block specific events from being sent to GTM to reduce noise and focus on important conversions:
+
+```javascript
+gtm: {
+ enabled: true,
+ blockedEvents: [
+ 'dl_test_event',
+ 'internal_debug',
+ 'dev_event'
+ ]
+}
+```
+
+### Why Block Events?
+
+- Prevent low-priority events from cluttering your GTM logs
+- Reduce GTM traffic (GTM charges based on page views)
+- Focus on events that matter for your business
+- Block test or debug events from production
+
+## Troubleshooting
+
+### Events Not Appearing in GTM
+
+**Problem**: You've configured GTM but aren't seeing events in the preview/debug mode.
+
+**Solutions**:
+1. Verify the GTM container snippet is loaded **before** the Campaign Cart SDK
+2. Check that `analytics.providers.gtm.enabled` is set to `true`
+3. Verify the GTM container ID is correct (GTM-XXXXXX)
+4. Open GTM Preview mode and reload the page to see real-time events
+5. Check browser console for any JavaScript errors
+
+### Events Not Triggering GA4 Tags
+
+**Problem**: Events appear in GTM but aren't reaching Google Analytics 4.
+
+**Solutions**:
+1. Verify your GA4 Event Tag is created and enabled
+2. Check the trigger configuration - ensure it matches `dl_*` or the specific event name
+3. Verify the Measurement ID in your GA4 tag is correct
+4. Check GA4 real-time report to confirm events are arriving
+5. Ensure Event Parameters are correctly mapped to data layer variables
+
+### Incorrect Event Data
+
+**Problem**: Events are reaching GTM but with missing or incorrect data.
+
+**Solutions**:
+1. Verify data layer variables point to the correct data layer paths
+2. Use GTM's Preview mode to inspect the raw event payload
+3. Check the `ecommerce` object structure matches GA4 requirements
+4. Verify `user_properties` are being populated correctly
+5. Ensure custom dimensions are correctly named and configured
+
+### Performance Issues
+
+**Problem**: Site performance degrades after implementing GTM.
+
+**Solutions**:
+1. Load the GTM container asynchronously (it should load async by default)
+2. Review the number of tags firing on each page
+3. Consider delaying non-critical tag execution
+4. Use GTM's tag sequencing to optimize load order
+5. Monitor tag firing frequency and optimize trigger conditions
+
+## Best Practices
+
+### 1. Use Consistent Event Names
+
+Keep event names consistent:
+
+```javascript
+// Good
+'dl_add_to_cart'
+'dl_purchase'
+'dl_begin_checkout'
+
+// Avoid
+'dl_event1'
+'dl_tracking'
+'dl_data'
+```
+
+### 2. Structure Data Consistently
+
+The ecommerce object should follow the GA4 schema:
+
+```javascript
+ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [
+ {
+ item_id: 'SKU123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1
+ }
+ ]
+}
+```
+
+### 3. Test Before Deploying
+
+1. Use GTM's Preview mode during development
+2. Test each event type on staging
+3. Verify data flows to GA4 before production
+4. Monitor real-time reports after deploying
+
+### 4. Document Your Implementation
+
+Maintain documentation of:
+- Which events you're tracking
+- What GTM variables you created
+- Which tags use which triggers
+- Any custom event modifications
+
+### 5. Monitor and Iterate
+
+- Regularly review GTM reports for data quality
+- Check GA4 for anomalies or missing events
+- Adjust blockedEvents list based on actual needs
+- Update documentation as your implementation evolves
+
+### 6. Use Version Control for GTM
+
+- Export your GTM container configuration
+- Store it in your project repository
+- Document significant changes
+- Maintain a changelog of GTM updates
+
+### 7. Use Attribution Tracking
+
+Use the root-level attribution fields:
+
+```javascript
+{
+ event: 'dl_purchase',
+ utm_source: 'google',
+ utm_medium: 'cpc',
+ utm_campaign: 'summer_sale',
+ funnel: 'main',
+ affiliate: 'partner-123'
+}
+```
+
+Create GTM variables for each attribution field to enable advanced segmentation and attribution analysis.
+
+### 8. Handle Blocked Events Wisely
+
+Only block events that:
+- Are used for internal testing
+- Generate excessive noise
+- Aren't needed for business analysis
+- Can be filtered elsewhere
+
+Document which events are blocked and why.
+
+## Migration Guide
+
+If migrating from another analytics setup to GTM with Campaign Cart SDK:
+
+1. **Inventory existing events** - Document all events you're currently tracking
+2. **Map to Campaign Cart events** - Match existing events to SDK event types
+3. **Set up GTM container** - Follow the Setup section above
+4. **Test in parallel** - Run both old and new tracking simultaneously
+5. **Validate data quality** - Compare reports between old and new setup
+6. **Monitor initial period** - Watch for discrepancies in first 2-4 weeks
+7. **Phase out old tracking** - Gradually disable legacy tracking when confident
+
+## Additional Resources
+
+- [Google Tag Manager Documentation](https://support.google.com/tagmanager)
+- [GA4 Event Schema](https://support.google.com/analytics/answer/11137820)
+- [Campaign Cart Analytics Documentation](/docs/campaign-cart/analytics/)
+- [Event Reference](/docs/campaign-cart/analytics/events/)
diff --git a/docs/campaign-cart/analytics/examples/index.md b/docs/campaign-cart/analytics/examples/index.md
new file mode 100644
index 00000000..2f37041a
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/index.md
@@ -0,0 +1,112 @@
+---
+sidebar_label: Examples
+sidebar_position: 14
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Analytics Providers Overview
+
+Configure multiple analytics providers to send events simultaneously to GTM, Facebook Pixel, RudderStack, and custom platforms.
+
+Configure analytics providers to send events to multiple platforms. The SDK supports Google Tag Manager, Direct GA4 integration, Facebook Pixel, RudderStack, and custom webhooks.
+
+## Provider Configuration
+
+Enable multiple providers in your configuration:
+
+```javascript
+window.nextConfig = {
+ apiKey: 'your-api-key',
+ storeName: 'my-store', // Important for Facebook deduplication
+ analytics: {
+ enabled: true,
+ mode: 'auto',
+ providers: {
+ gtm: { enabled: true },
+ facebook: { enabled: true, settings: { pixelId: 'xxx' } },
+ rudderstack: { enabled: true },
+ custom: { enabled: true, settings: { endpoint: 'https://...' } }
+ }
+ }
+};
+```
+
+## Providers Comparison
+
+| Provider | Best For | Setup Complexity | Auto-Deduplication |
+|----------|----------|------------------|--------------------|
+| **Google Tag Manager** | Event tracking & conversion measurement | Low | Yes (via GTM) |
+| **Direct GA4 (No GTM)** | Simple GA4 tracking without GTM | Very Low | Yes (automatic) |
+| **Facebook Pixel** | Conversion tracking & audience building | Medium | Yes (with storeName) |
+| **RudderStack** | Data warehouse integration & CDP | High | Yes (via RudderStack) |
+| **Custom Webhook** | Third-party integrations & APIs | Medium | Manual |
+
+## Provider Independence
+
+Each provider operates independently. If one provider fails or is temporarily unavailable:
+
+- Other providers continue to receive and process events normally
+- Failed requests do not block the event pipeline
+- Your analytics data is safely distributed across multiple platforms
+- No single point of failure exists
+
+## Using Multiple Providers
+
+You can enable any combination of providers simultaneously:
+
+### All Providers
+Enable all providers for data collection across multiple platforms:
+
+```javascript
+analytics: {
+ providers: {
+ gtm: { enabled: true },
+ facebook: { enabled: true, settings: { pixelId: 'YOUR_PIXEL_ID' } },
+ rudderstack: { enabled: true },
+ custom: { enabled: true, settings: { endpoint: 'https://your-api.com/events' } }
+ }
+}
+```
+
+### Selective Providers
+Choose only the providers you need:
+
+```javascript
+analytics: {
+ providers: {
+ gtm: { enabled: true },
+ facebook: { enabled: true, settings: { pixelId: 'YOUR_PIXEL_ID' } },
+ rudderstack: { enabled: false },
+ custom: { enabled: false }
+ }
+}
+```
+
+:::tip
+Enable multiple providers to send analytics data to all required platforms. If one service fails, others continue operating.
+:::
+
+## Provider Setup Guides
+
+### Built-in Providers
+
+- **[Google Tag Manager](/docs/campaign-cart/analytics/examples/google-tag-manager/)** - Container setup and variable configuration
+- **[Facebook Pixel](/docs/campaign-cart/analytics/examples/facebook-pixel/)** - Conversion tracking and audience building
+- **[RudderStack](/docs/campaign-cart/analytics/examples/rudderstack/)** - Data warehouse and CDP integration
+- **[Custom Webhook](/docs/campaign-cart/analytics/examples/custom-webhook/)** - Third-party API integration
+
+### Alternative Integrations
+
+- **[Direct GA4 (No GTM)](/docs/campaign-cart/analytics/examples/direct-ga4/)** - Send events directly to Google Analytics 4 without GTM
+- **[Event Transformers](/docs/campaign-cart/analytics/examples/event-transformers/)** - Build custom transformers for any platform (TikTok, Snapchat, Pinterest, etc.)
+- **[Custom Analytics Triggers](/docs/campaign-cart/analytics/examples/custom-analytics-triggers/)** - Modify when `add_to_cart` and `begin_checkout` events fire
+
+## Next Steps
+
+1. Choose which providers you need
+2. Follow the provider-specific setup guide
+3. Test event delivery in your development environment
+4. Deploy to production
+
diff --git a/docs/campaign-cart/analytics/examples/rudderstack.md b/docs/campaign-cart/analytics/examples/rudderstack.md
new file mode 100644
index 00000000..379c7a16
--- /dev/null
+++ b/docs/campaign-cart/analytics/examples/rudderstack.md
@@ -0,0 +1,223 @@
+---
+title: RudderStack Setup
+description: Integrate RudderStack with Segment-compatible event tracking.
+---
+
+
+RudderStack is a Segment-compatible analytics platform that tracks customer events and collects product data. This integration maps SDK events to RudderStack's Segment specification.
+
+## Setup
+
+1. **Add RudderStack Snippet**
+
+ Add the RudderStack tracking snippet to your HTML `` section. You'll need to replace `YOUR_WRITE_KEY` and `YOUR_DATA_PLANE_URL` with your actual RudderStack credentials:
+
+ ```html
+
+
+ ```
+
+ **Getting Your Credentials:**
+ - Log in to your RudderStack dashboard
+ - Navigate to Workspace Settings → Data Plane URLs
+ - Copy your Write Key and Data Plane URL
+ - Replace the placeholders in the snippet above
+
+2. **Enable in SDK Config**
+
+ Configure the RudderStack provider in your analytics configuration:
+
+ ```javascript
+ analytics: {
+ providers: {
+ rudderstack: {
+ enabled: true,
+ blockedEvents: [] // Optional: array of event names to exclude
+ }
+ }
+ }
+ ```
+
+ **Configuration Options:**
+ - `enabled` (boolean): Enable or disable RudderStack tracking
+ - `blockedEvents` (array): List of SDK event names to exclude from RudderStack (useful for filtering sensitive events)
+
+
+
+## Event Mapping
+
+RudderStack events follow the Segment specification. The SDK automatically maps your e-commerce events to their RudderStack equivalents:
+
+| SDK Event | RudderStack Event | Description |
+|-----------|-------------------|-------------|
+| `dl_add_to_cart` | `Product Added` | Fired when a product is added to the shopping cart |
+| `dl_remove_from_cart` | `Product Removed` | Fired when a product is removed from the shopping cart |
+| `dl_view_item` | `Product Viewed` | Fired when a product detail page is viewed |
+| `dl_view_item_list` | `Product List Viewed` | Fired when a product list or category page is viewed |
+| `dl_view_cart` | `Cart Viewed` | Fired when the shopping cart is viewed |
+| `dl_begin_checkout` | `Checkout Started` | Fired when the checkout process is initiated |
+| `dl_add_shipping_info` | `Checkout Step Completed` | Fired when shipping information is entered |
+| `dl_add_payment_info` | `Payment Info Entered` | Fired when payment information is provided |
+| `dl_purchase` | `Order Completed` | Fired when an order is successfully completed |
+
+## Product Format
+
+Products are automatically converted to the Segment specification format. Each product in your events will be transformed to include these standardized properties:
+
+```javascript
+{
+ product_id: 'SKU-123',
+ sku: 'SKU-123',
+ name: 'Product Name',
+ price: 99.99,
+ quantity: 1,
+ category: 'Category',
+ brand: 'Brand',
+ variant: 'Variant',
+ position: 0,
+ url: 'https://example.com/product/sku-123'
+}
+```
+
+**Field Descriptions:**
+- `product_id`: Unique identifier for the product (same as SKU)
+- `sku`: Stock Keeping Unit
+- `name`: Product display name
+- `price`: Product price in decimal format
+- `quantity`: Number of units
+- `category`: Product category
+- `brand`: Product brand
+- `variant`: Product variant or size
+- `position`: Position in product list (0-indexed)
+- `url`: Product page URL
+
+## Features
+
+### Identify Calls
+
+The SDK sends `identify()` calls with user data when user information is available. This includes:
+- User profile tracking
+- Cross-device identification
+- Demographic data collection
+- User trait enrichment
+
+### Page Calls
+
+The SDK triggers `page()` calls on route changes to:
+- Track page views and navigation patterns
+- Segment user journeys
+- Analyze user flow through your application
+
+### Additional Capabilities
+
+- Product metadata included in tracking calls
+- Campaign source and attribution tracking
+- Session tracking across user interactions
+- Revenue and conversion metrics
+
+## Configuration Options
+
+### Basic Configuration
+
+```javascript
+analytics: {
+ providers: {
+ rudderstack: {
+ enabled: true
+ }
+ }
+}
+```
+
+### Advanced Configuration
+
+```javascript
+analytics: {
+ providers: {
+ rudderstack: {
+ enabled: true,
+ blockedEvents: [
+ 'dl_custom_internal_event',
+ 'dl_debug_event'
+ ]
+ }
+ }
+}
+```
+
+### Environment-Based Configuration
+
+```javascript
+analytics: {
+ providers: {
+ rudderstack: {
+ enabled: process.env.NODE_ENV === 'production',
+ blockedEvents: process.env.NODE_ENV === 'development' ? ['dl_debug_event'] : []
+ }
+ }
+}
+```
+
+## Troubleshooting
+
+### Events Not Appearing in RudderStack
+
+**Check Your Setup:**
+1. Verify the RudderStack snippet is loaded in your `` section
+2. Ensure your Write Key and Data Plane URL are correct
+3. Check browser console for JavaScript errors (open Developer Tools)
+4. Confirm RudderStack is enabled in your SDK configuration
+
+**Debug with Browser Console:**
+```javascript
+// Check if RudderStack is loaded
+console.log(window.rudderanalytics);
+
+// Manually trigger a test event
+rudderanalytics.track('Test Event', { test: true });
+```
+
+### Write Key or Data Plane URL Issues
+
+**Symptoms:** Events fail silently or "401 Unauthorized" errors appear
+
+**Solution:**
+1. Verify credentials in your RudderStack dashboard
+2. Ensure your Data Plane URL is complete (include protocol, e.g., `https://`)
+3. Check that your workspace is active
+4. Generate a new Write Key if the current one seems compromised
+
+### Blocked Events Not Working
+
+**Symptoms:** Events you want to exclude still appear in RudderStack
+
+**Solution:**
+1. Verify the event name exactly matches your blockedEvents array
+2. Check that the configuration is properly loaded before events fire
+3. Event names are case-sensitive: `dl_add_to_cart` ≠ `dl_AddToCart`
+
+### Product Data Missing
+
+**Symptoms:** Product events reach RudderStack but lack properties
+
+**Solution:**
+1. Ensure your product objects include required fields: `product_id`, `name`, `price`
+2. Check that product data is properly formatted in your event payloads
+3. Verify no custom product field mapping is conflicting
+
+### Performance Issues
+
+**Optimization Tips:**
+1. Use `blockedEvents` to exclude high-frequency internal events
+2. Load the RudderStack script asynchronously
+3. Consider batching events if sending large volumes
+4. Review RudderStack's destination list and disable unused integrations
+
+### Contact Support
+
+For additional help:
+- Check the [RudderStack Documentation](https://www.rudderstack.com/docs/)
+- Review [Segment Event Specification](https://segment.com/docs/protocols/tracking-plan/spec/)
+- Contact your RudderStack support team
diff --git a/docs/campaign-cart/analytics/index.md b/docs/campaign-cart/analytics/index.md
new file mode 100644
index 00000000..f469ddf6
--- /dev/null
+++ b/docs/campaign-cart/analytics/index.md
@@ -0,0 +1,250 @@
+---
+sidebar_label: Analytics
+sidebar_position: 6
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Analytics Overview
+
+Track e-commerce events across Google Analytics 4, Facebook Pixel, RudderStack, and custom platforms.
+
+The SDK tracks e-commerce events and sends them to analytics providers.
+
+## Supported Providers
+
+- Google Tag Manager
+- Facebook Pixel
+- RudderStack
+- Custom webhooks
+
+Events follow GA4 specification and can be tracked automatically or manually using two APIs: `next.*` methods or `window.NextAnalytics`.
+
+## How It Works
+
+### 1. Events Are Tracked
+
+The SDK captures e-commerce events using two APIs:
+
+
+
+
+```javascript
+// Simple tracking methods
+next.trackAddToCart(packageId, quantity);
+next.trackViewItem(packageId);
+next.trackBeginCheckout();
+next.trackPurchase(orderData);
+```
+
+Works immediately, handles async loading automatically.
+
+
+
+
+```javascript
+// Advanced tracking with full control
+window.NextAnalytics.trackAddToCart(item, listId, listName);
+window.NextAnalytics.trackViewItem(item);
+window.NextAnalytics.track({ event: 'custom_event', data: '...' });
+```
+
+Direct access to analytics engine with advanced features.
+
+
+
+
+### 2. Events Are Stored
+
+All events are stored in three data layers:
+
+- **`window.NextDataLayer`** - SDK's primary analytics store
+- **`window.dataLayer`** - Standard Google Tag Manager layer
+- **`window.ElevarDataLayer`** - Elevar-compatible format
+
+### 3. Events Are Sent
+
+Events are automatically sent to all enabled providers:
+
+```javascript
+providers: {
+ gtm: { enabled: true }, // → Google Tag Manager
+ facebook: { enabled: true, settings: {} }, // → Facebook Pixel
+ rudderstack: { enabled: true }, // → RudderStack
+ custom: { enabled: true, settings: {} } // → Your backend
+}
+```
+
+Each provider operates independently - if one fails, others continue working.
+
+## Event Data Structure
+
+All events follow GA4-compliant format:
+
+```javascript
+{
+ event: 'dl_add_to_cart',
+ event_id: 'sess_123_2_1234567890',
+ event_time: '2025-01-12T10:30:00Z',
+
+ user_properties: {
+ visitor_type: 'guest',
+ customer_email: 'user@example.com',
+ customer_id: 'user_123'
+ },
+
+ ecommerce: {
+ currency: 'USD',
+ value: 99.99,
+ items: [{
+ item_id: 'SKU-123',
+ item_name: 'Product Name',
+ price: 99.99,
+ quantity: 1
+ }]
+ },
+
+ attribution: {
+ utm_source: 'google',
+ utm_medium: 'cpc',
+ funnel: 'main'
+ },
+
+ _metadata: {
+ session_id: 'sess_abc123',
+ sequence_number: 2,
+ source: 'next-campaign-cart',
+ version: '0.2.0'
+ }
+}
+```
+
+## Testing & Verification
+
+### Enable Debug Mode
+
+
+
+
+```javascript
+analytics: {
+ debug: true
+}
+```
+
+
+
+
+```javascript
+// Enable at runtime
+window.NextAnalytics.setDebugMode(true);
+
+// Check status
+const status = window.NextAnalytics.getStatus();
+console.log(status);
+```
+
+
+
+
+### Disable Tracking Temporarily
+
+```
+https://yoursite.com?ignore=true
+```
+
+This disables ALL tracking for the entire session.
+
+To clear:
+```javascript
+window.NextAnalyticsClearIgnore();
+```
+
+### Verify Events
+
+```javascript
+// Check all data layers
+console.log(window.NextDataLayer);
+console.log(window.dataLayer); // GTM
+console.log(window.ElevarDataLayer); // Elevar
+
+// Get analytics status
+const status = window.NextAnalytics.getStatus();
+console.log('Events tracked:', status.eventsTracked);
+console.log('Providers:', status.providers);
+```
+
+## Next Steps
+
+1. **Configure providers** - Set up GTM, Facebook Pixel, or other platforms
+
+ See [Examples Overview](/docs/campaign-cart/analytics/examples/)
+
+2. **Learn tracking methods** - Understand the tracking API
+
+ See [Tracking API Reference](/docs/campaign-cart/analytics/tracking-api/)
+
+3. **Review events** - See all standard e-commerce events
+
+ See [Event Reference](/docs/campaign-cart/analytics/events/)
+
+4. **Advanced tracking** - Create custom events and use transform functions
+
+ See [Custom Events](/docs/campaign-cart/analytics/custom-events/)
+
+## Documentation Structure
+
+- **[Meta Tags](/docs/campaign-cart/analytics/meta-tags/)** - Declarative analytics configuration via HTML meta tags
+- **[Configuration & Modes](/docs/campaign-cart/analytics/configuration/)** - Detailed configuration options
+- **[Tracking API Reference](/docs/campaign-cart/analytics/tracking-api/)** - Complete API documentation
+- **[Examples](/docs/campaign-cart/analytics/examples/)** - Provider-specific setup guides
+- **[Event Reference](/docs/campaign-cart/analytics/events/)** - Complete event schemas and examples
+- **[Custom Events](/docs/campaign-cart/analytics/custom-events/)** - Advanced tracking patterns
+- **[Debugging](/docs/campaign-cart/analytics/debugging/)** - Troubleshooting and testing
+- **[Best Practices](/docs/campaign-cart/analytics/best-practices/)** - Implementation patterns and tips
+
+## FAQ
+
+### Do I need to call next.init()?
+
+No! Analytics initializes automatically when the SDK loads. Just configure `window.nextConfig`.
+
+### What's the difference between the three data layers?
+
+- `window.dataLayer` - Standard GTM data layer
+- `window.NextDataLayer` - SDK's primary analytics store (all events)
+- `window.ElevarDataLayer` - Elevar-compatible format for GTM integrations
+
+### Can I track events before SDK loads?
+
+Yes, use the nextReady queue:
+
+```javascript
+window.nextReady = window.nextReady || [];
+window.nextReady.push(function() {
+ next.trackAddToCart('123', 1);
+});
+```
+
+### What happens if a provider fails?
+
+The SDK handles failures gracefully:
+- Events still track to NextDataLayer
+- Other providers continue working
+- Warnings logged in debug mode
+- SDK functionality unaffected
+
+### How do I check if analytics is working?
+
+```javascript
+// Check status
+window.NextAnalytics.getStatus();
+
+// Check events
+window.NextDataLayer;
+
+// Enable debug
+window.NextAnalytics.setDebugMode(true);
+```
+
diff --git a/docs/campaign-cart/analytics/meta-tags.md b/docs/campaign-cart/analytics/meta-tags.md
new file mode 100644
index 00000000..e7194204
--- /dev/null
+++ b/docs/campaign-cart/analytics/meta-tags.md
@@ -0,0 +1,236 @@
+---
+title: Analytics Meta Tags
+description: Control analytics events declaratively through HTML meta tags - no JavaScript required.
+sidebar_position: 4
+---
+
+Control analytics events declaratively through HTML meta tags - no JavaScript required.
+
+---
+
+## Quick Reference
+
+| Meta Tag | Purpose |
+|----------|---------|
+| `next-analytics-view-item` | Fire `dl_view_item` for a package (replaces auto-detection) |
+| `next-analytics-view-item-list` | Fire `dl_view_item_list` for packages (replaces auto-detection) |
+| `next-analytics-list-id` | Set page-level list ID for all events |
+| `next-analytics-list-name` | Set page-level list name for all events |
+| `next-analytics-scroll-tracking` | Track scroll depth at specified thresholds |
+| `next-analytics-disable` | Block specific events globally (all providers) |
+| `next-analytics-enable-only` | Whitelist mode - only fire these events |
+
+---
+
+## `dl_view_item` Examples
+
+### Basic - Fire immediately on page load
+```html
+
+```
+Replace `123` with an actual package `ref_id` from your campaign.
+
+### With Time Delay (engagement signal)
+```html
+
+```
+The event fires 3 seconds (3000ms) after the page loads.
+
+### With Scroll Trigger
+```html
+
+```
+The event fires when the element `#product-details` scrolls into view (50% visible).
+
+### From URL Parameter
+```html
+
+```
+Reads the package ID from the URL query string: `?pid=123`
+
+**Trigger Format**: `type:value`
+- `time:3000` = wait 3000ms (3 seconds) after page load
+- `view:#selector` = fire when CSS selector scrolls into view (50% threshold)
+
+---
+
+## `dl_view_item_list` Examples
+
+### Multiple packages (comma-separated)
+```html
+
+```
+Fires `dl_view_item_list` with all specified packages.
+
+### From URL Parameter
+```html
+
+```
+Reads comma-separated IDs from URL: `?products=123,456,789`
+
+---
+
+## List Context (Attribution)
+
+Set page-level list context that will be included in all add-to-cart events:
+
+```html
+
+
+```
+
+This ensures proper attribution tracking when users add items to cart.
+
+---
+
+## Scroll Depth Tracking
+
+Track when users scroll to specific percentages of the page:
+
+```html
+
+```
+
+Fires `dl_scroll_depth` events at 25%, 50%, 75%, and 90% scroll depth. Each threshold fires only once.
+
+---
+
+## Event Blocking
+
+### Disable Specific Events (Global Block)
+```html
+
+```
+Blocks these events from firing for ALL providers.
+
+### Whitelist Mode (Only Allow These Events)
+```html
+
+```
+Only these events will fire - everything else is blocked globally.
+
+---
+
+## Complete Examples
+
+### Product Detail Page
+```html
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Landing Page with URL Parameters
+```html
+
+
+
+
+
+
+
+
+```
+
+### Upsell Page (Block Unwanted Events)
+```html
+
+
+
+
+
+
+
+
+```
+
+---
+
+## How It Works
+
+### Priority: Meta Tags Override Auto-Detection
+
+When a meta tag like `` is present:
+- It **REPLACES** auto-detected `dl_view_item` entirely
+- **No need to manually block it first** in the config
+- The meta tag always takes priority over auto-detection
+
+### Event Control Hierarchy
+
+```
+┌─────────────────────────────────────────────────────────────────────┐
+│ LEVEL 1: Provider-Specific blockedEvents (Most Granular) │
+│ Blocks event for THAT PROVIDER ONLY │
+│ gtm: { blockedEvents: ['dl_view_item_list'] } → GTM won't get it │
+└─────────────────────────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────────────┐
+│ LEVEL 2: Meta Tag disable/enable-only (Global Block) │
+│ Blocks event for ALL PROVIDERS │
+│ │
+└─────────────────────────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────────────┐
+│ LEVEL 3: Meta Tag view-item/view-item-list (Auto-Event Override) │
+│ REPLACES auto-detection entirely (not additive) │
+│ │
+└─────────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## Debugging
+
+After the page loads, you can check the status in the browser console:
+
+```javascript
+// Check MetaTagController status
+NextMetaTagController.getStatus()
+
+// Check if events were fired
+NextMetaTagController.wasViewItemFired()
+NextMetaTagController.wasViewItemListFired()
+
+// Check the parsed config
+NextMetaTagController.getStatus().config
+
+// Check disabled events
+NextMetaTagController.getStatus().config.disabledEvents
+
+// Check list context
+NextMetaTagController.getListContext()
+```
+
+---
+
+## Events Reference
+
+| Event Name | Description |
+|------------|-------------|
+| `dl_view_item` | Single product view |
+| `dl_view_item_list` | Multiple products viewed (list/collection) |
+| `dl_add_to_cart` | Item added to cart |
+| `dl_remove_from_cart` | Item removed from cart |
+| `dl_begin_checkout` | Checkout started |
+| `dl_purchase` | Order completed |
+| `dl_scroll_depth` | User scrolled to threshold |
+
+---
+
+## Browser Support
+
+- Chrome 90+
+- Firefox 88+
+- Safari 14+
+- Edge 90+
+
+No polyfills required - uses standard DOM APIs.
+
diff --git a/docs/campaign-cart/analytics/tracking-api.md b/docs/campaign-cart/analytics/tracking-api.md
new file mode 100644
index 00000000..b802becd
--- /dev/null
+++ b/docs/campaign-cart/analytics/tracking-api.md
@@ -0,0 +1,679 @@
+---
+title: Tracking API Reference
+description: Complete reference for tracking e-commerce events using the simple next.* API or advanced window.NextAnalytics methods.
+sidebar_position: 11
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+The SDK provides two complementary APIs for tracking analytics events. Choose the simple API for quick implementations or the advanced API for full control.
+
+## API Overview
+
+
+
+
+**Best for:** Quick implementations, minimal code
+
+```javascript
+// Simple, clean method calls
+next.trackAddToCart(packageId, quantity);
+next.trackViewItem(packageId);
+next.trackBeginCheckout();
+next.trackPurchase(orderData);
+```
+
+**Features:**
+- Handles async loading automatically
+- Simple parameter signatures
+- Works before SDK fully loads (queued)
+- Ideal for most use cases
+
+
+
+
+**Best for:** Advanced tracking, custom events, full control
+
+```javascript
+// Direct access to analytics engine
+window.NextAnalytics.trackAddToCart(item, listId, listName);
+window.NextAnalytics.track({ event: 'custom', data: '...' });
+window.NextAnalytics.setDebugMode(true);
+```
+
+**Features:**
+- Full item data objects
+- List attribution support
+- Custom event tracking
+- Debug and status methods
+- Direct analytics engine access
+
+
+
+
+---
+
+## E-commerce Events
+
+### Add to Cart
+
+Track when items are added to the cart.
+
+
+
+
+```javascript
+// Track with package ID and quantity
+next.trackAddToCart('123', 1);
+
+// With quantity
+next.trackAddToCart('456', 2);
+```
+
+**Parameters:**
+- `packageId` (string|number) - Product/package identifier
+- `quantity` (number, optional) - Quantity added (default: 1)
+
+**Auto-tracked when:**
+- Using `data-next-action="add-to-cart"` attributes
+- Calling cart methods like `next.addToCart()`
+
+
+
+
+```javascript
+// With full item data
+window.NextAnalytics.trackAddToCart({
+ id: 'pkg-123',
+ packageId: '123',
+ title: 'Premium Package',
+ price: 99.99,
+ quantity: 1
+});
+
+// With list attribution
+window.NextAnalytics.trackAddToCart({
+ id: 'pkg-123',
+ packageId: '123',
+ title: 'Premium Package',
+ price: 99.99,
+ quantity: 1
+}, 'summer-collection', 'Summer Sale 2025');
+```
+
+**Parameters:**
+- `item` (object) - Full item data
+ - `id` (string) - Unique item identifier
+ - `packageId` (string|number) - Package ID
+ - `title` (string) - Product name
+ - `price` (number) - Unit price
+ - `quantity` (number) - Quantity
+- `listId` (string, optional) - Product list ID for attribution
+- `listName` (string, optional) - Product list name for attribution
+
+
+
+
+### Remove from Cart
+
+Track when items are removed from the cart.
+
+
+
+
+```javascript
+// Track removal
+next.trackRemoveFromCart('123', 1);
+```
+
+**Parameters:**
+- `packageId` (string|number) - Product identifier
+- `quantity` (number, optional) - Quantity removed
+
+
+
+
+```javascript
+// Using EcommerceEvents helper
+import { EcommerceEvents } from '@/utils/analytics';
+import { dataLayer } from '@/utils/analytics';
+
+const event = EcommerceEvents.createRemoveFromCartEvent(item);
+dataLayer.push(event);
+```
+
+**Auto-tracked when:**
+- Using cart removal methods
+
+
+
+
+### View Item
+
+Track product detail page views.
+
+
+
+
+```javascript
+// Track product view
+next.trackViewItem('123');
+```
+
+**Parameters:**
+- `packageId` (string|number) - Product identifier
+
+**Auto-tracked when:**
+- Page has exactly 1 product with `data-next-package-id`
+- Selected items in `data-next-selection-mode="select"` selectors
+- Selected items in `data-next-selection-mode="swap"` selectors
+
+
+
+
+```javascript
+// With full product data
+window.NextAnalytics.trackViewItem({
+ id: 'pkg-123',
+ packageId: '123',
+ title: 'Premium Package',
+ price: 99.99
+});
+```
+
+**Parameters:**
+- `item` (object) - Product data
+ - `id` (string) - Unique identifier
+ - `packageId` (string|number) - Package ID
+ - `title` (string) - Product name
+ - `price` (number) - Price
+
+
+
+
+### View Item List
+
+Track product list/collection views.
+
+
+
+
+```javascript
+// Track list view
+next.trackViewItemList(
+ ['123', '456', '789'],
+ 'summer-sale',
+ 'Summer Sale Collection'
+);
+```
+
+**Parameters:**
+- `packageIds` (array) - Array of product IDs
+- `listId` (string) - List identifier
+- `listName` (string) - List display name
+
+**Auto-tracked when:**
+- URL matches collection/category patterns
+- Page type detected as product list
+
+
+
+
+```javascript
+window.NextAnalytics.trackViewItemList(items, listId, listName);
+```
+
+**Parameters:**
+- `items` (array) - Array of item objects
+- `listId` (string) - List identifier
+- `listName` (string) - List display name
+
+
+
+
+### Begin Checkout
+
+Track when checkout process starts.
+
+
+
+
+```javascript
+// Track checkout start
+next.trackBeginCheckout();
+```
+
+**No parameters required** - automatically includes cart items
+
+**Auto-tracked when:**
+- Checkout page loads (in auto mode)
+
+
+
+
+```javascript
+window.NextAnalytics.trackBeginCheckout();
+```
+
+Automatically includes:
+- All current cart items
+- Cart total value
+- Currency
+- User properties
+
+
+
+
+### Purchase
+
+Track completed orders.
+
+
+
+
+```javascript
+// Minimal purchase tracking
+next.trackPurchase({
+ id: 'ORDER_123',
+ total: 159.99,
+ currency: 'USD',
+ tax: 9.99,
+ shipping: 10.00
+});
+
+// With items
+next.trackPurchase({
+ id: 'ORDER_123',
+ total: 159.99,
+ currency: 'USD',
+ items: [
+ {
+ id: 'SKU-123',
+ name: 'Product Name',
+ price: 149.99,
+ quantity: 1
+ }
+ ]
+});
+```
+
+**Parameters:**
+- `orderData` (object)
+ - `id` (string) - **Required** - Order ID
+ - `total` (number) - **Required** - Order total
+ - `currency` (string) - Currency code (default: 'USD')
+ - `tax` (number, optional) - Tax amount
+ - `shipping` (number, optional) - Shipping cost
+ - `items` (array, optional) - Order line items
+
+
+
+
+```javascript
+// Full order data from backend
+window.NextAnalytics.trackPurchase({
+ order: {
+ ref_id: 'ORD-12345',
+ number: '12345',
+ total_incl_tax: '159.99',
+ total_tax: '9.99',
+ shipping_incl_tax: '10.00',
+ currency: 'USD',
+ user: {
+ email: 'user@example.com',
+ first_name: 'John',
+ last_name: 'Doe'
+ },
+ lines: [
+ {
+ product_sku: 'SKU-123',
+ product_title: 'Product Name',
+ price_incl_tax: '149.99',
+ quantity: 1
+ }
+ ],
+ billing_address: {
+ first_name: 'John',
+ last_name: 'Doe',
+ city: 'San Francisco',
+ state: 'CA',
+ postcode: '94102',
+ country: 'US'
+ }
+ }
+});
+```
+
+**Parameters:**
+- `orderData` (object)
+ - `order` (object) - Complete order object from backend
+ - Automatically transforms to GA4 format
+ - Includes user properties, items, transaction details
+
+
+
+
+**Auto-tracked:** Yes (queued and fired on confirmation page)
+
+**Event Queue:** Purchase events are queued to `sessionStorage` when order completes, then automatically fired on the confirmation page after redirect.
+
+**Manual tracking (optional):**
+
+You can manually trigger purchase events if needed (e.g., for testing or special integrations):
+
+```javascript
+// Manually track with order data from sessionStorage['next-order']
+const orderData = JSON.parse(sessionStorage.getItem('next-order'))?.state?.order;
+if (orderData) {
+ next.trackPurchase({ order: orderData });
+}
+
+// Or provide custom order data
+next.trackPurchase({
+ id: 'ORDER_123',
+ total: 159.99,
+ currency: 'USD'
+});
+```
+
+---
+
+## User Events
+
+### Sign Up
+
+Track user registration.
+
+
+
+
+```javascript
+// Track registration
+next.trackSignUp('user@example.com');
+```
+
+**Parameters:**
+- `email` (string) - User email address
+
+
+
+
+```javascript
+window.NextAnalytics.trackSignUp('user@example.com');
+```
+
+Automatically includes:
+- User email
+- Timestamp
+- Session data
+- Attribution
+
+
+
+
+### Login
+
+Track user login.
+
+
+
+
+```javascript
+// Track login
+next.trackLogin('user@example.com');
+```
+
+**Parameters:**
+- `email` (string) - User email address
+
+
+
+
+```javascript
+window.NextAnalytics.trackLogin('user@example.com');
+```
+
+
+
+
+---
+
+## Custom Events
+
+Track custom business events.
+
+```javascript
+// Only available via advanced API
+window.NextAnalytics.track({
+ event: 'newsletter_subscribe',
+ email: 'user@example.com',
+ list_name: 'Weekly Newsletter',
+ source: 'footer_form'
+});
+
+// Video engagement
+window.NextAnalytics.track({
+ event: 'video_played',
+ video_id: 'intro-demo',
+ video_title: 'Product Introduction',
+ duration: 120
+});
+
+// Feature usage
+window.NextAnalytics.track({
+ event: 'feature_used',
+ feature_name: 'product_comparison',
+ items_compared: 3
+});
+```
+
+**Parameters:**
+- `eventData` (object) - Custom event object
+ - `event` (string) - **Required** - Event name (use snake_case)
+ - Any additional properties as needed
+
+Custom events are sent to **all enabled providers**.
+
+See [Custom Events Guide](/docs/campaign-cart/analytics/custom-events/) for advanced patterns and EventBuilder usage.
+
+---
+
+## Utility Methods
+
+### setDebugMode
+
+Enable or disable debug logging.
+
+```javascript
+// Enable debug mode
+window.NextAnalytics.setDebugMode(true);
+
+// Disable
+window.NextAnalytics.setDebugMode(false);
+```
+
+**Parameters:**
+- `enabled` (boolean) - Enable/disable debug logs
+
+**Debug output includes:**
+- Event names and data
+- Provider dispatch confirmations
+- Validation warnings
+- Error messages
+
+### getStatus
+
+Get current analytics status and configuration.
+
+```javascript
+const status = window.NextAnalytics.getStatus();
+console.log(status);
+```
+
+**Returns:**
+```javascript
+{
+ enabled: true,
+ mode: 'auto',
+ providers: ['GTM', 'Facebook', 'RudderStack', 'Custom'],
+ eventsTracked: 15,
+ debugMode: false,
+ sessionId: 'sess_abc123',
+ version: '0.2.0'
+}
+```
+
+---
+
+## Method Reference Tables
+
+### Simple API (next.*)
+
+| Method | Parameters | Description | Auto-Tracked |
+|--------|------------|-------------|--------------|
+| `trackViewItem()` | packageId | Product detail view | Yes* |
+| `trackAddToCart()` | packageId, quantity? | Add item to cart | Yes* |
+| `trackRemoveFromCart()` | packageId, quantity? | Remove from cart | Yes* |
+| `trackViewItemList()` | packageIds[], listId, listName | Product list view | Yes* |
+| `trackBeginCheckout()` | - | Checkout initiation | Yes* |
+| `trackPurchase()` | orderData | Order completion | Yes* |
+| `trackSignUp()` | email | User registration | No |
+| `trackLogin()` | email | User login | No |
+
+*Auto-tracked only in auto mode
+
+### Advanced API (window.NextAnalytics)
+
+| Method | Parameters | Description |
+|--------|------------|-------------|
+| `trackAddToCart()` | item, listId?, listName? | Add to cart with list attribution |
+| `trackRemoveFromCart()` | item | Remove from cart |
+| `trackViewItem()` | item | Product detail view |
+| `trackViewItemList()` | items[], listId, listName | Product list view |
+| `trackBeginCheckout()` | - | Checkout initiation |
+| `trackPurchase()` | orderData | Order completion |
+| `trackSignUp()` | email | User registration |
+| `trackLogin()` | email | User login |
+| `track()` | eventData | Custom event |
+| `setDebugMode()` | enabled | Enable/disable debug logs |
+| `getStatus()` | - | Get analytics status |
+
+---
+
+## Usage Patterns
+
+### Track on Page Load
+
+```javascript
+window.addEventListener('DOMContentLoaded', () => {
+ // Product page
+ if (productData) {
+ next.trackViewItem(productData.id);
+ }
+
+ // Order confirmation
+ if (orderData) {
+ next.trackPurchase(orderData);
+ }
+});
+```
+
+### Track Before SDK Loads
+
+Use the nextReady queue:
+
+```javascript
+window.nextReady = window.nextReady || [];
+window.nextReady.push(function() {
+ next.trackAddToCart('123', 1);
+ next.trackBeginCheckout();
+});
+```
+
+### Track from Event Handlers
+
+```javascript
+// Button click
+document.getElementById('subscribe-btn').addEventListener('click', () => {
+ window.NextAnalytics.track({
+ event: 'newsletter_subscribe',
+ source: 'hero_section'
+ });
+});
+
+// Form submission
+form.addEventListener('submit', (e) => {
+ window.NextAnalytics.track({
+ event: 'form_submitted',
+ form_id: 'contact'
+ });
+});
+```
+
+### Track with List Attribution
+
+```javascript
+// Set list attribution when viewing a collection
+window.NextAnalytics.trackViewItemList(
+ items,
+ 'summer-sale-2025',
+ 'Summer Sale Collection'
+);
+
+// Attribution automatically included when user adds to cart
+next.trackAddToCart('123', 1);
+// Event includes: item_list_id: 'summer-sale-2025', item_list_name: 'Summer Sale Collection'
+```
+
+---
+
+## Error Handling
+
+The SDK handles analytics errors gracefully:
+
+```javascript
+// Analytics errors never break your app
+try {
+ next.trackPurchase(orderData);
+} catch (error) {
+ // Error automatically logged in debug mode
+ // App continues functioning normally
+}
+```
+
+**Error behavior:**
+- Errors logged to console in debug mode
+- Events still stored in NextDataLayer
+- Failed provider doesn't affect others
+- SDK functionality unaffected
+
+---
+
+## TypeScript Support
+
+Type definitions available for TypeScript projects:
+
+```typescript
+// Import types
+import type { OrderData, ItemData } from 'next-campaign-cart';
+
+// Typed parameters
+const orderData: OrderData = {
+ id: 'ORDER_123',
+ total: 159.99,
+ currency: 'USD'
+};
+
+next.trackPurchase(orderData);
+```
+
+---
+
+## Related Documentation
+
+- [Configuration & Modes](/docs/campaign-cart/analytics/configuration/) - Configure tracking modes and providers
+- [Event Reference](/docs/campaign-cart/analytics/events/) - Complete event schemas and examples
+- [Custom Events](/docs/campaign-cart/analytics/custom-events/) - Advanced tracking patterns with EventBuilder
+- [Debugging Guide](/docs/campaign-cart/analytics/debugging/) - Troubleshooting and testing
diff --git a/docs/campaign-cart/cart-system/index.md b/docs/campaign-cart/cart-system/index.md
new file mode 100644
index 00000000..14dc7ad3
--- /dev/null
+++ b/docs/campaign-cart/cart-system/index.md
@@ -0,0 +1,452 @@
+---
+sidebar_label: Cart System
+sidebar_position: 1
+---
+
+# Cart System
+
+Learn how to manage shopping carts with Campaign Cart JS SDK using HTML attributes.
+
+## Cart Selectors
+
+Cart selectors allow users to choose products before adding them to cart. The SDK supports multiple selection patterns.
+
+### Swap Mode Selector
+
+In swap mode, clicking a card immediately replaces the current item in the cart. No button needed.
+
+```html
+
+
+
Basic Package
+ $99
+
+
+
Premium Package
+ $199
+
+
+```
+
+**Key Attributes:**
+- `data-next-cart-selector`: Defines the selector container
+- `data-next-selection-mode="swap"`: Auto-adds to cart on selection
+- `data-next-selector-card`: Individual selectable cards
+- `data-next-package-id`: Package ID to add
+- `data-next-selected="true"`: Default selection
+
+### Select Mode with Button
+
+Select first, then click button to add. Button is disabled until selection is made.
+
+```html
+
+
+
Package Option 1
+
+
+
Package Option 2
+
+
+
+
+```
+
+**Key Attributes:**
+- `data-next-selection-mode="select"`: Requires button to add
+- `data-next-selector-id`: Links selector to button
+- `data-next-action="add-to-cart"`: Add to cart action
+
+### Displaying Selection Data
+
+Show data about the currently selected package:
+
+```html
+
+
+
+
+
+
+ Selected: None
+ Price: $0
+
+```
+
+### CSS Classes
+
+Selectors automatically get CSS classes:
+- `.next-selected` - Applied to selected card
+- `.next-selector-active` - Applied when selector has selection
+
+### Multiple Selectors
+
+You can have multiple selectors on the same page with different IDs:
+
+```html
+
+
+
+
+
+
+
+
+
+```
+
+### Conditional Display
+
+Show/hide elements based on selection:
+
+```html
+
+ You've selected a package!
+
+```
+
+## Cart Buttons
+
+Various button types for managing cart items.
+
+### Direct Add to Cart Buttons
+
+Buttons that add specific packages directly without selection.
+
+**Basic Add to Cart:**
+
+```html
+
+```
+
+**Add and Redirect:**
+
+```html
+
+```
+
+**Clear Cart, Add, and Redirect:**
+
+```html
+
+```
+
+### Cart Toggle Buttons
+
+Toggle items in/out of cart with dynamic states.
+
+**Basic Toggle:**
+
+```html
+
+```
+
+**Toggle with Quantity:**
+
+```html
+
+```
+
+**Dynamic Text Toggle:**
+
+```html
+
+```
+
+### State Container Pattern
+
+Container element gets state classes when item is in cart:
+
+```html
+
+
+
+
+```
+
+### Quantity Sync Feature
+
+Perfect for warranties and accessories that should match main product quantity.
+
+```html
+
+
+```
+
+### Button Attributes
+
+**Add to Cart Attributes:**
+- `data-next-action="add-to-cart"` - Action type
+- `data-next-package-id` - Package to add
+- `data-next-quantity` - Quantity to add
+- `data-next-url` - Redirect after add
+- `data-next-clear-cart` - Clear cart before adding
+
+**Toggle Attributes:**
+- `data-next-toggle` - Enable toggle functionality
+- `data-next-package-id` - Package to toggle
+- `data-next-quantity` - Quantity when toggled on
+- `data-add-text` - Text when item not in cart
+- `data-remove-text` - Text when item in cart
+- `data-next-is-upsell` - Mark as upsell item
+- `data-next-package-sync` - Sync quantity with other packages
+
+**CSS Classes:**
+- `.next-in-cart` - Item is in cart
+- `.next-active` - Toggle is active
+- `.next-disabled` - Button is disabled
+
+## Quantity Controls
+
+Manage product quantities in the cart with various control patterns.
+
+### Direct Quantity in Buttons
+
+Set quantity directly in add to cart buttons:
+
+```html
+
+
+```
+
+### Toggle with Quantity
+
+Toggle buttons can specify quantity:
+
+```html
+
+```
+
+### Container-Based Quantity
+
+Specify quantity at the container level:
+
+```html
+
+
+
+```
+
+### Quantity Sync Feature
+
+Sync quantities between related products (e.g., warranties that match product quantity):
+
+```html
+
+
+
+
+
+
+
+```
+
+### Quantity Display
+
+Show current quantity in cart:
+
+```html
+
+0
+
+
+0
+```
+
+### Quantity-Based Conditionals
+
+Show/hide elements based on quantity:
+
+```html
+
+
+ You qualify for bulk discount!
+
+
+
+
Single item in cart
+
Multiple items in cart
+```
+
+### Best Practices
+
+1. **Clear Labels**: Always indicate quantity in button text
+2. **Visual Feedback**: Update button text when quantity changes
+3. **Sync Related Items**: Use quantity sync for accessories/warranties
+4. **Display Current Quantity**: Show users current cart quantities
+
+## State Management
+
+The Next Commerce JS SDK automatically manages cart state and synchronizes it across all elements.
+
+### Automatic State Sync
+
+All elements displaying cart data automatically update when the cart changes:
+
+```html
+
+$0.00
+0
+
Cart has items!
+```
+
+### CSS State Classes
+
+Elements automatically receive CSS classes based on state:
+
+**Toggle Button States:**
+
+```html
+
+```
+
+**Container States:**
+
+```html
+
+
+
+
+ Product Info
+
+```
+
+**Selector States:**
+
+```html
+
+
+ Package Option
+
+```
+
+### State-Based Styling
+
+Use CSS to style based on state:
+
+```css
+/* Style selected cards */
+.next-selected {
+ border: 2px solid blue;
+ background: #f0f0ff;
+}
+
+/* Style items in cart */
+.next-in-cart {
+ opacity: 0.6;
+}
+
+/* Style active toggle buttons */
+button.next-active {
+ background: green;
+ color: white;
+}
+```
+
+### Conditional Display
+
+Show/hide elements based on cart state:
+
+```html
+
+
Your cart is empty
+
+ You have 0 items
+
+
+
+
Package 2 is in your cart
+
+
+
Free shipping unlocked!
+```
+
+### Events
+
+Listen to state changes:
+
+```javascript
+// Cart updated
+next.on('cart:updated', (data) => {
+ console.log('Cart updated:', data);
+});
+
+// Item added
+next.on('cart:item-added', (data) => {
+ console.log('Item added:', data);
+});
+
+// Item removed
+next.on('cart:item-removed', (data) => {
+ console.log('Item removed:', data);
+});
+```
+
+### Best Practices
+
+1. **Use CSS Classes**: Style based on state classes for better UX
+2. **Conditional Content**: Show relevant messages based on cart state
+3. **Listen to Events**: Trigger analytics or custom logic on state changes
+4. **Loading States**: Use data-next-await for initial loading
+
+## Related Documentation
+
+- [Cart Attributes](/docs/campaign-cart/data-attributes/display/#cart-summary) - Display cart data
+- [Upsells](/docs/campaign-cart/upsells/) - Post-purchase flows
diff --git a/docs/campaign-cart/data-attributes/actions.md b/docs/campaign-cart/data-attributes/actions.md
new file mode 100644
index 00000000..af133822
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/actions.md
@@ -0,0 +1,750 @@
+---
+title: Action Attributes
+description: Turn any HTML element into an interactive cart control
+sidebar_position: 2
+---
+
+**Action attributes transform static HTML elements into powerful e-commerce controls without writing JavaScript.**
+
+## Core Principles
+
+- **Any Element Can Be Interactive:** Not just buttons - images, divs, links all work
+- **Automatic State Management:** Loading, disabled, and success states handled for you
+- **Error Recovery Built-in:** Network failures and conflicts handled gracefully
+- **Composable Actions:** Combine multiple actions on a single element
+
+## Primary Actions
+
+### Add to Cart
+
+The most fundamental e-commerce action. Any element can become an add-to-cart control.
+
+```html
+
+```
+
+**Advanced Options:**
+
+```html
+
+```
+
+| Attribute | Purpose | Default |
+|-----------|---------|---------|
+| `data-next-package-id` | Package to add | Required |
+| `data-next-quantity` | Quantity to add | 1 |
+| `data-next-clear-cart` | Clear cart first | false |
+| `data-next-url` | Redirect after adding | none |
+| `data-add-text` | Text when not in cart | Element's text |
+| `data-remove-text` | Text when in cart | Element's text |
+| `data-loading-text` | Text while processing | "Loading..." |
+
+### Toggle Cart Item
+
+Toggle between adding and removing an item - perfect for wishlist-style interfaces.
+
+```html
+
+
+ ♥
+
+```
+
+The SDK automatically:
+- Adds `next-in-cart` class when item is in cart
+- Toggles between add and remove operations
+- Updates ARIA states for screen readers
+
+### Remove from Cart
+
+Explicitly remove an item from the cart.
+
+```html
+
+```
+
+### Clear Cart
+
+Empty the entire cart - useful for "Start Over" functionality.
+
+```html
+
+```
+
+### Swap Package
+
+Replace one package with another - perfect for variant selection.
+
+```html
+
+```
+
+## Quantity Actions
+
+### Quantity Controls
+
+Create increment/decrement controls without JavaScript.
+
+```html
+
+
+
+
+
+
+
+```
+
+| Value | Behavior |
+|-------|----------|
+| `increase` | Increment by step (default 1) |
+| `decrease` | Decrement by step (default 1) |
+| `input` | Direct quantity input |
+| `set` | Set to specific value |
+
+**With Custom Steps:**
+
+```html
+
+```
+
+## Selector Actions
+
+### Package Selector
+
+Create product variant selectors that update the cart automatically.
+
+```html
+
+
+
+
+
+
+
+```
+
+**Button-Based Selector:**
+
+```html
+
+
+
+
+
+```
+
+## Checkout Actions
+
+### Direct Checkout
+
+Skip the cart page and go straight to checkout.
+
+```html
+
+```
+
+### Express Checkout
+
+Trigger express checkout methods (Apple Pay, Google Pay, etc.).
+
+```html
+
+
+
+
+
+
+```
+
+## Upsell Actions
+
+### Accept Upsell
+
+For post-purchase upsell flows.
+
+```html
+
+```
+
+### Skip Upsell
+
+Track upsell rejections for analytics.
+
+```html
+
+```
+
+## Conditional Actions
+
+### Profile-Based Actions
+
+Show different actions based on customer profiles.
+
+```html
+
+
+
+
+```
+
+### State-Based Actions
+
+Actions that only work in certain states.
+
+```html
+
+
+
+
+
+```
+
+## Action Composition
+
+### Multiple Actions
+
+Execute multiple actions in sequence.
+
+```html
+
+```
+
+**Execution order:**
+1. Clear existing cart
+2. Add package 123 with quantity 1
+3. Redirect to /checkout
+
+### Conditional Chains
+
+```html
+
+```
+
+## Loading States
+
+The SDK automatically manages loading states during actions.
+
+```html
+
+
+
+
+```
+
+**Custom Loading Behavior:**
+
+```html
+
+```
+
+## Error Handling
+
+Actions automatically handle common errors.
+
+```html
+
+
+
+
+```
+
+## Use Cases
+
+1. **Page Headers**: Display campaign name
+2. **Currency Formatting**: Show appropriate currency
+3. **Localization**: Conditional content by language
+4. **Analytics**: Track campaign performance
+
+## Notes
+
+- Campaign data is loaded on SDK initialization
+- Values are read-only
+- Use for display purposes only
+
+## Related Documentation
+
+- [Display Attributes](/docs/campaign-cart/data-attributes/display/) - Display campaign data
+- [State Attributes](/docs/campaign-cart/data-attributes/state/) - Conditional display based on campaign
+
diff --git a/docs/campaign-cart/data-attributes/checkout-review.md b/docs/campaign-cart/data-attributes/checkout-review.md
new file mode 100644
index 00000000..80a2451d
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/checkout-review.md
@@ -0,0 +1,487 @@
+---
+title: Checkout Review
+description: Display checkout information for customer review before order completion
+sidebar_position: 8
+---
+
+**The Checkout Review enhancer automatically displays stored checkout data from previous steps, allowing customers to review their information before completing their order.**
+
+The enhancer reads from the checkout store and supports multiple format types, auto-updates when data changes, and works with any container element.
+
+## Key Features
+
+- **Automatic data loading** - Reads from checkout store automatically
+- **Multiple format types** - Text, address, name, phone, currency
+- **Real-time updates** - Auto-updates when checkout data changes
+- **Fallback support** - Custom text for empty fields
+- **Flexible containers** - Works with any HTML element
+
+## Basic Usage
+
+### Container Setup
+
+Mark a container element with the checkout-review enhancer:
+
+```html
+
+
+
+```
+
+All checkout review fields within this container will be automatically populated with data from the checkout store.
+
+### Simple Text Fields
+
+Display individual checkout fields:
+
+```html
+
+
+
+ Contact:
+
+
+
+
+
+ Phone:
+
+
+
+```
+
+### Formatted Fields
+
+Use format types to display formatted data:
+
+```html
+
+
+
+ Name:
+
+
+
+
+
+ Ship to:
+
+
+
+```
+
+## Attributes
+
+### Required Attributes
+
+| Attribute | Value | Description |
+|-----------|-------|-------------|
+| `data-next-enhancer` | `"checkout-review"` | Marks container element as checkout review enhancer |
+| `data-next-checkout-review` | Field name | Specifies which checkout field to display |
+
+### Optional Attributes
+
+| Attribute | Values | Description |
+|-----------|--------|-------------|
+| `data-next-format` | `text`, `address`, `name`, `phone`, `currency` | Format type for the field value |
+| `data-next-fallback` | Any text | Text to display when field is empty |
+
+## Available Fields
+
+All fields from the checkout store's form data:
+
+| Field | Description | Example Value |
+|-------|-------------|---------------|
+| `email` | Customer email | john@example.com |
+| `fname` | First name | John |
+| `lname` | Last name | Doe |
+| `phone` | Phone number | 5551234567 |
+| `address1` | Street address | 1949 East Camelback Road |
+| `address2` | Apartment, suite, etc. | Suite 100 |
+| `city` | City | Phoenix |
+| `province` | State/Province | AZ |
+| `postal` | ZIP/Postal code | 85016 |
+| `country` | Country code | US |
+
+## Format Types
+
+### text (Default)
+
+Displays the raw field value as text:
+
+```html
+
+
+
+
+
+
+
+```
+
+Use for: Email, individual name fields, individual address components
+
+### address
+
+Combines multiple address fields into a single formatted address:
+
+```html
+
+
+```
+
+**Includes:**
+- address1 (required)
+- address2 (if provided)
+- city (required)
+- province (required)
+- postal (required)
+- country (required - converts code to full name)
+
+**Example output formats:**
+- With address2: `123 Main St, Apt 4B, Springfield IL 62701, United States`
+- Without address2: `123 Main St, Springfield IL 62701, United States`
+
+**Notes:**
+- Use `address1` as the field name
+- Country codes automatically convert to full names (US → United States)
+- address2 only included if it has a value
+
+### name
+
+Combines first and last name into a full name:
+
+```html
+
+
+```
+
+**Includes:**
+- fname (first name)
+- lname (last name)
+
+**Notes:**
+- Use `fname` as the field name
+- Automatically combines both names with a space
+
+### phone
+
+Formats phone numbers into standard display format:
+
+```html
+
+
+```
+
+**Input:** Raw digits (e.g., 5551234567)
+**Output:** Formatted phone number (e.g., (555) 123-4567)
+
+### currency
+
+Formats numeric values as currency:
+
+```html
+
+
+```
+
+Use for: Prices, shipping costs, or any monetary value
+
+## Nested Fields
+
+Access nested checkout data using dot notation:
+
+```html
+
+
+
+
+
+
+```
+
+## Fallback Text
+
+Provide default text for empty or undefined fields:
+
+```html
+
+```
+
+When the field is empty:
+- Displays the fallback text
+- Adds `next-review-empty` CSS class for styling
+
+## Auto-Updates
+
+The enhancer automatically subscribes to checkout store changes:
+
+```html
+
+
+
+
+
+```
+
+**How it works:**
+1. Customer enters information on checkout step 1
+2. Customer proceeds to review page
+3. Review fields automatically populate with stored data
+4. If customer goes back and updates information
+5. Review fields automatically update when they return
+
+No manual refresh or JavaScript required.
+
+## CSS Classes
+
+### next-review-empty
+
+Applied to elements when field is empty or using fallback text:
+
+```css
+.next-review-empty {
+ color: #999;
+ font-style: italic;
+}
+```
+
+Use this class to visually distinguish empty states from actual customer data.
+
+## Complete Example
+
+Shopify-style checkout review section:
+
+```html
+
+
+```
+
+### Conditional Display with Fallbacks
+
+```html
+
+
+
+ Email:
+
+
+
+
+
+ Apartment:
+
+
+
+```
+
+## Format Types Reference
+
+| Format | Field Used | Combines | Output Example |
+|--------|-----------|----------|----------------|
+| `text` | Any field | Single field | john@example.com |
+| `address` | `address1` | address1, address2, city, province, postal, country | 123 Main St, Suite 1, Phoenix AZ 85016, United States |
+| `name` | `fname` | fname + lname | John Doe |
+| `phone` | `phone` | Single field (formatted) | (555) 123-4567 |
+| `currency` | Any numeric | Single field (formatted) | $9.99 |
+
+## Common Patterns
+
+### Customer Information Summary
+
+```html
+
+
Customer Information
+
+
Name:
+
-
+
+
Email:
+
-
+
+
Phone:
+
-
+
+
+```
+
+### Address Review
+
+```html
+
+
Shipping Address
+
+
+```
+
+### Multi-Section Review
+
+```html
+
+
+
+
Contact Information
+
+
+
+
+
+
+
Shipping Address
+
+
+
+```
+
+## Important Notes
+
+- The enhancer **must** be placed inside a container with `data-next-enhancer="checkout-review"`
+- All review fields within the container will be **automatically populated**
+- The enhancer **subscribes to checkout store updates** for real-time changes
+- **Country codes are automatically converted** to full country names (US → United States)
+- Fallback text triggers the `next-review-empty` CSS class for styling
+
+## Related Documentation
+
+- [Action Attributes](/data-attributes/actions/) - Checkout form actions
+- [Display Attributes](/data-attributes/display/) - Display dynamic data
+- [State Attributes](/data-attributes/state/) - Conditional display logic
diff --git a/docs/campaign-cart/data-attributes/configuration.md b/docs/campaign-cart/data-attributes/configuration.md
new file mode 100644
index 00000000..ac12c344
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/configuration.md
@@ -0,0 +1,1038 @@
+---
+title: Configuration Attributes
+description: Configure SDK behavior and appearance through HTML attributes
+sidebar_position: 5
+---
+
+**Configuration attributes control formatting, behavior, and appearance without writing JavaScript.**
+
+## Formatting Attributes
+
+Control how values are displayed and formatted.
+
+### data-format
+
+Specify how numeric values should be formatted.
+
+```html
+
+
+ $99.99
+
+
+
+
+ 99.99
+
+
+
+
+ 5
+
+
+
+
+ 30%
+
+
+
+
+ $8.999
+
+```
+
+| Format | Description | Example Output |
+|--------|-------------|----------------|
+| `currency` | With currency symbol | $99.99 |
+| `number` | Numeric only | 99.99 |
+| `integer` | No decimals | 100 |
+| `percentage` | Percentage format | 30% |
+| `auto` | Auto-detect format | Varies |
+
+### data-hide-zero-cents
+
+Hide decimal places when value has no cents.
+
+```html
+
+
+ $100
+
+
+
+
+ $99.99
+
+```
+
+### data-hide-if-zero
+
+Hide element completely when value is zero.
+
+```html
+
+
+ Discount:
+ $0.00
+
+
+
+
+ Shipping: $0.00
+
+```
+
+### data-hide-if-false
+
+Hide element when boolean value is false.
+
+```html
+
+ Discount applied!
+
+
+
+ In stock and ready to ship
+
+```
+
+## Mathematical Operations
+
+Perform calculations on displayed values.
+
+### data-multiply-by
+
+Multiply the value before displaying.
+
+```html
+
+
+ $9.99
+
+
+
+
+ $1,188/year
+
+
+
+
+ 10%
+
+```
+
+### data-divide-by
+
+Divide the value before displaying.
+
+```html
+
+
+ $19.99/item
+
+
+
+
+ 30% off
+
+```
+
+### data-add
+
+Add a value to the displayed number.
+
+```html
+
+
+ $109.99
+
+```
+
+### data-subtract
+
+Subtract from the displayed value.
+
+```html
+
+
+ Save $20.00
+
+
+
+
+ $25.00 away from free shipping
+
+```
+
+## Timer Configuration
+
+Configure countdown timers and urgency elements.
+
+### Timer Attributes
+
+```html
+
+
+ 05:00
+
+
+
+
+ 01:00:00
+
+
+
+
+ 1d 00:00:00
+
+
+
+
+ 10:00
+
+```
+
+| Attribute | Purpose | Values |
+|-----------|---------|--------|
+| `data-duration` | Timer duration in seconds | Number |
+| `data-format` | Display format | `mm:ss`, `hh:mm:ss`, `dd:hh:mm:ss`, `auto` |
+| `data-persistence-id` | Persist across refreshes | String ID |
+| `data-on-expire` | Action when timer ends | `hide`, `show-message`, `redirect` |
+| `data-expire-message` | Message to show | String |
+| `data-expire-url` | URL to redirect to | URL |
+
+## Selector Configuration
+
+Configure package selector behavior.
+
+### Selection Modes
+
+```html
+
+
+```
+
+## Related Documentation
+
+- [Display Attributes](/docs/data-attributes/display/) - Dynamic data display
+- [Action Attributes](/docs/data-attributes/actions/) - Interactive elements
+- [State Attributes](/docs/data-attributes/state/) - Conditional logic
+- [Meta Tags](/docs/configuration/meta-tags/) - Page-level configuration
diff --git a/docs/campaign-cart/data-attributes/css-classes.md b/docs/campaign-cart/data-attributes/css-classes.md
new file mode 100644
index 00000000..dd155d76
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/css-classes.md
@@ -0,0 +1,298 @@
+---
+title: CSS Classes
+description: Automatic CSS classes applied by the SDK based on element state
+sidebar_position: 12
+---
+
+# CSS Classes
+
+The Next Commerce JS SDK automatically applies CSS classes to elements based on their state.
+
+## State Classes
+
+### Cart Item States
+
+#### .next-in-cart
+Applied to elements when their package is in the cart:
+
+```html
+
+
+
+
+
+
+
+```
+
+#### .next-active
+Applied to toggle buttons when active:
+
+```html
+
+```
+
+### Selection States
+
+#### .next-selected
+Applied to selected selector cards:
+
+```html
+
+ Selected Option
+
+```
+
+#### .next-selector-active
+Applied to selector container when it has a selection:
+
+```html
+
+
+
+```
+
+### Button States
+
+#### .next-disabled
+Applied to disabled action buttons:
+
+```html
+
+
+```
+
+## Page States
+
+### .next-display-ready
+Applied to `` when SDK is initialized:
+
+```html
+
+
+
+```
+
+Usage:
+```css
+/* Hide content until ready */
+html:not(.next-display-ready) [data-next-display] {
+ visibility: hidden;
+}
+```
+
+### .next-loading
+Applied during data loading operations:
+
+```html
+
+
+
+```
+
+## Loading State Classes
+
+Elements with `data-next-await` get special treatment:
+
+```css
+/* Before SDK ready */
+html:not(.next-display-ready) [data-next-await] {
+ /* Shows loading skeleton */
+}
+
+/* After SDK ready */
+html.next-display-ready [data-next-await] {
+ /* Normal display */
+}
+```
+
+## Styling Examples
+
+### Toggle Button States
+
+```css
+/* Default state */
+button[data-next-toggle] {
+ background: #007bff;
+ color: white;
+}
+
+/* When item is in cart */
+button[data-next-toggle].next-in-cart {
+ background: #28a745;
+}
+
+/* Active state */
+button[data-next-toggle].next-active {
+ background: #dc3545;
+}
+
+/* Disabled state */
+button.next-disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+```
+
+### Product Card States
+
+```css
+/* Product card container */
+.product-card {
+ border: 1px solid #ddd;
+ transition: all 0.3s ease;
+}
+
+/* When product is in cart */
+.product-card.next-in-cart {
+ border-color: #28a745;
+ background: #f8fff9;
+}
+
+/* Style children based on parent state */
+.product-card.next-in-cart .add-button {
+ display: none;
+}
+
+.product-card.next-in-cart .remove-button {
+ display: block;
+}
+```
+
+### Selector Card States
+
+```css
+/* Selector cards */
+[data-next-selector-card] {
+ border: 2px solid #ddd;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+/* Hover state */
+[data-next-selector-card]:hover {
+ border-color: #007bff;
+}
+
+/* Selected state */
+[data-next-selector-card].next-selected {
+ border-color: #007bff;
+ background: #e7f3ff;
+}
+
+/* Selected indicator */
+[data-next-selector-card].next-selected::after {
+ content: '✓';
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ color: #007bff;
+}
+```
+
+### Loading States
+
+```css
+/* Loading skeleton animation */
+[data-next-await]::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
+ background-size: 200% 100%;
+ animation: loading 1.5s infinite;
+}
+
+@keyframes loading {
+ 0% { background-position: 200% 0; }
+ 100% { background-position: -200% 0; }
+}
+
+/* Hide skeleton when ready */
+html.next-display-ready [data-next-await]::before {
+ display: none;
+}
+```
+
+## Advanced Patterns
+
+### Multi-State Styling
+
+```css
+/* Combine multiple states */
+.product-card.next-in-cart [data-next-toggle].next-active {
+ background: #dc3545;
+ color: white;
+}
+
+/* Different styles for different pages */
+html[data-page-type="checkout"] .next-in-cart {
+ /* Checkout-specific styles */
+}
+```
+
+### Animation on State Change
+
+```css
+/* Animate when item added to cart */
+@keyframes addedToCart {
+ 0% { transform: scale(1); }
+ 50% { transform: scale(1.1); }
+ 100% { transform: scale(1); }
+}
+
+.product-card:not(.next-in-cart) {
+ animation: none;
+}
+
+.product-card.next-in-cart {
+ animation: addedToCart 0.3s ease;
+}
+```
+
+### Responsive State Styling
+
+```css
+/* Mobile adjustments */
+@media (max-width: 768px) {
+ [data-next-selector-card].next-selected {
+ border-width: 3px;
+ }
+
+ button[data-next-toggle].next-active {
+ font-size: 14px;
+ padding: 10px;
+ }
+}
+```
+
+## Best Practices
+
+1. **Use CSS Classes**: Style based on SDK classes, not attributes
+2. **Smooth Transitions**: Add transitions for state changes
+3. **Clear Visual Feedback**: Make states obvious to users
+4. **Accessibility**: Ensure state changes are perceivable
+5. **Performance**: Use CSS transforms over layout changes
+
+## Class Reference Table
+
+| Class | Applied To | When |
+|-------|------------|------|
+| `.next-in-cart` | Elements with package ID | Package is in cart |
+| `.next-active` | Toggle buttons | Toggle is active |
+| `.next-selected` | Selector cards | Card is selected |
+| `.next-selector-active` | Selector container | Has selection |
+| `.next-disabled` | Action buttons | Action unavailable |
+| `.next-display-ready` | `` | SDK initialized |
+| `.next-loading` | `` | Loading data |
\ No newline at end of file
diff --git a/docs/campaign-cart/data-attributes/display.md b/docs/campaign-cart/data-attributes/display.md
new file mode 100644
index 00000000..17d71788
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/display.md
@@ -0,0 +1,744 @@
+---
+title: Display Attributes
+description: Show dynamic data that updates automatically
+sidebar_position: 3
+---
+
+**Display attributes bind HTML elements to live data that updates automatically when state changes.**
+
+## data-next-display
+
+The primary attribute for showing dynamic values from cart, campaign, and order data.
+
+### Basic Usage
+
+```html
+
+$0.00
+$0.00
+$0.00
+$0.00
+$0.00
+
+
+0
+0
+
+
+$0.00
+Loading...
+Loading...
+```
+
+### Display Paths
+
+| Path | Description | Example Output |
+|------|-------------|----------------|
+| `cart.total` | Total cart value | "$99.99" |
+| `cart.subtotal` | Subtotal before shipping/tax | "$89.99" |
+| `cart.shipping` | Shipping cost | "$10.00" |
+| `cart.tax` | Tax amount | "$8.00" |
+| `cart.discount` | Discount amount | "-$10.00" |
+| `cart.totalQuantity` | Total items in cart | "5" |
+| `cart.itemCount` | Unique items in cart | "3" |
+| `cart.isEmpty` | Cart empty state | "true" or "false" |
+| `package.[id].price` | Package price | "$29.99" |
+| `package.[id].name` | Package display name | "Premium Bundle" |
+| `package.[id].description` | Package description | "Includes everything..." |
+| `package.[id].savings` | Discount amount | "$10.00" |
+| `package.[id].quantity` | Quantity in cart | "2" |
+| `campaign.name` | Campaign name | "Summer Sale" |
+| `campaign.currency` | Active currency | "USD" |
+| `order.total` | Order total | "$99.99" |
+| `order.refId` | Order reference | "ORD-12345" |
+| `profile.active` | Active profile | "premium" |
+
+### Formatting Options
+
+Use `data-format` to control how values are displayed:
+
+```html
+
+
+ $0.00
+
+
+
+
+ 0.00
+
+
+
+
+ 0
+
+
+
+
+ 0%
+
+
+
+
+ $100
+
+```
+
+### Mathematical Operations
+
+```html
+
+
+ 0.99
+
+
+
+
+ 30
+
+
+
+
+ $20.00
+
+```
+
+## Conditional Display
+
+### data-next-show
+
+Show element when condition is true:
+
+```html
+
+
+ Your cart has items!
+
+
+
+
+ Premium package selected
+
+
+
+
+ Free shipping unlocked!
+
+
+
+
+ Bulk discount applied!
+
+```
+
+### data-next-hide
+
+Hide element when condition is true (inverse of show):
+
+```html
+
+
+
+
+
+
+
+
+ Checkout available
+
+```
+
+### data-hide-if-zero
+
+Hide element when displayed value is zero:
+
+```html
+
+
+ Discount: $0.00
+
+
+
+
+ Shipping: $0.00
+
+```
+
+### data-hide-if-false
+
+Hide element when value is false:
+
+```html
+
+ Discount applied!
+
+```
+
+## Profile-Based Display
+
+Show/hide content based on active profile:
+
+```html
+
+
+```
+
+## Fallback Content
+
+Always provide fallback content for progressive enhancement:
+
+```html
+
+
+ Starting at $29.99
+
+
+
+
+ Check availability
+
+
+
+
+ Loading campaign...
+
+```
+
+## Debugging Display
+
+Enable debug mode to see:
+- Which elements are bound to data
+- Update frequency and performance
+- Data path resolution
+- Formatting applied
+
+```html
+
+
+ $99.99
+
+```
+
+## Related Documentation
+
+- [Actions](/docs/data-attributes/actions/) - Interactive elements
+- [State Management](/docs/data-attributes/state/) - Conditional logic
+- [Events](/docs/campaign-cart/javascript-api/events/) - React to data changes
+- [Cart Display](/docs/building-blocks/cart-display/) - Complete cart UI patterns
\ No newline at end of file
diff --git a/docs/campaign-cart/data-attributes/index.md b/docs/campaign-cart/data-attributes/index.md
new file mode 100644
index 00000000..cd0fe01c
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/index.md
@@ -0,0 +1,311 @@
+---
+title: Data Attributes Reference
+description: Complete catalog of every data-next-* attribute that controls SDK behavior
+sidebar_position: 3
+---
+
+**Data attributes are the API through which your HTML communicates with the Campaign Cart SDK.**
+
+## Core Principles
+
+- **HTML as the Source of Truth:** Behavior is defined in markup, not JavaScript files
+- **Progressive Enhancement:** Elements work without JavaScript, transform with it
+- **Composable Patterns:** Combine attributes to create complex behaviors
+- **State Management:** The SDK automatically tracks and updates element states
+
+## Attribute Categories
+
+### Display Attributes
+
+These attributes bind elements to dynamic data that updates automatically when state changes.
+
+| Attribute | Purpose | Example |
+|-----------|---------|---------|
+| `data-next-display` | Display dynamic data | `data-next-display="cart.total"` |
+| `data-next-show` | Conditionally show element | `data-next-show="cart.isEmpty === false"` |
+| `data-next-hide` | Conditionally hide element | `data-next-hide="cart.total < 100"` |
+| `data-next-timer` | Countdown timer display | `data-next-timer="true" data-duration="300"` |
+
+This means: Your UI stays synchronized with cart state without writing any JavaScript.
+
+### Action Attributes
+
+These attributes turn any element into an interactive component.
+
+| Attribute | Purpose | Example |
+|-----------|---------|---------|
+| `data-next-action` | Define element action | `data-next-action="add-to-cart"` |
+| `data-next-package-id` | Target package for action | `data-next-package-id="123"` |
+| `data-next-quantity` | Quantity for action | `data-next-quantity="2"` |
+| `data-next-toggle` | Toggle cart state | `data-next-toggle="cart"` |
+| `data-next-clear-cart` | Clear cart before action | `data-next-clear-cart="true"` |
+| `data-next-url` | Redirect after action | `data-next-url="/checkout"` |
+
+This means: Any element can trigger cart operations - buttons, images, links, or custom components.
+
+### Configuration Attributes
+
+These attributes configure component behavior and appearance.
+
+| Attribute | Purpose | Example |
+|-----------|---------|---------|
+| `data-format` | Number/price formatting | `data-format="currency"` |
+| `data-hide-if-zero` | Hide when value is zero | `data-hide-if-zero="true"` |
+| `data-hide-zero-cents` | Hide .00 in prices | `data-hide-zero-cents="true"` |
+| `data-divide-by` | Mathematical division | `data-divide-by="100"` |
+| `data-multiply-by` | Mathematical multiplication | `data-multiply-by="1.2"` |
+
+### State Attributes
+
+These attributes reflect current state and enable conditional logic.
+
+| Attribute | Purpose | Example |
+|-----------|---------|---------|
+| `data-next-selected` | Pre-selected state | `data-next-selected="true"` |
+| `data-next-in-cart` | Item is in cart | Automatically managed |
+| `data-next-loading` | Loading state | Automatically managed |
+| `data-next-disabled` | Disabled state | Automatically managed |
+
+## Common Patterns
+
+### Add to Cart Button
+
+```html
+
+```
+
+The SDK automatically:
+- Toggles button text based on cart state
+- Adds loading states during operations
+- Updates aria-labels for accessibility
+- Prevents double-clicks
+
+### Dynamic Price Display
+
+```html
+
+ $0.00
+
+```
+
+The SDK automatically:
+- Fetches current price from campaign data
+- Formats according to user's locale
+- Updates when currency changes
+- Falls back to default content if data unavailable
+
+### Conditional Content
+
+```html
+
+ Your cart has 0 items
+
+
+
+ Your cart is empty
+
+```
+
+The SDK automatically:
+- Evaluates conditions on every state change
+- Uses CSS classes for performance (no DOM manipulation)
+- Maintains layout stability (no content shifting)
+
+### Package Selector
+
+```html
+
+
+
+
+
+```
+
+The SDK automatically:
+- Manages selection state across options
+- Updates cart when selection changes
+- Applies active/selected classes
+- Handles keyboard navigation
+
+## Advanced Patterns
+
+### Quantity Controls with Sync
+
+```html
+
+
+
+
+
+
+
+```
+
+This creates a complete quantity control that:
+- Syncs with cart state
+- Respects min/max limits
+- Updates on external changes
+- Handles keyboard input
+
+### Timer with Persistence
+
+```html
+
+ 05:00
+
+```
+
+This creates a countdown timer that:
+- Persists across page refreshes
+- Formats time as minutes:seconds
+- Emits events at milestones
+- Auto-hides when complete
+
+### Profile-Based Display
+
+```html
+
+ Premium member exclusive content
+
+
+
+
+
+```
+
+This enables:
+- A/B testing without code changes
+- Customer segment targeting
+- Dynamic content based on user profiles
+
+## Performance Implications
+
+### Efficient Patterns
+
+✅ **Use specific display paths**
+```html
+$0
+```
+
+✅ **Combine conditions in single attribute**
+```html
+
+```
+
+## Debugging Attributes
+
+Enable debug mode with `?debugger=true` to see:
+- Which elements have been enhanced
+- Current attribute values
+- State changes in real-time
+- Performance metrics
+
+```html
+
+
+ $99.00
+
+```
+
+## Edge Cases
+
+### Multiple Actions on Single Element
+
+```html
+
+
+```
+
+Execution order:
+1. Clear cart
+2. Add package to cart
+3. Redirect to checkout
+
+### Dynamic Attribute Updates
+
+The SDK observes attribute changes:
+
+```javascript
+// This will trigger SDK re-enhancement
+element.setAttribute('data-next-package-id', '456');
+```
+
+### Fallback Content
+
+Always provide fallback content for progressive enhancement:
+
+```html
+
+$0.00
+
+
+
+ Limited time offer!
+
+```
+
+## Related Documentation
+
+- [JavaScript API](/docs/campaign-cart/javascript-api/) - JavaScript methods reference
+- [Events](/docs/campaign-cart/javascript-api/events/) - Responding to SDK events
+- [CSS Classes](/docs/campaign-cart/data-attributes/css-classes/) - Styling enhanced elements
\ No newline at end of file
diff --git a/docs/campaign-cart/data-attributes/order-data.md b/docs/campaign-cart/data-attributes/order-data.md
new file mode 100644
index 00000000..a1efd0ba
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/order-data.md
@@ -0,0 +1,790 @@
+---
+title: Order Data Attributes
+description: Display order confirmation data on thank you pages with order.* attributes
+sidebar_position: 6
+---
+
+**Order attributes display order confirmation data on thank you pages and post-purchase flows.**
+
+The order data is automatically loaded when the URL contains `?ref_id=ORDER_ID` and provides access to complete order information including customer details, line items, pricing, addresses, and attribution data.
+
+## Auto-Loading from URL
+
+Orders automatically load when the URL contains the `ref_id` parameter:
+
+```
+https://example.com/confirmation?ref_id=ORDER_123
+```
+
+The SDK detects this parameter and loads the complete order data, making all `order.*` attributes available for display.
+
+## Loading States
+
+Order data has three states that should be handled in your confirmation page:
+
+```html
+
+
+
Loading your order...
+
+
+
+
+
Unable to load order
+
Error details
+
+
+
+
+
+
+```
+
+The SDK automatically adds CSS classes to help with styling:
+- `.next-loading` - Applied when order is loading
+- `.next-loaded` - Applied when order loaded successfully
+- `.next-error` - Applied when error occurred
+
+## Basic Order Properties
+
+Display order identification, status, and metadata.
+
+```html
+
+12345
+ORD-001
+abc123xyz
+abc123xyz
+
+
+Processing
+2024-01-15
+2024-01-15
+USD
+
+
+View Order Status
+View Order Status
+```
+
+### Test Order Badge
+
+Display a badge when the order is a test transaction:
+
+```html
+
+🧪 TEST ORDER
+
+
+
+
This is a test order
+
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.id` | Order ID number | String/Number |
+| `order.number` | Human-readable order number | String/Number |
+| `order.ref_id` | Reference ID (snake_case) | String |
+| `order.refId` | Reference ID (camelCase) | String |
+| `order.status` | Order status | String |
+| `order.is_test` | Test order flag (snake_case) | Boolean |
+| `order.isTest` | Test order flag (camelCase) | Boolean |
+| `order.testBadge` | "🧪 TEST ORDER" text or empty | String |
+| `order.order_status_url` | Order status URL (snake_case) | String (URL) |
+| `order.statusUrl` | Order status URL (camelCase) | String (URL) |
+| `order.created_at` | Order creation date (snake_case) | String |
+| `order.createdAt` | Order creation date (camelCase) | String |
+| `order.currency` | Currency code | String |
+| `order.supports_upsells` | Supports upsells (snake_case) | Boolean |
+| `order.supportsUpsells` | Supports upsells (camelCase) | Boolean |
+
+## Order Financial Data
+
+Display order totals, taxes, shipping, and discounts.
+
+### Understanding Order Totals
+
+Order totals have specific meanings:
+
+- **`order.subtotal`** - Line items only (excludes shipping and tax)
+- **`order.total_excl_tax`** - Total excluding tax but INCLUDING shipping
+- **`order.total`** - Grand total including everything (products + shipping + tax)
+
+```html
+
+
Subtotal: $0.00
+
Shipping: $0.00
+
Tax: $0.00
+
Total: $0.00
+```
+
+### Complete Order Summary Example
+
+```html
+
+
+
+ Subtotal:
+ $0.00
+
+
+
+
+ Shipping:
+ $0.00
+
+
+
+
+ Tax:
+ $0.00
+
+
+
+
+ Discount:
+ -$0.00
+
+
+
+
+ You saved:
+
+ $0.00
+ (0%)
+
+
+
+
+
+ Total:
+ $0.00
+
+
+```
+
+### Financial Attributes Reference
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.total_incl_tax` | Grand total including tax and shipping | Currency |
+| `order.total` | Grand total (alias) | Currency |
+| `order.subtotal` | Line items only | Currency |
+| `order.subtotalExclShipping` | Line items only (alias) | Currency |
+| `order.total_excl_tax` | Total excluding tax (includes shipping) | Currency |
+| `order.total_tax` | Tax amount (snake_case) | Currency |
+| `order.tax` | Tax amount (alias) | Currency |
+| `order.shipping_incl_tax` | Shipping including tax (snake_case) | Currency |
+| `order.shipping` | Shipping including tax (alias) | Currency |
+| `order.shipping_excl_tax` | Shipping excluding tax (snake_case) | Currency |
+| `order.shippingExclTax` | Shipping excluding tax (camelCase) | Currency |
+| `order.shipping_tax` | Shipping tax amount (snake_case) | Currency |
+| `order.shippingTax` | Shipping tax amount (camelCase) | Currency |
+| `order.total_discounts` | Total discounts (snake_case) | Currency |
+| `order.discounts` | Total discounts (alias) | Currency |
+| `order.savingsAmount` | Calculated savings amount | Currency |
+| `order.savingsPercentage` | Savings percentage | Number |
+| `order.payment_method` | Payment method (snake_case) | String |
+| `order.paymentMethod` | Payment method (camelCase) | String |
+| `order.shipping_method` | Shipping method (snake_case) | String |
+| `order.shippingMethod` | Shipping method (camelCase) | String |
+
+### Raw Values for Calculations
+
+Use the `.raw` suffix to get numeric values for mathematical operations:
+
+```html
+
+0%
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.total.raw` | Total as number | Number |
+| `order.subtotal.raw` | Subtotal as number | Number |
+| `order.tax.raw` | Tax as number | Number |
+| `order.shipping.raw` | Shipping as number | Number |
+| `order.discounts.raw` | Discounts as number | Number |
+
+## Customer Information
+
+Display customer contact details and preferences.
+
+```html
+
+
+
John Doe
+
john@example.com
+
+ Phone: 555-123-4567
+
+
+
+
+
+ ✓ Subscribed to marketing emails
+
+```
+
+### Customer Attributes Reference
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.customer.name` | Full customer name | String |
+| `order.customer.firstName` | First name only | String |
+| `order.customer.lastName` | Last name only | String |
+| `order.customer.email` | Customer email | String |
+| `order.customer.phone` | Customer phone | String |
+| `order.customer.acceptsMarketing` | Marketing opt-in | Boolean |
+| `order.customer.language` | Customer language | String |
+| `order.customer.ip` | Customer IP address | String |
+
+### User Aliases
+
+`order.user.*` is an alias for `order.customer.*` and provides the same properties:
+
+```html
+
+John Doe
+John Doe
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.user.name` | Full name (alias) | String |
+| `order.user.firstName` | First name (alias) | String |
+| `order.user.lastName` | Last name (alias) | String |
+| `order.user.email` | Email (alias) | String |
+| `order.user.phone` | Phone (alias) | String |
+
+## Address Information
+
+Display shipping and billing addresses.
+
+### Shipping Address
+
+```html
+
+
Shipping Address
+
+ -
+ -
+
+ -
+
+ -,
+ -
+ -
+ -
+
+
+```
+
+### Full Formatted Address
+
+Use the `.full` property to get a pre-formatted address string:
+
+```html
+
+ 123 Main St, Springfield, IL 62701, USA
+
+```
+
+### Shipping Address Attributes
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.shippingAddress.full` | Full formatted address | String |
+| `order.shippingAddress.name` | Recipient name | String |
+| `order.shippingAddress.line1` | Address line 1 | String |
+| `order.shippingAddress.line2` | Address line 2 | String |
+| `order.shippingAddress.city` | City | String |
+| `order.shippingAddress.state` | State/Province | String |
+| `order.shippingAddress.zip` | ZIP code | String |
+| `order.shippingAddress.postcode` | Postcode (alias) | String |
+| `order.shippingAddress.country` | Country | String |
+| `order.shippingAddress.phone` | Phone number | String |
+
+### Billing Address Attributes
+
+Billing address has identical properties to shipping address:
+
+```html
+
+
Billing Address
+ -
+
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.billingAddress.full` | Full formatted address | String |
+| `order.billingAddress.name` | Recipient name | String |
+| `order.billingAddress.line1` | Address line 1 | String |
+| `order.billingAddress.line2` | Address line 2 | String |
+| `order.billingAddress.city` | City | String |
+| `order.billingAddress.state` | State/Province | String |
+| `order.billingAddress.zip` | ZIP code | String |
+| `order.billingAddress.postcode` | Postcode (alias) | String |
+| `order.billingAddress.country` | Country | String |
+| `order.billingAddress.phone` | Phone number | String |
+
+## Line Items
+
+Display order items and product details.
+
+### Aggregate Line Item Data
+
+```html
+
+
Items: 0
+
Quantity: 0
+
+
+
Product Name
+
SKU: -
+
+
+
+ Includes 0 bonus item(s)
+
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.lines.count` | Number of line items | Number |
+| `order.lines.totalQuantity` | Total quantity of all items | Number |
+| `order.lines.upsellCount` | Number of upsell items | Number |
+| `order.lines.mainProduct` | Main product title (first item) | String |
+| `order.lines.mainProductSku` | Main product SKU (first item) | String |
+| `order.items.count` | Line item count (alias) | Number |
+| `order.items.totalQuantity` | Total quantity (alias) | Number |
+
+### Accessing Individual Line Items
+
+Access specific line items using array index notation:
+
+```html
+
+
+
Product Name
+
SKU: -
+
Quantity: 1
+
Price: $0.00
+
Total: $0.00
+
+
+
+
+
Product Name
+
+```
+
+### Line Item Attributes
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.lines[n].title` | Product title | String |
+| `order.lines[n].product_title` | Product title (snake_case) | String |
+| `order.lines[n].sku` | Product SKU | String |
+| `order.lines[n].product_sku` | Product SKU (snake_case) | String |
+| `order.lines[n].quantity` | Quantity ordered | Number |
+| `order.lines[n].image` | Product image URL | String (URL) |
+| `order.lines[n].price` | Unit price including tax | Currency |
+| `order.lines[n].priceExclTax` | Unit price excluding tax | Currency |
+| `order.lines[n].priceExclTaxExclDiscounts` | Original price before discounts | Currency |
+| `order.lines[n].priceInclTaxExclDiscounts` | Original price with tax before discounts | Currency |
+| `order.lines[n].total` | Line total including tax | Currency |
+| `order.lines[n].totalExclTax` | Line total excluding tax | Currency |
+| `order.lines[n].isUpsell` | Is upsell item | Boolean |
+
+### Line Item Raw Values
+
+Use `.raw` for numeric calculations:
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `order.lines[n].price.raw` | Unit price as number | Number |
+| `order.lines[n].priceExclTax.raw` | Unit price excl tax as number | Number |
+| `order.lines[n].priceExclTaxExclDiscounts.raw` | Original price as number | Number |
+| `order.lines[n].priceInclTaxExclDiscounts.raw` | Original price with tax as number | Number |
+| `order.lines[n].total.raw` | Line total as number | Number |
+| `order.lines[n].totalExclTax.raw` | Line total excl tax as number | Number |
+
+## Order Items Renderer
+
+The `data-next-order-items` attribute automatically renders all line items using customizable templates.
+
+### Basic Usage
+
+```html
+
+
+
{item.name}
+ Qty: {item.quantity}
+ {item.lineTotal}
+
+
+```
+
+### Template Configuration
+
+Templates can be defined in multiple ways:
+
+#### Template by ID
+
+```html
+
+
+
+
+
{item.name}
+ Qty: {item.quantity}
+ {item.lineTotal}
+
+
+
+
+
+
+```
+
+#### Inline Template
+
+```html
+
+
+```
+
+### Template Variables
+
+#### Basic Properties
+
+| Variable | Description | Type |
+|----------|-------------|------|
+| `{item.id}` | Order line ID | String |
+| `{item.name}` | Product name | String |
+| `{item.title}` | Product title (alias) | String |
+| `{item.sku}` | Product SKU | String |
+| `{item.quantity}` | Quantity ordered | Number |
+| `{item.description}` | Product description | String |
+| `{item.variant}` | Variant title | String |
+| `{item.image}` | Product image URL | String |
+
+#### Pricing Variables
+
+| Variable | Description | Type |
+|----------|-------------|------|
+| `{item.price}` | Unit price including tax | Currency |
+| `{item.priceExclTax}` | Unit price excluding tax | Currency |
+| `{item.unitTax}` | Tax per unit | Currency |
+| `{item.lineTotal}` | Line total including tax | Currency |
+| `{item.lineTotalExclTax}` | Line total excluding tax | Currency |
+| `{item.lineTax}` | Total tax for line | Currency |
+
+#### Original Pricing (Before Discounts)
+
+| Variable | Description | Type |
+|----------|-------------|------|
+| `{item.priceExclDiscounts}` | Original unit price (incl tax) | Currency |
+| `{item.priceExclTaxExclDiscounts}` | Original unit price (excl tax) | Currency |
+| `{item.lineTotalExclDiscounts}` | Original line total (incl tax) | Currency |
+| `{item.lineTotalExclTaxExclDiscounts}` | Original line total (excl tax) | Currency |
+| `{item.unitDiscount}` | Discount per unit | Currency |
+| `{item.lineDiscount}` | Total line discount | Currency |
+
+#### Status Flags
+
+| Variable | Description | Value |
+|----------|-------------|-------|
+| `{item.isUpsell}` | Is upsell item | "true" or "false" |
+| `{item.upsellBadge}` | Upsell badge text | "UPSELL" or "" |
+| `{item.hasImage}` | Has image | "true" or "false" |
+| `{item.hasDescription}` | Has description | "true" or "false" |
+| `{item.hasVariant}` | Has variant | "true" or "false" |
+| `{item.hasTax}` | Has tax | "true" or "false" |
+| `{item.hasDiscount}` | Has discount | "true" or "false" |
+
+#### Conditional Display Classes
+
+| Variable | Description | Value |
+|----------|-------------|-------|
+| `{item.showUpsell}` | Show upsell badge | "show" or "hide" |
+| `{item.showImage}` | Show image | "show" or "hide" |
+| `{item.showDescription}` | Show description | "show" or "hide" |
+| `{item.showVariant}` | Show variant | "show" or "hide" |
+| `{item.showTax}` | Show tax | "show" or "hide" |
+| `{item.showDiscount}` | Show discount | "show" or "hide" |
+
+### Complete Renderer Example
+
+```html
+
+
+
+```
+
+### Profile Selector Dropdown
+```html
+
+
+
+
+
+```
+
+## Profile Switcher Options
+
+### data-next-clear-cart
+Clears the cart before applying the new profile.
+- **Values**: `true` | `false`
+- **Default**: `false`
+
+```html
+
+```
+
+### data-next-preserve-quantities
+Maintains item quantities when swapping packages.
+- **Values**: `true` | `false`
+- **Default**: `true`
+
+```html
+
+```
+
+### data-next-active-text / data-next-inactive-text
+Dynamic button text based on profile state.
+
+```html
+
+```
+
+## CSS Classes
+
+Automatically applied classes for styling profile elements.
+
+### Profile State Classes
+- `.next-profile-active` - Applied when the profile is active
+- `.next-profile-switcher` - Applied to profile switcher buttons
+- `.next-profile-selector` - Applied to profile selector dropdowns
+- `.next-profile-loading` - Applied during profile switching
+
+### Conditional Display Classes
+- `.next-condition-met` - Applied when profile condition is true
+- `.next-condition-not-met` - Applied when profile condition is false
+- `.next-visible` - Applied when element should be shown
+- `.next-hidden` - Applied when element should be hidden
+
+## Real-World Examples
+
+### Exit Intent Profile
+```html
+
+
+
Wait! Don't Leave Yet!
+
We've activated a special 10% discount just for you!
+
+
+
+```
+
+### VIP Member Dashboard
+```html
+
+
+
Welcome VIP Member!
+
+
Your Benefits:
+
+
Exclusive VIP pricing
+
Free shipping on all orders
+
Priority customer support
+
+
+
+
+```
+
+### Dynamic Pricing Display
+```html
+
+
+
+
+
Regular Price
+ $99.99
+
+
+
+
+
BLACK FRIDAY DEAL!
+ $99.99
+ $49.99
+ Save 50%!
+
+
+```
+
+### Profile-Based Navigation
+```html
+
+
+```
+
+## JavaScript Events
+
+Listen for profile-related events:
+
+```javascript
+// Profile applied
+window.next.on('profile:applied', (data) => {
+ console.log(`Profile ${data.profileId} applied`);
+ console.log(`${data.itemsSwapped} items updated`);
+});
+
+// Profile reverted
+window.next.on('profile:reverted', (data) => {
+ console.log(`Reverted from ${data.previousProfileId}`);
+});
+
+// Profile switched
+window.next.on('profile:switched', (data) => {
+ console.log(`Switched from ${data.fromProfileId} to ${data.toProfileId}`);
+});
+```
+
+## Notes
+
+1. **Profile Priority**: Only one profile can be active at a time
+2. **Package Mapping**: Profiles map package IDs to different packages (e.g., regular → sale version)
+3. **Cart Persistence**: By default, cart items are swapped to mapped packages when profiles change
+4. **URL Parameters**: Profiles can be activated via URL: `?profile=black_friday` or `?forceProfile=vip`
+5. **Session Storage**: Active profile persists across page refreshes in the same session
+
+## Related Documentation
+
+- [State Attributes](/docs/campaign-cart/data-attributes/state/) - Profile conditionals
+- [Configuration Attributes](/docs/campaign-cart/data-attributes/configuration/) - Profile switcher configuration
+- [Display Attributes](/docs/campaign-cart/data-attributes/display/) - Display profile data
+
diff --git a/docs/campaign-cart/data-attributes/selection.md b/docs/campaign-cart/data-attributes/selection.md
new file mode 100644
index 00000000..d9bea905
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/selection.md
@@ -0,0 +1,448 @@
+---
+title: Selection Attributes
+description: Display data based on currently selected package in product selectors
+sidebar_position: 9
+---
+
+**Selection attributes display data based on the currently selected package in a selector and update automatically when the selection changes.**
+
+Use selection attributes to show real-time pricing, savings, and product information as customers interact with your product selectors.
+
+## Selection Data Path
+
+Selection data is accessed using the pattern:
+
+```
+selection.{selectorId}.{property}
+```
+
+Where `{selectorId}` is the unique identifier specified in the `data-next-selector-id` attribute on the selector container.
+
+## Basic Selection Properties
+
+Display information about the currently selected package:
+
+```html
+
+Product Name
+
+
+123
+
+
+1
+
+
+
+ Something is selected
+
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `selection.{selectorId}.name` | Selected package name | String |
+| `selection.{selectorId}.packageId` | Selected package ID | Number |
+| `selection.{selectorId}.quantity` | Selected quantity | Number |
+| `selection.{selectorId}.hasSelection` | Whether something is selected | Boolean |
+
+## Selection Pricing
+
+Display pricing information for the selected package:
+
+```html
+
+$99.00
+
+
+$99.00
+
+
+$149.00
+
+
+$99.00
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `selection.{selectorId}.price` | Unit price of selection | Currency |
+| `selection.{selectorId}.total` | Total price (price × quantity) | Currency |
+| `selection.{selectorId}.compareTotal` | Compare at price total | Currency |
+| `selection.{selectorId}.unitPrice` | Price per unit | Currency |
+
+## Selection Calculated Fields
+
+Display savings and bundle information:
+
+```html
+
+$50.00
+
+
+33%
+
+
+
+ You save money with this selection!
+
+
+
+
+ Multi-pack deal
+
+
+
+3 units
+```
+
+| Property | Description | Type |
+|----------|-------------|------|
+| `selection.{selectorId}.savingsAmount` | Total savings amount | Currency |
+| `selection.{selectorId}.savingsPercentage` | Savings percentage | Number |
+| `selection.{selectorId}.hasSavings` | Has savings | Boolean |
+| `selection.{selectorId}.isBundle` | Is multi-pack bundle | Boolean |
+| `selection.{selectorId}.totalUnits` | Total units in selection | Number |
+
+## Mathematical Expressions
+
+Perform calculations with selection data:
+
+```html
+
+$9.90
+
+
+$104.00
+
+
+$89.00
+
+
+$49.50
+```
+
+Supported operators: `*` (multiply), `/` (divide), `+` (add), `-` (subtract)
+
+## Selector Container
+
+Create a product selector using the `data-next-cart-selector` attribute:
+
+```html
+
+
+
+```
+
+### Selector Container Attributes
+
+| Attribute | Required | Description | Example |
+|-----------|----------|-------------|---------|
+| `data-next-cart-selector` | Yes | Marks element as a selector container | `data-next-cart-selector` |
+| `data-next-selector-id` | Yes | Unique identifier for the selector | `data-next-selector-id="main-product"` |
+| `data-next-selection-mode` | No | Selection mode (swap, select, multi) | `data-next-selection-mode="swap"` |
+
+## Selector Cards
+
+Create selectable options within the selector:
+
+```html
+
+
+
+ 1 Pack - $99
+
+
+
+
+ 3 Pack - $249
+
+
+
+
+ 5 Pack - $399
+
+
+```
+
+### Selector Card Attributes
+
+| Attribute | Required | Description |
+|-----------|----------|-------------|
+| `data-next-selector-card` | Yes | Marks element as a selectable card |
+| `data-next-package-id` | Yes | Package ID to select when clicked |
+| `data-next-selected` | No | Pre-select this card (true/false) |
+| `data-next-quantity` | No | Initial quantity for this card |
+| `data-next-min-quantity` | No | Minimum quantity allowed (default: 1) |
+| `data-next-max-quantity` | No | Maximum quantity allowed (default: 999) |
+
+## Quantity Controls
+
+Add quantity adjustment controls to selector cards:
+
+```html
+
+
+
Premium Package
+
$19.99 each
+
+
+
+
+ 1
+
+
+
+
+
+ Total: $19.99
+
+
+```
+
+### Quantity Control Attributes
+
+| Attribute | Description | Behavior |
+|-----------|-------------|----------|
+| `data-next-quantity-increase` | Increase quantity button | Auto-disables at max quantity |
+| `data-next-quantity-decrease` | Decrease quantity button | Auto-disables at min quantity |
+| `data-next-quantity-display` | Display current quantity | Updates automatically |
+| `data-next-min-quantity` | Minimum allowed quantity | Default: 1 |
+| `data-next-max-quantity` | Maximum allowed quantity | Default: 999 |
+
+### Automatic Behavior
+
+- **Auto-disable**: Decrease button gets `disabled` attribute and `next-disabled` class at minimum
+- **Auto-disable**: Increase button gets `disabled` attribute and `next-disabled` class at maximum
+- **Cart sync**: In `swap` mode, quantity changes update the cart automatically
+- **Display updates**: All `selection.{selectorId}.total` elements update with quantity
+- **Event prevention**: Quantity button clicks don't trigger card selection
+
+## Complete Example
+
+Product selector with selection display and quantity controls:
+
+```html
+
+
+
+
+
+
+
1 Pack
+
$99.00 each
+
+
+
+
+ 1
+
+
+
+
+
+ Total: $99.00
+
+
+
+
+
+
3 Pack
+
$249.00
+
+
+
+
5 Pack
+
$399.00
+
+
+
+
+
+
Your Selection
+
+
+
+ Please select a package
+
+
+
+
+
Selected: -
+
Quantity: 0 units
+
Price: $0
+
+
+
+
You save: $0
+ (0%)
+
+
+
+
+
+
+
+```
+
+## Dynamic Pricing Display
+
+Show different messages based on selection price:
+
+```html
+
+
+
+
+
+
+ Basic protection for under $20
+
+
+ Premium protection
+
+
+ Ultimate protection package
+
+
+```
+
+## Multiple Selectors
+
+Use multiple selectors on one page and combine their totals:
+
+```html
+
+
+
+ Main Product - $99
+
+
+ Premium Product - $149
+
+
+
+
+
+
+ Basic Accessory - $19
+
+
+ Premium Accessory - $39
+
+
+
+
+
+
Product: $0
+
Accessory: $0
+
+
Total: $0
+
+```
+
+## Conditional Display
+
+Show/hide content based on selection state:
+
+```html
+
+
+
Choose a package to see pricing
+
+
+
+
+
You selected:
+
+
+
+
+ SAVE %
+
+
+
+
+ BUNDLE DEAL
+
+```
+
+## Selection Properties Reference
+
+### Basic Properties
+
+| Property | Description | Type | Example Value |
+|----------|-------------|------|---------------|
+| `name` | Package name | String | "Premium Package" |
+| `packageId` | Package ID | Number | 123 |
+| `quantity` | Selected quantity | Number | 2 |
+| `hasSelection` | Selection exists | Boolean | true |
+
+### Pricing Properties
+
+| Property | Description | Type | Example Value |
+|----------|-------------|------|---------------|
+| `price` | Unit price | Currency | "$99.00" |
+| `total` | Total price | Currency | "$198.00" |
+| `compareTotal` | Compare total | Currency | "$298.00" |
+| `unitPrice` | Price per unit | Currency | "$99.00" |
+
+### Calculated Properties
+
+| Property | Description | Type | Example Value |
+|----------|-------------|------|---------------|
+| `savingsAmount` | Total savings | Currency | "$100.00" |
+| `savingsPercentage` | Savings % | Number | 33 |
+| `hasSavings` | Has savings | Boolean | true |
+| `isBundle` | Is bundle | Boolean | true |
+| `totalUnits` | Total units | Number | 6 |
+
+## Best Practices
+
+1. **Use unique selector IDs**
+ - Choose descriptive, unique IDs for each selector
+ - Example: `main-product`, `warranty`, `accessory`
+
+2. **Show selection feedback**
+ - Display selected package details
+ - Show pricing updates in real-time
+
+3. **Use conditional display**
+ - Hide/show elements based on `hasSelection`
+ - Guide users through the selection process
+
+4. **Display price updates**
+ - Show real-time pricing as quantity changes
+ - Highlight savings when applicable
+
+5. **Validate before actions**
+ - Hide "Add to Cart" button until selection is made
+ - Use `data-next-hide="!selection.{selectorId}.hasSelection"`
+
+6. **Set appropriate quantity limits**
+ - Use `data-next-min-quantity` and `data-next-max-quantity`
+ - Match limits to your inventory/business rules
+
+## Related Documentation
+
+- [Display Attributes](/data-attributes/display/) - Display dynamic data
+- [Action Attributes](/data-attributes/actions/) - Add to cart actions
+- [State Attributes](/data-attributes/state/) - Conditional display
diff --git a/docs/campaign-cart/data-attributes/state.md b/docs/campaign-cart/data-attributes/state.md
new file mode 100644
index 00000000..dce3529b
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/state.md
@@ -0,0 +1,552 @@
+---
+title: State & Conditional Attributes
+description: Control element visibility and behavior based on cart and application state
+sidebar_position: 4
+---
+
+**State attributes enable conditional logic and visibility control without JavaScript.**
+
+## Core Principles
+
+- **Declarative Conditions:** Express logic directly in HTML
+- **CSS-Based Performance:** Uses classes for visibility, not DOM manipulation
+- **Real-Time Evaluation:** Conditions re-evaluate on every state change
+- **Layout Stability:** No content shifting or reflow
+
+## Conditional Display
+
+### data-next-show
+
+Show elements when conditions are true.
+
+```html
+
+
+ Cart has items
+
+
+
+ Cart is empty
+
+
+
+
+ Free shipping unlocked!
+
+
+
+ Bulk discount applied
+
+
+
+
+ Eligible for express checkout
+
+
+
+
+ Premium package selected
+
+```
+
+### data-next-hide
+
+Hide elements when conditions are true (inverse of show).
+
+```html
+
+
+
+
+
+
+
+
+ Checkout available
+
+```
+
+## Profile Conditionals
+
+Show/hide content based on active customer profiles.
+
+### data-next-show-if-profile
+
+```html
+
+
+```
+
+### Race Conditions
+
+Conditions are evaluated after data loads:
+
+```html
+
+
+ Ready to checkout
+
+```
+
+### Dynamic Updates
+
+Conditions re-evaluate when data changes:
+
+```javascript
+// Changing cart will update all conditions
+await next.addItem({ packageId: 123 });
+// All data-next-show/hide automatically update
+```
+
+## Related Documentation
+
+- [Display Attributes](/docs/data-attributes/display/) - Showing dynamic data
+- [Action Attributes](/docs/data-attributes/actions/) - Interactive elements
+- [CSS Classes](/docs/reference/css-classes/) - Styling state classes
+- [Events](/docs/campaign-cart/javascript-api/events/) - Responding to state changes
diff --git a/docs/campaign-cart/data-attributes/url-parameters.md b/docs/campaign-cart/data-attributes/url-parameters.md
new file mode 100644
index 00000000..c38590ee
--- /dev/null
+++ b/docs/campaign-cart/data-attributes/url-parameters.md
@@ -0,0 +1,449 @@
+---
+title: URL Parameters
+description: Control element visibility and behavior using URL query parameters
+sidebar_position: 7
+---
+
+**URL parameters provide a powerful way to control element visibility and behavior based on query string values.**
+
+Parameters are automatically captured when the SDK initializes and persist throughout the user's session, even when navigating between pages. This makes them perfect for feature flags, A/B testing, marketing campaigns, and development/testing scenarios.
+
+## How It Works
+
+The URL parameter system follows this lifecycle:
+
+1. **Parameter Capture** - When the SDK initializes, all URL parameters are automatically captured and stored in sessionStorage
+2. **Session Persistence** - Parameters remain available throughout the user's session, even when navigating to pages without those parameters
+3. **Parameter Override** - If a user visits a new page with different parameter values, the new values override the stored ones
+4. **Conditional Display** - Use `data-next-show` and `data-next-hide` attributes to control element visibility based on parameter values
+
+## Basic Usage
+
+### Hiding Elements
+
+Hide elements when specific URL parameters are present:
+
+```html
+
+
+ As seen on TV section
+
+
+
+
+
00:00:00
+
+
+
+
+ Customer testimonials...
+
+```
+
+### Showing Elements
+
+Show elements only when specific URL parameters match:
+
+```html
+
+
+ Debug mode is enabled
+
+
+
+
+ Simple header without promotional banner
+
+```
+
+## Parameter Syntax
+
+Access URL parameters using the `param.` prefix:
+
+```html
+
+
+ Advanced options
+
+```
+
+The parameter name after `param.` must match the URL query parameter name exactly (case-sensitive).
+
+## Supported Conditions
+
+### Equality Checks
+
+```html
+
+
+ Advanced options
+
+
+
+
+ Dark theme styles
+
+```
+
+### Existence Checks
+
+Check if a parameter exists regardless of its value:
+
+```html
+
+
+```
+
+Access different variants using `?variant=a` or `?variant=b` in the URL.
+
+### Development & Testing
+
+Show debug information or test indicators:
+
+```html
+
+
+
Cart State:
+
+
+
+
+ TEST MODE - Orders will not be processed
+
+```
+
+Use `?debug=true` or `?test=true` to enable development features.
+
+### Marketing Campaigns
+
+Customize content based on campaign parameters:
+
+```html
+
+
+ Summer Sale - 50% Off Everything!
+
+
+
+
+ Regular pricing section
+
+
+ VIP exclusive pricing!
+
+```
+
+Track campaigns with URLs like:
+- `?campaign=summer2024`
+- `?special=vip`
+- `?member=gold`
+
+## Session Persistence
+
+Parameters persist throughout the entire session:
+
+```
+Page 1: ?banner=n&theme=dark
+ → Stores: banner=n, theme=dark
+
+Page 2: ?theme=light
+ → Updates: theme=light
+ → Keeps: banner=n
+
+Page 3: (no parameters)
+ → Uses stored: banner=n, theme=light
+```
+
+### Parameter Priority
+
+When the same parameter appears multiple times:
+
+1. **URL parameters on current page** - Highest priority
+2. **Previously stored session parameters** - Used as fallback
+3. **New values override old values** - Most recent wins
+
+## JavaScript API
+
+Manage URL parameters programmatically without modifying the URL.
+
+### Setting Parameters
+
+```javascript
+// Set a single parameter
+next.setParam('banner', 'n');
+
+// Set multiple parameters at once
+next.setParams({
+ timer: 'n',
+ reviews: 'n'
+});
+```
+
+### Getting Parameters
+
+```javascript
+// Check if parameter exists
+if (next.hasParam('debug')) {
+ // Parameter exists
+}
+
+// Get parameter value
+const debugValue = next.getParam('debug');
+console.log('Debug mode:', debugValue);
+
+// Get all parameters
+const params = next.getAllParams();
+console.log('Current parameters:', params);
+```
+
+### Clearing Parameters
+
+```javascript
+// Clear a specific parameter
+next.clearParam('timer');
+```
+
+### JavaScript API Reference
+
+| Method | Description | Example |
+|--------|-------------|---------|
+| `next.setParam(name, value)` | Set single parameter | `next.setParam('banner', 'n')` |
+| `next.setParams(object)` | Set multiple parameters | `next.setParams({ timer: 'n' })` |
+| `next.hasParam(name)` | Check if parameter exists | `next.hasParam('debug')` |
+| `next.getParam(name)` | Get parameter value | `next.getParam('debug')` |
+| `next.clearParam(name)` | Clear parameter | `next.clearParam('timer')` |
+| `next.getAllParams()` | Get all parameters | `next.getAllParams()` |
+
+## Debugging
+
+### View Current Parameters
+
+Open the browser console and use these commands:
+
+```javascript
+// View all stored parameters (debug method)
+nextDebug.stores.parameter().debug()
+
+// Get all parameters
+const params = next.getAllParams();
+console.log('Current parameters:', params);
+
+// Check specific parameter
+nextDebug.stores.parameter().getParam('seen')
+
+// Check if parameter exists
+nextDebug.stores.parameter().hasParam('timer')
+```
+
+### Common Issues
+
+**Parameters not persisting**
+- Check that sessionStorage is not being cleared
+- Verify parameters are being set correctly
+
+**Wrong values showing**
+- Remember that URL parameters override stored values
+- Check parameter priority order
+
+**Case sensitivity**
+- Parameter names are case-sensitive
+- `param.Test` is NOT the same as `param.test`
+
+**Webflow quote stripping**
+- Webflow may strip quotes from attribute values
+- Both formats work:
+ - `data-next-hide="param.timer == 'n'"` (with quotes)
+ - `data-next-hide="param.timer==n"` (without quotes)
+- The SDK automatically handles both formats
+
+## Complete Examples
+
+### Feature Flag System
+
+```html
+
+
+
+ Special offer popup
+
+
+
+
+
+
00:00:00
+
+
+
+
+ Customer reviews section
+
+
+
+
+
Loading...
+
+
+
+
+ Promotional banner content
+
+
+
+
+ As seen on TV/Media logos
+
+```
+
+### A/B Test Implementation
+
+```html
+
+
+
Limited Time Offer!
+
+
Only 3 items left in stock
+
+
+
+
+
Premium Quality Products
+
+
Free shipping on all orders
+
+
+
+
+
Welcome to Our Store
+
+
+```
+
+## Best Practices
+
+1. **Use descriptive parameter names**
+ - Good: `?hideReviews=y`
+ - Bad: `?hr=y`
+
+2. **Be consistent with values**
+ - Choose a convention: `true`/`false` or `y`/`n`
+ - Use the same convention throughout your site
+
+3. **Document your parameters**
+ - Keep a list of all parameters your site uses
+ - Document what each parameter does
+
+4. **Consider security**
+ - Don't use parameters for sensitive features without validation
+ - Parameters are visible in URLs and can be modified
+
+5. **Test thoroughly**
+ - Test parameter behavior across page navigation
+ - Verify session persistence works as expected
+ - Check both with and without parameters in URL
+
+## Conditional Operators Reference
+
+| Operator | Description | Example |
+|----------|-------------|---------|
+| `==` | Equal to | `param.mode == 'advanced'` |
+| `!=` | Not equal to | `param.theme != 'dark'` |
+| `>` | Greater than | `param.quantity > 5` |
+| `<` | Less than | `param.age < 18` |
+| `param.name` | Exists (truthy) | `param.preview` |
+| `!param.name` | Does not exist | `!param.authenticated` |
+| `&&` | Logical AND | `param.a == 'x' && param.b == 'y'` |
+
+## Related Documentation
+
+- [State Attributes](/data-attributes/state/) - Conditional display logic
+- [Display Attributes](/data-attributes/display/) - Display dynamic data
+- [Configuration Attributes](/data-attributes/configuration/) - Advanced options
diff --git a/docs/campaign-cart/guides/advanced-customization.md b/docs/campaign-cart/guides/advanced-customization.md
new file mode 100644
index 00000000..ade0df21
--- /dev/null
+++ b/docs/campaign-cart/guides/advanced-customization.md
@@ -0,0 +1,625 @@
+# Advanced Customization Examples
+
+Complex scenarios and edge cases with the Next Commerce JS SDK.
+
+## Dynamic Bundle Builder
+
+Build custom bundles with real-time pricing updates:
+
+```html
+
+
+
+
+ Build Your Custom Drone Bundle
+
+
+
+
+
+
+
+
+
+
+
+
+
1. Choose Your Drone
+
+
+
+
+
Drone Pro X Basic
+
Entry-level drone with HD camera
+
+
$599
+
+
+
+
+
+
Drone Pro X Advanced
+
4K camera with gimbal stabilization
+
+
$899
+
+
+
+
+
+
Drone Pro X Ultimate
+
8K camera, obstacle avoidance, 45min flight
+
+
$1299
+
+
+
+
+
+
+
2. Extra Batteries
+
+
+
+
No Extra Batteries
+
Just the one that comes with drone
+
+
$0
+
+
+
+
+
+1 Extra Battery
+
Double your flight time
+
+
$79
+
+
+
+
+
+2 Extra Batteries
+
Triple your flight time
+
+ Save 10%
+
+
+
$149
+
+
+
+
+
+
+
3. Select Accessories
+
+
+
+
+
Carrying Case
+
Professional hard-shell case
+
+
$49
+
+
+
+
+
+
ND Filter Set
+
6 filters for perfect exposure
+
+
$39
+
+
+
+
+
+
Extra Propellers
+
2 complete sets
+
+
$29
+
+
+
+
+
+
Landing Pad
+
Professional takeoff/landing surface
+
+
$19
+
+
+
+
+
+
+
4. Protection Plan
+
+
+
+
No Protection
+
Standard manufacturer warranty only
+
+
$0
+
+
+
+
+
2-Year Protection
+
Covers accidents and defects
+
+
$99
+
+
+
+
+
3-Year Protection + Care
+
Full coverage + annual maintenance
+
+
$179
+
+
+
+
+
+
+
+
Your Bundle
+
+
+
+
+ Drone:
+ $0
+
+
+
+ Batteries:
+ $0
+
+
+
+ Carrying Case: $49
+
+
+
+ ND Filter Set: $39
+
+
+
+ Extra Propellers: $29
+
+
+
+ Landing Pad: $19
+
+
+
+ Protection:
+ $0
+
+
+
+
+
+
+
+ Total: $0
+
+
+
+
+ You're saving $0!
+ That's 0% off retail.
+
+
+
+
+
Bundle Discounts
+
+ 3+ items: 5% off
+ ✓ Active
+
+
+ 5+ items: 10% off
+ ✓ Active
+
+
+ $1500+: Extra 5% off
+ ✓ Active
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## Multi-Currency Support
+
+Handle different currencies and regional pricing:
+
+```html
+
+