Migrating to Enable Experiments

A guide for Ninetailed users whose applications support only personalizations and want to upgrade to create and serve experiments.
This guide is for Ninetailed users who are using an older version of the Contentful Ninetailed integration. New Ninetailed users and connections should configure new Contentful connections to use the "Advanced Model" that supports both personalization and experimentation.


Prior versions of:
  1. 1.
    the content model that Ninetailed installed in Contentful, and
  2. 2.
    the pre-built components in the React (and Next.js) SDKs
allowed users to create and serve personalizations. Ninetailed has expanded both the Contentful content model and the SDKs to both to additionally support creating and serving experiments. This guide is for Ninetailed users whose applications support only personalizations to upgrade to also be able to create and serve experiments.


  1. 1.
    Have an existing connection to a Contentful space environment configured from a Ninetailed dashboard
  2. 2.
    Have at least one free content type in the Contentful space environment
  3. 3.
    Have a copy of your production Contentful environment to perform these steps in isolation from your production application. Consult Contentful's Environments and environment aliases best practices documentation for more information.


1. Upgrade your Ninetailed SDK dependency to at least the 2.x version. We recommend using the latest published version:
npm install @ninetailed/[email protected]
Or, if using the Next.js SDK:
@ninetailed/[email protected]
2. Enable the Advanced Model in the connection to your non-production Contetnful environment from with the Ninetailed dashboard by clicking "Edit" in the top right and enabling the "Advanced Model" toggle. Click "Save" to finalize changes. Doing so will automatically:
  • Create a new content type "Ninetailed Experience" (nt_experience), and
  • Create a new field on each experiences-enabled content type (nt_experiences)
  • Disable the nt_variants and nt_audience fields from being edited on content types that were previously personalizable.
This changes your content model such that baseline entries of personalizable content types now reference Ninetailed Experience entries instead of directly referencing an audience and its variants. Ninetailed Experiences entries now take on the responsibility of referencing an audience and variants. Ninetailed Experiences can be either personalizations or experiments, which are distinguished by the read-only nt_type field.
3. Provide all experiments to the <NinetailedProvider>. This requires that you fetch all entries of type nt_experience whose nt_type field is equal to nt_experiment. Provide the array of returned entry objects as the value to the experiments prop. Example using Next.js:
// utils/api.js
import { createClient } from 'contentful';
const contentfulClient = createClient({
space: process.env.CONTENTFUL_SPACE_ID ?? '',
accessToken: process.env.CONTENTFUL_TOKEN ?? '',
environment: process.env.CONTENTFUL_ENVIRONMENT ?? 'master',
export async function getExperiments() {
const query = {
content_type: 'nt_experience',
'fields.nt_type': 'nt_experiment',
const client = getClient(false);
const entries = await contentfulClient.getEntries(query);
return experiments = entries.items;
// pages/[[...slug]].jsx
import { GetStaticProps } from 'next';
import { getExperiments } from '@/utils/api'
export const getStaticProps = async ({ params, preview }) => {
const page = await ...
const experiments = await getExperiments(),
return {
props: { page, ninetailed: { experiments } },
// pages/_app.jsx
import {
} from '@ninetailed/experience.js-next';
const myApp = ({ Component, pageProps }) => {
return (
clientId={process.env.NEXT_PUBLIC_NINETAILED_CLIENT_ID ?? ''}
environment={process.env.NEXT_PUBLIC_NINETAILED_ENVIRONMENT ?? 'main'}
experiments={pageProps.ninetailed?.experiments || []}
<Component {...pageProps} />
export default myApp;
4. Replace the <Personalize> component provided by the React SDK with the <Experience> component. Pass the Ninetailed Experiences that the entry is referencing as the experiences prop, rather than the formerly attached variants .
// Old
import { Personalize } from '@ninetailed/experience.js-react';
return (
// New
import { Experience } from '@ninetailed/experience.js-react';
return (
5. 🎉 Bask in the glory of being able to create experiments from within your CMS! Test out creating experimentations and when ready, perform these changes to de deployed in your production application.