Skip to main content

Personalizing on Kontent Data

Optimize Deprecation

Uniform Optimize has been deprecated and replaced by Context, a more powerful and flexible personalization solution. Optimize is not being discontinued at this time, but it will not receive updates or new features.

We do not recommend starting a new project with Optimize. If you have an existing project that uses Optimize, you can upgrade your project to Context at no cost using our upgrade guide. If you have any issues with this process you can contact our team.

Once you have installed the Uniform Optimize plugin for Kontent, the next step is to get the Kontent content into your application and start personalizing it.

Fetch data from Kontent

The file below expects the Kontent JS SDK to be already installed. It returns the Kontent Delivery client so it can be used to Query data.

import { ContentItem, DeliveryClient, Elements, IContentItem, TypeResolver } from '@kentico/kontent-delivery';

// PersonalizedHeroItem is a component with a reference field that holds
// HeroItem components as personalization variations.
// HeroItem contains the Uniform Intent Tag for intent matching purposes.
// Data setup in Kontent CMS
// PageItem
// - PersonalizedHeroItem
// -- HeroItem (no intent tag)
// -- HeroItem (with Intent Tag)
// -- HeroItem (with Intent Tag)
// -- ...
// The <presonalize /> component delivered by the Uniform SDK choses
// which HeroItem to show based on the Intent scoring given by the Signals.
// More info:
// And more:

export type ComponentType = PersonalizedHeroItem | HeroItem;

export class PageItem extends ContentItem {
public page_components: Elements.LinkedItemsElement<ComponentType>;
public title: Elements.TextElement;
public slug: Elements.UrlSlugElement;

export class PersonalizedHeroItem extends ContentItem {
public unfrmoptp13nlist: Elements.LinkedItemsElement<IContentItem>;

export class HeroItem extends ContentItem {
public title: Elements.TextElement;
public description: Elements.RichTextElement;
public image: Elements.AssetsElement;
public intent_tags: Elements.CustomElement;

export const deliveryClient = new DeliveryClient({
projectId: process.env.KONTENT_PROJECT_ID, // Your Kontent Project ID
typeResolvers: [
new TypeResolver('page', () => new PageItem()),
new TypeResolver('personalized_hero_banner', () => new PersonalizedHeroItem()),
new TypeResolver('hero_banner', () => new HeroItem()),

The following piece of code loads a page by slug. Beware this is a highly simplified version of this code.

import { deliveryClient, PageItem } from '../lib/api';

export const getPageBySlug = async (slug: string) => {
const page = await deliveryClient.item<PageItem>(slug).depthParameter(3).toPromise();
const components = page.item.page_components.value;

return {
props: {
title: slug,
components: components,

Use Kontent Data With the Personalize Component

The variations field contains references to personalizable content entries. The <Personalize /> component needs variants to be mapped in a specific way. See the HeroData type below. The result can be passed to the variations field.

import { Personalize } from '@uniformdev/optimize-tracker-react';
import { IntentTags } from '@uniformdev/optimize-common';
import { Hero } from './Hero';

enum ComponentType {
Hero = 'hero',
PersonalizedHero = 'personalized-hero',

type HeroData = {
type: ComponentType.Hero;
title: string;
description: string;
image: string;

// Note the 'intentTag' key.
// This is needed for the <Personalize /> component to understand how to personalize.
intentTag: IntentTags | undefined | null;

type PersonalizedHeroData = {
type: ComponentType.PersonalizedHero;
heros: HeroData[];

export const PersonalizedHero = ({ item }: { item: PersonalizedHeroData }) => {
return (
loadingMode={PersonalizedHeroLoading} // specifiy a component for a potential loading state

Note that the intentTag field comes back as a serialized string from the Kontent CMS. Make sure to JSON.parse it.

export const convertIntents = (IntentTagValue: Elements.CustomElement) => {
return JSON.parse(IntentTagValue.value);