dot CMS

How to use dotCMS Experiments in a Headless App

dotCMS

Share this article on:

A/B testing has become essential for modern web applications, helping teams optimize user experience and increase conversion rates through data-driven decisions. dotCMS provides a powerful experiments feature that integrates seamlessly with headless applications through the @dotcms/experiments library.

To demonstrate what we'll be building, watch how experiments work in a real dotCMS headless application:

IMAGE VARIANT A

IMAGE VARIANT B

The dotCMS experiments library enables seamless A/B testing where:

  • Users are automatically directed to different variants of your pages

  • The experience remains consistent throughout their session

  • All interactions are tracked automatically for analysis

In this guide, we'll walk through how to implement this functionality in your own headless application.

Prerequisites

Before starting this integration, ensure you have:

  • A running dotCMS instance with Analytics and Experiments properly configured

  • An Analytics API Key (contact your dotCMS administrator if you don't have one)

  • A headless application (React/Next.js)

Solution Introduction

dotCMS's @dotcms/experiments library simplifies A/B testing in headless applications by providing a Higher-Order Component approach. This design choice is particularly powerful because it allows the experiments functionality to wrap around your existing components without requiring significant changes to your application's structure. The library handles all the complex aspects of A/B testing, from user assignment to analytics tracking, while maintaining the performance and flexibility that headless architectures are known for.

Step-by-Step Guide

1. Understanding the Example Project

Let's examine our official example that demonstrates how to build a headless application using Next.js integrated with dotCMS. This example showcases the best practices for implementing experiments in a real-world headless architecture:

# Clone the dotCMS repository 
git clone https://github.com/dotCMS/core.git 
cd core/examples/nextjs 

# Install dependencies 
npm install 

# Start the development 
server npm run dev

This example provides a complete implementation that you can use as a reference. The most important file for our experiments integration is located at /src/components/my-page.js. This file contains the pre-configured setup for experiments and demonstrates how to integrate them with dotCMS, which will be discussed below.

2.  Setting Up the Integration

The integration process begins with installing the experiments library:

npm install @dotcms/experiments

Next, you'll need to set up your environment variables. Create an .env.local file in the root of your project and add the following variables:

# .env.local
NEXT_PUBLIC_EXPERIMENTS_API_KEY=your-api-key-here
NEXT_PUBLIC_DOTCMS_HOST=https://your-dotcms-instance.com
NEXT_PUBLIC_EXPERIMENTS_DEBUG=true  # Optional, set to true for detailed logging

Once installed, navigate to your main page component. In our example, this is the aforementioned /src/components/my-page.js. Here you'll find the experiments configuration already set up:

const experimentConfig = { 
apiKey: process.env.NEXT_PUBLIC_EXPERIMENTS_API_KEY, 
server: process.env.NEXT_PUBLIC_DOTCMS_HOST,
debug: process.env.NEXT_PUBLIC_EXPERIMENTS_DEBUG
};

These environment variables are crucial for the experiments functionality:

  • NEXT_PUBLIC_EXPERIMENTS_API_KEY: Your Analytics API key for authentication

  • NEXT_PUBLIC_DOTCMS_HOST: The URL of your dotCMS instance

  • NEXT_PUBLIC_EXPERIMENTS_DEBUG: Optional flag to enable detailed logging

Remember that the .env.local file should never be committed to your repository as it contains sensitive information. Make sure it's included in your .gitignore file!

3. Implementing the HOC Pattern

The core of the integration lies in how we wrap our layout component with the experiments functionality:

import { withExperiments } from "@dotcms/experiments";
import { useRouter } from 'next/router';

const experimentConfig = { 
apiKey: process.env.NEXT_PUBLIC_EXPERIMENTS_API_KEY,
server: process.env.NEXT_PUBLIC_DOTCMS_HOST, 
debug: process.env.NEXT_PUBLIC_EXPERIMENTS_DEBUG 
};
function MyPage({ pageAsset, nav }) {
  const { replace } = useRouter();
  
  // Conditional wrapping based on API key presence
  const DotLayoutComponent = experimentConfig?.apiKey
    ? withExperiments(DotcmsLayout, {
        ...experimentConfig,
        redirectFn: replace, // Provide navigation function
      })
    : DotcmsLayout;
...

....
  return (
    <DotLayoutComponent>
      <Component {...pageProps} />
    </DotLayoutComponent>
  );
}

Let's break down what's happening here:

  1. Configuration Setup: The experimentConfig object contains essential information:

    • apiKey: Authenticates requests to dotCMS Analytics

    • server: Specifies your dotCMS instance URL

  2. Conditional Wrapping: We only apply the experiments wrapper when an API key is present. This approach:

    • Enables easy development without experiments

    • Prevents unnecessary API calls in development

    • Allows graceful fallback if configuration is missing

  3. Navigation Integration: The redirectFn property receives Next.js's router replace function, allowing the experiments library to handle redirects seamlessly when users need to be shown different variants.

4. Running and Testing Your Implementation

After setting up your environment variables and implementing the HOC, you can start your development server:

npm run dev

Your application will now start with experiments enabled. You can verify the integration is working by:

  • Checking your browser's console for experiment-related logs (if debug mode, mentioned above, is enabled)

  • Visiting pages with active experiments to see variant assignments

  • Monitoring your dotCMS Experiment dashboard for incoming pageview data

How It Works Behind the Scenes

When a user visits your application, the experiments integration performs several important tasks:

  1. User Assignment The library first checks if the user has been assigned to any experiment variants. This check happens automatically and uses browser storage to maintain consistency across sessions.

  2. Variant Management If the user needs to see a specific variant, the library handles this through the provided redirectFn. This ensures users consistently see the same variant throughout their session, which is crucial for gathering reliable test data.

  3. Analytics Integration Every pageview is automatically tracked and sent to dotCMS Analytics, providing you with data about how different variants are performing.

Key Benefits

  • Seamless Integration: The HOC pattern allows for non-invasive integration with existing applications

  • Performance Optimized: Conditional wrapping ensures experiments only run when needed

  • Automatic Handling: User assignment and tracking happen without manual intervention

Flexible Implementation: Works with any React-based application, with special optimization for Next.js

Conclusion

The @dotcms/experiments library provides a sophisticated yet straightforward way to implement A/B testing in headless applications. By using the HOC pattern and handling complex operations automatically, it allows developers to focus on creating and testing content variants rather than worrying about the implementation details of A/B testing.

Additional Resources