Mini-Cart Test
This example demonstrates how to test showing or hiding a specific element (like a free shipping message) in your mini cart. Visitors only enter the test when they interact with the cart.
What We're Testing
Control: Standard mini cart without promotional message
Variant: Mini cart with free shipping progress bar
Step 1: Create Your Test in Shoplift
Navigate to Tests → Create New Test
Select "JavaScript API" as the test type
Choose Manual trigger (only assigns users who open cart)
Create your hypothesis and copy the ID
Step 2: Add HTML Structure
Add the test element to your mini cart, hidden by default:
<!-- In your mini cart template -->
<div class="mini-cart">
<div class="cart-header">
<h3>Your Cart</h3>
<button class="close-cart">×</button>
</div>
<!-- Free shipping element - hidden by default -->
<div class="free-shipping-progress" style="display: none; opacity: 0;">
<div class="shipping-message">
<span class="shipping-icon">🚚</span>
<span class="shipping-text">You're $<span class="amount-remaining">50</span> away from free shipping!</span>
</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 0%"></div>
</div>
</div>
<div class="cart-items">
<!-- Cart items here -->
</div>
<div class="cart-footer">
<!-- Checkout button etc -->
</div>
</div>
Step 3: Add CSS for Smooth Transitions
/* Prevent flicker with transitions */
.free-shipping-progress {
transition: opacity 0.3s ease;
padding: 15px;
background: #f0f8ff;
border-radius: 8px;
margin: 10px;
}
.free-shipping-progress.show {
display: block !important;
opacity: 1 !important;
}
.shipping-message {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 10px;
font-size: 14px;
}
.progress-bar {
width: 100%;
height: 8px;
background: #e0e0e0;
border-radius: 4px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #4CAF50, #45a049);
transition: width 0.3s ease;
}
Step 4: Implement the Test Logic
// Mini Cart Free Shipping Test
(function() {
// Configuration
const HYPOTHESIS_ID = 'your-hypothesis-id-here'; // Replace with your ID
const FREE_SHIPPING_THRESHOLD = 75; // Free shipping at $75
// Cache the test result
let variantAssignment = null;
let cartTotal = 0;
// Initialize test when cart is opened
async function initCartTest() {
// Only check once per session
if (variantAssignment !== null) {
applyTestResult();
return;
}
// Check if Shoplift is available
if (!window.shoplift) {
console.warn('Shoplift not available, hiding promotional element');
variantAssignment = false;
return;
}
try {
// This triggers test assignment on first cart open
variantAssignment = await window.shoplift.isHypothesisActive(HYPOTHESIS_ID);
console.log('Mini cart test assigned:', variantAssignment ? 'variant' : 'control');
// Apply the test result
applyTestResult();
} catch (error) {
console.error('Mini cart test failed:', error);
variantAssignment = false; // Default to control (hide element)
}
}
// Apply test result to UI
function applyTestResult() {
const shippingElement = document.querySelector('.free-shipping-progress');
if (!shippingElement) return;
if (variantAssignment) {
// Show free shipping progress (variant)
updateShippingProgress();
// Add show class with slight delay to ensure smooth transition
setTimeout(() => {
shippingElement.classList.add('show');
}, 10);
// Track interaction if analytics exists
if (window.analytics) {
window.analytics.track('Free Shipping Bar Viewed', {
test_id: 'mini-cart-shipping',
variant: 'shown'
});
}
} else {
// Hide free shipping progress (control)
shippingElement.classList.remove('show');
// After transition, hide completely
setTimeout(() => {
if (!variantAssignment) {
shippingElement.style.display = 'none';
}
}, 300);
}
}
// Update shipping progress bar
function updateShippingProgress() {
const shippingElement = document.querySelector('.free-shipping-progress');
if (!shippingElement || !variantAssignment) return;
// Get current cart total (you'd get this from your cart data)
fetchCartTotal().then(total => {
cartTotal = total;
const remaining = Math.max(0, FREE_SHIPPING_THRESHOLD - cartTotal);
const progress = Math.min(100, (cartTotal / FREE_SHIPPING_THRESHOLD) * 100);
// Update text
const textElement = shippingElement.querySelector('.shipping-text');
if (remaining > 0) {
textElement.innerHTML = `You're $${remaining.toFixed(2)} away from free shipping!`;
} else {
textElement.innerHTML = `🎉 You've qualified for free shipping!`;
}
// Update progress bar
const progressFill = shippingElement.querySelector('.progress-fill');
if (progressFill) {
progressFill.style.width = `${progress}%`;
}
// Make sure element is visible
shippingElement.style.display = 'block';
});
}
// Fetch cart total from Shopify
async function fetchCartTotal() {
try {
const response = await fetch('/cart.js');
const cart = await response.json();
return cart.total_price / 100; // Convert from cents
} catch (error) {
console.error('Failed to fetch cart:', error);
return 0;
}
}
// Set up event listeners
function setupEventListeners() {
// Cart open triggers
const cartTriggers = document.querySelectorAll('.cart-icon, [data-cart-open], a[href="/cart"]');
cartTriggers.forEach(trigger => {
trigger.addEventListener('click', async (e) => {
// Prevent default if it's a link
if (trigger.tagName === 'A') {
e.preventDefault();
}
// Initialize test on first interaction
await initCartTest();
// Open your cart (implement your cart open logic here)
openCart();
});
});
// Listen for cart updates
document.addEventListener('cart:updated', () => {
if (variantAssignment) {
updateShippingProgress();
}
});
// Also check if cart is already open on page load
if (document.querySelector('.mini-cart.active')) {
initCartTest();
}
}
// Your existing cart open function
function openCart() {
// Your cart opening logic here
const cart = document.querySelector('.mini-cart');
if (cart) {
cart.classList.add('active');
}
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', setupEventListeners);
} else {
setupEventListeners();
}
})();
Step 5: Test Your Implementation
1. Force the Variant
https://yourstore.com/?slVariant=your-hypothesis-id
Open the cart - you should see the free shipping message.
2. Test Control
Open in incognito without URL parameters - the message should be hidden.
3. Debug in Console
// Check if test is working
console.log(window.shoplift);
// Manually check assignment
await window.shoplift.isHypothesisActive('your-hypothesis-id');
// Check visitor data
window.shoplift.getVisitorData();
Last updated
Was this helpful?