Learn how to run A/B tests with Remark and set up external monitoring
Remark includes built-in A/B testing capabilities that allow you to gradually roll out the chat widget to your customers while maintaining a control group. This enables you to measure the impact of Remark on your key business metrics.
Control Group Data
Read A/B test assignments, lead IDs, and set up external monitoring.
Testing Parameters
Open Remark automatically for testing and campaigns.
Hide Competing Tools
Automatically hide alternative chat solutions during A/B tests.
Rollout Strategy
Best practices for phased rollouts from 10% to 100%.
Remark manages control group assignment automatically on the backend. When a visitor arrives on your site, the backend determines whether they should be in the control group based on your configured rollout percentage.
Remark uses backend control for A/B test assignment to ensure consistent experiences across multiple entry points and devices. Visitors can engage with Remark through various channels:
Initial page load – First visit to your site
Page reloads – Navigating between pages or refreshing
Email follow-ups – Clicking links in conversation notification emails
Mobile transfers – Switching between mobile and desktop devices
Cross-device continuity – Moving from one device to another mid-conversation
If A/B test assignment were determined client-side only, a visitor could see Remark on desktop but not on mobile, or vice versa. Backend control ensures that once assigned to a group, a visitor remains in that group regardless of how they access your site.
Remark dispatches a remark:sdk-initialized event when the SDK has fully loaded and initialized. This is the ideal time to set up external monitoring or analytics.
Copy
window.addEventListener("remark:sdk-initialized", () => { // SDK is fully loaded and ready // Safe to access control group data const isControlGroup = localStorage.getItem("isInRemarkABControlGroup"); console.log("Control group status:", isControlGroup);});
The control group status is stored in localStorage and can be accessed synchronously:
Copy
const isInControlGroup = localStorage.getItem("isInRemarkABControlGroup");if (isInControlGroup === "true") { // User is in the control group (will NOT see Remark) console.log("Control group - Remark hidden");} else if (isInControlGroup === "false") { // User is in the treatment group (will see Remark) console.log("Treatment group - Remark visible");}
The value is stored as a string, not a boolean. Always use === "true" or === "false" for comparisons.
Remark also stores the lead ID (unique visitor identifier) in localStorage. This is useful for correlating Remark’s A/B test data with your own analytics:
Copy
const leadId = localStorage.getItem("remark_lead");if (leadId) { // Use this ID to track the same visitor in your analytics console.log("Remark Lead ID:", leadId);}
This lead ID remains consistent across:
Page reloads and navigation
Multiple sessions on the same device
Cross-device tracking (when visitors return via email links)
Including the lead ID in your external A/B test monitoring allows you to:
Match Remark’s user identification with your analytics
Track individual visitor journeys across the A/B test
Analyze conversion rates at the individual lead level
For A/B testing purposes, you can use the remark_open URL parameter to open the Remark widget automatically when the page loads. This ensures visitors in the treatment group see and interact with Remark.
When running an A/B test between Remark and another chat solution (e.g., HubSpot, Gorgias, Intercom), Remark will automatically hide the competing tool for users in the treatment group.
// Check if localStorage is being set correctlyconsole.log("Control Group Status:", localStorage.getItem("isInRemarkABControlGroup"));console.log("Lead ID:", localStorage.getItem("remark_lead"));// Verify both values are available for external trackingconst abTestData = { isControlGroup: localStorage.getItem("isInRemarkABControlGroup") === "true", leadId: localStorage.getItem("remark_lead")};console.log("A/B Test Data:", abTestData);
let sdkInitialized = false;window.addEventListener("remark:sdk-initialized", () => { sdkInitialized = true; console.log("✓ SDK initialized successfully");});// Check after a few secondssetTimeout(() => { if (!sdkInitialized) { console.error("✗ SDK did not initialize within 5 seconds"); }}, 5000);
Always wait for the remark:sdk-initialized event before accessing control group data or setting up integrations.
Copy
// ✓ Good - wait for SDKwindow.addEventListener("remark:sdk-initialized", () => { const isControlGroup = localStorage.getItem("isInRemarkABControlGroup"); // Use the data...});// ✗ Bad - might run before SDK initializesconst isControlGroup = localStorage.getItem("isInRemarkABControlGroup");
The control group status might not be available immediately on the first page load.
Copy
window.addEventListener("remark:sdk-initialized", () => { const isControlGroup = localStorage.getItem("isInRemarkABControlGroup"); if (isControlGroup === null) { console.warn("Control group status not yet available"); return; } // Proceed with your logic...});