Profiles
The Profile System enables dynamic package ID swapping across your entire e-commerce implementation. This powerful feature allows you to maintain multiple pricing tiers, seasonal promotions, and customer-specific offers without duplicating your frontend code.
Overview
Section titled “Overview”The Profile System solves a common e-commerce challenge: how to efficiently manage different product variants (regular price, discounted, bundles) without complex conditional logic throughout your codebase. Instead of hardcoding package IDs, you define mapping profiles that automatically swap packages based on the active profile.
Key Benefits
Section titled “Key Benefits”- Dynamic Pricing: Switch between pricing tiers instantly
- Seasonal Promotions: Activate holiday sales with a single profile change
- A/B Testing: Test different pricing strategies seamlessly
- Membership Tiers: Offer VIP pricing to premium customers
- Bundle Management: Convert single items to multi-packs automatically
How It Works
Section titled “How It Works”Profile Concept
Section titled “Profile Concept”A profile is a named configuration that defines how package IDs should be mapped. When a profile is active, any reference to an original package ID is automatically translated to its mapped counterpart.
// Profile Definition{ id: "black_friday", name: "Black Friday Sale", packageMappings: { 1: 101, // Package 1 → Package 101 (BF variant) 2: 102, // Package 2 → Package 102 (BF variant) 3: 103 // Package 3 → Package 103 (BF variant) }}Mapping Process
Section titled “Mapping Process”- Original State: Your site uses standard package IDs (1, 2, 3, etc.)
- Profile Activation: User or system activates a profile
- Automatic Mapping: All package operations use mapped IDs
- Transparent Integration: Cart, checkout, and display components update automatically
Configuration
Section titled “Configuration”Add profile configuration to your window.nextConfig:
<script>window.nextConfig = { apiKey: 'your-api-key',
// Define your profiles profiles: { // Regular pricing (no mappings needed) "regular": { name: "Regular Pricing", description: "Standard retail prices" },
// Discount profile "sale_20": { name: "20% Off Sale", description: "Limited time 20% discount", packageMappings: { 1: 101, // Regular Product A → Sale Product A 2: 102, // Regular Product B → Sale Product B 3: 103 // Regular Product C → Sale Product C } },
// VIP member profile "vip": { name: "VIP Member Pricing", description: "Exclusive VIP discounts", packageMappings: { 1: 201, // Regular → VIP variant 2: 202, 3: 203 } },
// Bundle profiles "2_pack": { name: "2-Pack Bundle", description: "Buy 2 save more", packageMappings: { 1: 301, // Single → 2-pack 2: 302, 3: 303 } } },
// Optional: Set default profile defaultProfile: "regular"};</script>Activation Methods
Section titled “Activation Methods”1. URL Parameters
Section titled “1. URL Parameters”The simplest way to activate profiles:
// Apply profile (preserves cart)https://example.com/checkout?profile=black_friday
// Force profile (clears cart first)https://example.com/checkout?forceProfile=vip
// Alternative parameter namehttps://example.com/checkout?packageProfile=sale_202. JavaScript API
Section titled “2. JavaScript API”Programmatic control via the next object:
window.nextReady.push(function() { // Apply a profile next.setProfile('black_friday');
// Apply with options next.setProfile('vip', { clearCart: false, // Keep existing cart items preserveQuantities: true // Maintain item quantities });
// Revert to no profile next.revertProfile();
// Check active profile const currentProfile = next.getActiveProfile(); console.log(currentProfile); // "black_friday"
// Get mapped package ID const mappedId = next.getMappedPackageId(1); console.log(mappedId); // 101 (if black_friday is active)
// Get original package ID from mapped const originalId = next.getOriginalPackageId(101); console.log(originalId); // 1
// List all available profiles const profiles = next.listProfiles(); console.log(profiles); // ["regular", "black_friday", "vip"]
// Check if profile exists if (next.hasProfile('black_friday')) { // Profile is configured }
// Get profile information const profileInfo = next.getProfileInfo('black_friday'); console.log(profileInfo.name); // "Black Friday Sale"});3. HTML Data Attributes
Section titled “3. HTML Data Attributes”Profile Switcher Buttons
Section titled “Profile Switcher Buttons”<!-- Simple profile switcher --><button data-next-profile="black_friday"> Apply Black Friday Prices</button>
<!-- With cart clearing --><button data-next-profile="vip" data-next-clear-cart="true"> Switch to VIP Pricing (New Cart)</button>
<!-- With quantity preservation control --><button data-next-profile="3_pack" data-next-preserve-quantities="false"> Convert to 3-Pack Bundle</button>
<!-- With visual states --><button data-next-profile="sale_20" data-next-active-text="Sale Active ✓" data-next-inactive-text="Activate 20% Sale"> Activate 20% Sale</button>Profile Selector Dropdown
Section titled “Profile Selector Dropdown”<!-- Manual dropdown --><select data-next-profile-selector> <option value="">Regular Pricing</option> <option value="black_friday">Black Friday Sale</option> <option value="vip">VIP Member</option> <option value="3_pack">3-Pack Bundle</option></select>
<!-- Auto-populated dropdown --><select data-next-profile-selector data-next-auto-populate="true" data-next-clear-cart="false"></select>Profile-Aware Actions
Section titled “Profile-Aware Actions”<!-- Add to cart with profile override --><button data-next-action="add-to-cart" data-next-package-id="1" data-next-profile="black_friday"> Add with Black Friday Price</button>Conditional Display
Section titled “Conditional Display”<!-- Show only when specific profile is active --><div data-next-show-if-profile="black_friday"> 🎉 Black Friday prices are active! Save up to 40%!</div>
<!-- Display profile information --><p>Current Pricing: <span data-next-display="profile.name">Regular</span></p><p>Profile ID: <span data-next-display="profile.id">none</span></p>Practical Examples
Section titled “Practical Examples”Exit Intent Discount
Section titled “Exit Intent Discount”window.nextReady.push(function() { // In your exit intent handler next.exitIntent({ image: '/images/special-offer.jpg', action: function() { // Apply exit discount profile next.setProfile('exit_10');
// Optionally apply a coupon too next.applyCoupon('SAVE10');
// Show success message alert('10% discount applied to your cart!'); } });});Membership Tier System
Section titled “Membership Tier System”// After user loginfunction applyMembershipPricing(user) { if (user.membership === 'vip_gold') { next.setProfile('vip_gold'); } else if (user.membership === 'vip_silver') { next.setProfile('vip_silver'); } // Regular members use default pricing}
// Check if user qualifies for special pricingwindow.nextReady.push(function() { const user = getCurrentUser(); if (user && user.membership) { applyMembershipPricing(user); }});Time-Based Promotions
Section titled “Time-Based Promotions”// Automatic profile activation based on timefunction checkAndApplyPromotions() { const now = new Date(); const hour = now.getHours();
// Happy hour: 3-6 PM if (hour >= 15 && hour < 18) { next.setProfile('happy_hour'); } // Flash sale: Midnight to 2 AM else if (hour >= 0 && hour < 2) { next.setProfile('flash_sale'); } // Weekend special else if (now.getDay() === 0 || now.getDay() === 6) { next.setProfile('weekend_special'); }}
window.nextReady.push(function() { // Check every hour setInterval(checkAndApplyPromotions, 3600000); checkAndApplyPromotions(); // Initial check});A/B Testing
Section titled “A/B Testing”// A/B test different pricing strategiesfunction initPricingExperiment() { // Get or generate user variant let variant = localStorage.getItem('pricing_variant');
if (!variant) { // Randomly assign variant variant = Math.random() < 0.5 ? 'control' : 'test'; localStorage.setItem('pricing_variant', variant); }
// Apply corresponding profile if (variant === 'test') { next.setProfile('test_pricing');
// Track with analytics next.trackCustomEvent('experiment_variant', { experiment: 'pricing_test', variant: 'test' }); }}
window.nextReady.push(initPricingExperiment);Bundle Size Selector
Section titled “Bundle Size Selector”<!-- Bundle selector UI --><div class="bundle-options"> <h3>Select Bundle Size:</h3>
<label> <input type="radio" name="bundle" value="" checked> <span>Single Item</span> </label>
<label> <input type="radio" name="bundle" value="2_pack"> <span>2-Pack (Save 15%)</span> </label>
<label> <input type="radio" name="bundle" value="3_pack"> <span>3-Pack (Save 25%)</span> </label></div>
<script>window.nextReady.push(function() { document.querySelectorAll('input[name="bundle"]').forEach(radio => { radio.addEventListener('change', function(e) { const profile = e.target.value;
if (profile) { next.setProfile(profile); } else { next.revertProfile(); } }); });});</script>Advanced Features
Section titled “Advanced Features”Profile Events
Section titled “Profile Events”Listen to profile change events:
window.nextReady.push(function() { // Listen for profile changes next.on('profile:applied', function(data) { console.log(`Profile changed to: ${data.profileId}`); console.log(`Items swapped: ${data.itemsSwapped}`);
// Update UI elements updatePricingBadges(); showProfileNotification(data.profileId); });
// Listen for profile revert next.on('profile:reverted', function(data) { console.log(`Profile reverted, restored ${data.itemsRestored} items`); });});Dynamic Profile Registration
Section titled “Dynamic Profile Registration”Register profiles at runtime:
window.nextReady.push(function() { // Register a new profile programmatically next.registerProfile({ id: 'custom_sale', name: 'Custom Sale', description: 'Dynamically created sale', packageMappings: { 1: 501, 2: 502, 3: 503 } });
// Now you can use it next.setProfile('custom_sale');});Combining with Coupons
Section titled “Combining with Coupons”Apply profiles and coupons together:
function applySpecialOffer(offerCode) { switch (offerCode) { case 'BLACKFRIDAY': next.setProfile('black_friday'); next.applyCoupon('BF2024'); break;
case 'VIP_WELCOME': next.setProfile('vip'); next.applyCoupon('WELCOME10'); break;
case 'BUNDLE_DEAL': next.setProfile('3_pack'); // No coupon needed, profile handles discount break; }}Best Practices
Section titled “Best Practices”1. Predefine Profiles
Section titled “1. Predefine Profiles”Configure all profiles at initialization for optimal performance:
window.nextConfig = { profiles: { // Define all profiles upfront regular: { /* ... */ }, sale: { /* ... */ }, vip: { /* ... */ } }};2. Use Meaningful Names
Section titled “2. Use Meaningful Names”Choose descriptive profile IDs and names:
// Good"black_friday_2024": { name: "Black Friday 2024 Sale" }"vip_gold_tier": { name: "VIP Gold Member Pricing" }
// Avoid"profile1": { name: "Sale" }"p2": { name: "Discount" }3. Validate Mappings
Section titled “3. Validate Mappings”Ensure mapped packages exist in your campaign:
function validateProfile(profile) { const campaign = next.getCampaignData();
for (const [original, mapped] of Object.entries(profile.packageMappings)) { const packageExists = campaign.packages.some(p => p.ref_id === mapped); if (!packageExists) { console.warn(`Mapped package ${mapped} not found`); } }}4. Handle Profile Switching Gracefully
Section titled “4. Handle Profile Switching Gracefully”Provide clear feedback when profiles change:
next.on('profile:applied', function(data) { // Show user feedback showNotification(`Switched to ${data.profileName} pricing`);
// Update UI badges document.querySelectorAll('.pricing-badge').forEach(badge => { badge.textContent = data.profileName; });});Troubleshooting
Section titled “Troubleshooting”Profile Not Applying
Section titled “Profile Not Applying”// Debug profile applicationconsole.log('Active profile:', next.getActiveProfile());console.log('Available profiles:', next.listProfiles());
// Check if profile existsif (!next.hasProfile('my_profile')) { console.error('Profile not configured');}
// Verify mappingsconst profile = next.getProfileInfo('my_profile');console.log('Mappings:', profile.packageMappings);Cart Items Not Updating
Section titled “Cart Items Not Updating”// Force cart recalculation after profile changenext.on('profile:applied', function() { // Trigger cart UI update const cartData = next.getCartData(); console.log('Updated cart:', cartData);
// Emit custom event for UI updates window.dispatchEvent(new CustomEvent('cart:profile-updated'));});Related Documentation
Section titled “Related Documentation”- Data Attributes - HTML-based profile controls
- JavaScript API - Programmatic profile management
- Events - Profile-related events