Contentstack

Contentstack is a composable foundation for driving best-in-class personalized experiences. Contentstack provides an API-first CMS platform to drive the delivery of the best content to everywhere it needs to be.

Integrating Contentstack and Lytics allows you to connect content from your CMS to:

  • Power and customize Lytics Context Layers based on your Contenstack taxonomy. This connection helps to drive affinity calculations and power personalized content or product recommendations that combine user activity data and metadata from your Contentstack Stack.
  • Leverage Lytics profiles to power real-time experiences in Lytics profile fields as Personalize attributes in Contentstack Personalize. Profile schema and fields are synced automatically to Contentstack's Personalize Edge API.

Authorization

If you haven't already done so, you'll need to set up a Contentstack account before you begin the process described below.

Once created, you'll add new Authorizations in Lytics for Contentstack by navigating to "Account > Authorizations > Create New" and select Contentstack as the provider.

Contentstack API Key

Syncing your entry metadata to Lytics requires a Contentstack API Key for your desired stack Stack.

  1. Select "Stack API Key".

  2. Add your Contentstack Region, Stack API Key, Delivery Token and Management Token.

  3. Click "Complete".

Contentstack Authtoken

Syncing profiles to Contentstack Personalize requires you to first generate an authtoken from Contentstack. Then, you'll add that authtoken as a new Lytics authorization.

  1. Select Contentstack Authtoken.

  2. Add your authtoken and the region of your Personalize Project.

  3. Click "Complete".

Contentstack Entry Import

Once you've created an Authorization for Contentstack, you'll start a Contentstack "Import Entries" job in Lytics to sync your entries and taxonomy with your Lytics Content Graph.

  1. Navigate to "Data Pipeline > Jobs > Create New" and select Contentstack as the provider.

  2. Select the "Import Entries" job type and then select your content types to import (likely "article", "landing page", not "navigation", etc.). You can select multiple content types to import their entries.

  3. Select Keep Updated to continuously import the entries for selected content types.

  4. You can also provide the domain (optional) on which you are serving content and have the JavaScript Tag installed.

  5. Select the Taxonomies you'd like to import. Each taxonomy selected will create a new Context Layer and calculate new scores on profiles for each value in that taxonomy.

  6. Click "Complete".

Enable JavaScript Tag Plugin for Contentstack

📘

See "Manual Installation" below for details on how to manually configure all aspects to the website (tag) based sync with Contentstack.

Once you've imported your Contentstack entries into Lytics, you'll want to enable Lytics' JavaScript Tag to sync profile data with Contentstack's Personalize Edge API.

  1. Navigate to "Account > Settings > JavaScript Tag".

  2. Enter the Base URL for the data center to which you want to send to Contentstack's Personalize Edge API, and your Personalize Project ID.

  3. Click "Save".

Once connected, you'll be able to use any Lytics Audience as Contentstack Audience to help tailor content for different audiences, manage variants, and run A/B tests to enhance engagement and conversions.

Sync Audience Definitions

Export Lytics audience defintions to create the personalize audience in Contentstack by starting the Sync Audience Defintions job.

  1. Navigate to "Data Pipeline > Jobs > Create New" and select Contentstack as the provider.

  2. Select the "Sync Audience Definitions" job type.

  3. Select the authorizations you would like to use.

  4. Select your Contentstack organization.

  5. Select the Personalize project where you would like to send the Lytics audience definitions.

  6. Click "Complete".

Manual Website (Jstag) Configuration

This following explains how to enable and use the Contentstack integrations available in JSTag3. There are two distinct plugins available: Contentstack Sync and Contentstack Push.

Overview

Contentstack Sync vs Contentstack Push

Contentstack Sync

  • Synchronizes audience and flow membership data to Contentstack via cookies
  • Sets browser cookies (cs-lytics-audiences, cs-lytics-flows) that get passed to the edge on each request and leverages "Live Attributes" within Contentstack Personalize
  • Recommended approach due to better performance and lower latency
  • Real-time data availability on every subsequent page request

Contentstack Push

  • Pushes audience and flow data directly to the Contentstack Edge API
  • Makes HTTP requests to update user attributes on Contentstack's servers
  • Higher latency due to API calls

Configuration

Both plugins are disabled by default and must be explicitly enabled in your JSTag configuration or via supported account settings.

Sync Configuration (full configuration options)

window.jstag.config({
  contentstack: {
    entitySync: {
      disabled: false, // Enable the sync plugin
      cookie: "cs-personalize-user-uid", // Main user ID cookie name
      segmentsCookie: "cs-lytics-audiences", // Cookie for audience data
      flowsCookie: "cs-lytics-flows", // Cookie for flow data
      stateCookiesMaxAge: 604800, // Cookie expiration (7 days in seconds)
      cookieDomain: null, // Cookie domain (null = current domain)
      poll: {
        disabled: true, // Disable automatic polling
        initialDelay: 4000, // Initial delay before first poll (ms)
        maxAttempts: 5, // Maximum polling attempts
      },
      cache: {
        disabled: false, // Enable session storage caching
        storage: sessionStorage, // Storage mechanism
        key: "contentstack_personalize", // Cache key name
      },
    },
  },
});

Push Configuration (full configuration options)

window.jstag.config({
  contentstack: {
    entityPush: {
      disabled: false, // Enable the push plugin
      baseUrl: "https://personalize-edge.contentstack.com", // Contentstack API endpoint
      personalizeProjectId: "your-project-id", // Your Contentstack project ID(s)
      audienceAttribute: "lytics_audiences", // Attribute name for audiences
      flowAttribute: "lytics_flows", // Attribute name for flows
      cookie: "cs-personalize-user-uid", // User ID cookie name
      cookieDomain: null, // Cookie domain
      poll: {
        disabled: true, // Disable automatic polling
        initialDelay: 4000, // Initial delay (ms)
        maxAttempts: 5, // Maximum attempts
      },
      cache: {
        disabled: false, // Enable caching
        storage: sessionStorage, // Storage type
        key: "contentstack_personalize", // Cache key
      },
    },
  },
});

Usage Examples

Basic Sync Setup (Recommended)

// Minimal configuration for Contentstack Sync
window.jstag.config({
  contentstack: {
    entitySync: {
      disabled: false,
    },
  },
});

This will:

  • Set a user ID cookie (cs-personalize-user-uid) when entity data is loaded
  • Create audience cookies (cs-lytics-audiences) with pipe-delimited segment data
  • Create flow cookies (cs-lytics-flows) with pipe-delimited flow step data
  • Cookies expire after 7 days and are available on every page request

Basic Push Setup

// Minimal configuration for Contentstack Push
window.jstag.config({
  contentstack: {
    entityPush: {
      disabled: false,
      personalizeProjectId: "your-contentstack-project-id",
    },
  },
});

This will:

  • Send PATCH requests to Contentstack's Edge API when entity data loads
  • Include user ID in request headers
  • Send audience and flow data as JSON attributes

Advanced Configuration with Polling (Advanced use cases only)

// Enable automatic polling for real-time updates
window.jstag.config({
  contentstack: {
    entitySync: {
      disabled: false,
      cookieDomain: ".yourdomain.com", // Set cookies for entire domain
      poll: {
        disabled: false, // Enable polling
        initialDelay: 5000, // Wait 5 seconds before first poll
        maxAttempts: 10, // Poll up to 10 times
      },
    },
  },
});

Multiple Project IDs (Push only)

// Push to multiple Contentstack projects
window.jstag.config({
  contentstack: {
    entityPush: {
      disabled: false,
      personalizeProjectId: ["project-id-1", "project-id-2", "project-id-3"],
    },
  },
});

How Data is Formatted

Both plugins format audience and flow data consistently:

Audience Data Format

  • Input: ["segment1", "segment2", "segment3"]
  • Output: "|segment1|segment2|segment3|"

Flow Data Format

  • Input: {"flow1": "step2", "flow2": "step1"}
  • Output: "|step1|step2|"

The data is:

  1. Deduplicated (removes duplicates)
  2. Sorted alphabetically
  3. Wrapped in pipe delimiters for easy parsing

// Monitor polling status (both plugins)
window.jstag.on("contentstack.entitySync.pollStarted", function() {
  console.log("Polling started");
});

window.jstag.on("contentstack.entitySync.pollStopped", function() {
  console.log("Polling stopped");
});

Troubleshooting

Common Issues

  1. No cookies are set (Sync)

    • Verify disabled: false in configuration
    • Check that entity data contains user ID and segments
    • Ensure no ad blockers are preventing cookie setting
  2. API requests failing (Push)

    • Verify personalizeProjectId is correct
    • Check network tab for CORS or authentication errors
    • Ensure Contentstack endpoint is accessible
  3. Polling not working

    • Confirm poll.disabled: false in configuration
    • Check that initial delay and max attempts are reasonable
    • Verify entity loading is working properly

Debug Mode

// Enable debug logging
window.jstag.config({
  audit: {
    disabled: false, // This enables console logging for troubleshooting
  },
});

Migration Notes

  • Both plugins require entity data to be available before they can function
  • The plugins automatically detect when entity data is loaded and trigger accordingly
  • No manual triggering is required - everything happens automatically after configuration