Scalable list-based personalization
This recipe describes how to enable content authors to configure personalized lists that are based on a combination of what they know about their site's visitors and content.
About this recipe#
Use case#
- A content author can define personalization rules that determine which entries in a reference list are displayed and the order the entries are displayed.
- An entry may be used in multiple reference lists, but the personalization rules are applied to the list of entries, rather than the entries themselves.
Real-world scenario#
- Content authors manage website content and personalization in Contentful.
- Uniform enables content authors to configure personalization in Contentful.
- The website is built using Next.js.
Location detail pages play a large role on your website. Rather than being limited to a specific section of the site, locations are available throughout. Your content authors create curated lists of locations in Contentful.
They want to add personalization to these curated lists. However, the personalization rules that apply to a location depend on the list, not the location.
Example
The headquarters location may always be displayed on a list of locations in the "about us" section of the site, but when that same location is included in a location list in the "training" section, it only need to be displayed if the visitor is located in the same country as the headquarters.
Setup#
Prerequisites#
This recipe assumes you have the following:
- Your Contentful space has the Uniform app installed.
- Your Next.js application already has personalization activated.
- Your Next.js application uses the page router and TypeScript.
Technically neither of these is a requirement for the approach described in this recipe, but the instructions are written for an app that uses this configuration.
- Your Next.js application uses client-side personalization.
This recipe will work with edge-side personalization, but in order to keep the instructions as simple as possible, these instructions assume client-side personalization is used.
Contentful setup#
Create content type: Personalization Rule#
A personalization rule is an instruction that controls how personalization operates. Just like rules in the real world, a personalization rule describes two things:
What does this describe? | How this will be implemented in this solution? | |
---|---|---|
Criteria | What needs to be true in order for the rule to take effect. | This solution involves two criteria: visitor classification and enrichment tags assigned to the location in the list. For example, the personalization rule will take effect if the visitor is interested in a certain topic and the location is tagged with that same topic. |
Action | What happens when the condition is true. | This solution supports two actions for when the criteria is true: the location will be boosted to the top of the list, or the location will be removed from the list. |
The following steps describe how to create a content type that allows a content author to describe personalization rules.
- In Contentful, create the following content type:
Name Personalization Rule
Api Identifier personalizationRule
- Add the following field:
Property Value Notes Field type Short text Name Name
Field ID name
This field represents the Entry title Checked Required field Checked About this step
This is a human-readable description of the personalization.
- Add the following field:
Property Value Notes Field type Short text Name Action
Field ID Action
Required field Checked Accept only specified values Checked boost
andhide
Appearance Dropdown About this step
This field allows the content author to control the action for the personalization rule. This action is applied to the locations in the list when the criteria (not yet configured) is met.
- Save the content type.
- Open the Uniform app configuration page.
About this step
You get to the Uniform by by navigating to Apps > Installed apps > Uniform > Configure.
- Enable enrichment taggings on the content type.
- Enable personalization criteria on the content type.
Be sure to click the Save button
- Return to the content type.
- Rename the following fields:
Current name New name Notes Enrichment Tags Content Criteria
This field represents part of the personalization rule's criteria. It allows content authors to specify the enrichment tags that must be assigned to the location in order for the personalization rule to take effect. Personalization Criteria Visitor Criteria
This field represents part of the personalization rule's criteria. It allows content authors to specify the classification dimensions must be true of the visitor's session in order for the personalization rule to take effect. - Add the following field:
Property Value Notes Field type Short text Name Content Criteria Match Type
Field ID contentCriteriaMatchType
Accept only specified values Checked all
andany
Appearance Radio About this step
This field represents part of the personalization rule's criteria. The field
Content Criteria
allows the content author to select multiple enrichment tags. This field allows the content author to specify specify how many of the selected enrichment tags must be set on the content in order for the rule to take effect:all
means every one of the selected tags must be set, whileany
means just one of the selected tags must be set (any
). - Change the order of the fields to the following:
Position Field name 1 Name 2 Action 3 Visitor Criteria 4 Content Criteria 5 Content Criteria Match Type - Save the content type.
Update content type: Location#
In this example, a content type already exists that represents a location. Enrichment tagging has already been enabled on the content type, so no changes are needed.
Update content type: Curated Location List#
In this example, a content type already exists that represents a location list. You need to add the ability for content authors to assign personalization rules so they can control personalization.
- Open the content type Curated Location List.
- Add the following field:
Property Value Notes Field type Reference Name Personalization Rules
Field ID personalizationRules
Type Many references Required field Checked Accept only specified entry type Checked Personalization Rule Appearance Dropdown About this step
This field allows the content author select the personalization rules that apply to the entries in the field Locations.
- Change the order of the fields to the following:
Position Field name 1 Title 2 Personalization Rules 3 Locations - Save the content type.
Update Next.js application#
You have given content authors the ability to configure personalization. Now you need to update the Next.js application in order to make that configuration available to the code responsible for displaying location lists.
- Add the following npm packages:
npm
npm i @uniformdev-collab/rule-based-personalization \ @uniformdev-collab/rule-based-personalization-contentful \ @uniformdev-collab/rule-based-personalization-react \ @uniformdev-collab/rule-based-personalization-react-contentful - In your
_app.tsx
file, add the following before the default component is defined:./src/pages/_app.tsx
import { ContentfulPzConfigLookupConfig, ContentfulPzRuleLookupConfig, } from "@uniformdev-collab/rule-based-personalization-contentful"; /** * Define how Uniform should handle the personalization * entries that have personalized lists on them. */ const contentfulPzConfigs: ContentfulPzConfigLookupConfig = { /** * There is no default configuration, which means that * a content type must be specifically configured in * the 'elements' section in order for Uniform to be * able to personalize a list on an entry. */ defaultElement: undefined, elements: { /** * The settings below only apply to entries with * the content type 'curatedLocationList'. */ curatedLocationList: { contentEntriesFieldId: "locations", pzRulesFieldId: "personalizationRules", }, }, }; /** * Define how Uniform should handle the entries that represent * the personalization rules that control personalized lists. */ const contentfulPzRuleConfigs: ContentfulPzRuleLookupConfig = { /** * These settings are used for entries that represent * personalization rules. These are the default settings. * The 'elements' section can be used to define settings * that apply to specific content types. */ defaultElement: { /** * Entry field that represents the rule name. */ nameFieldId: "name", /** * Entry field that represents the rule action. */ actionFieldId: "action", /** * Entry field that represent the content criteria * match type (i.e. 'all' or 'any'). */ contentCriteriaMatchTypeFieldId: "contentCriteriaMatchType", }, /** * There are settings that only apply to a specific content type. */ elements: {}, }; - Add the following code:
./src/pages/_app.tsx
import { RuleBasedPersonalization, } from "@uniformdev-collab/rule-based-personalization-react"; ... <UniformContext context={...}> <RuleBasedPersonalization context={clientContext} pzConfigs={contentfulPzConfigs} pzRuleConfigs={contentfulPzRuleConfigs} > ... </RuleBasedPersonalization> </UniformContext> ... - In the page that has the component that displays the location list, add the following code:import { Entry } from "contentful"; import { useEffect, useState } from "react"; import { useUniformContext, } from "@uniformdev/context-react"; import { useContentfulRuleBasedPz, } from "@uniformdev-collab/rule-based-personalization-react-contentful"; ... export default function HomePage(props: HomePageProps) { const { context } = useUniformContext(); const { doPersonalize } = useContentfulRuleBasedPz(); const [locations, setLocations] = useState<Entry>(); /** * This example assumes the Contentful entry is provided * in props. This entry should represent the curated * location list. */ const { entry } = props; /** * On mount, run personalization and add event listeners * on the tracker so personalization runs when visitor * dimensions change. */ useEffect(() => { personalize(); context.events.on("scoresUpdated", personalize); return () => { context.events.off("scoresUpdated", personalize); }; }, []); function personalize() { if (entry) { const { personalized } = doPersonalize(entry); /** * This example assumes */ setLocations(personalized); } } ...
Use the solution#
The video at the top of this page demonstrates how the solution is used.
- Create a new entry using the content type Curated Location List.
- Create new entries using the content type Personalization Rule.
- Assign the personalization rules to the field Personalization Rules.
- Publish the entries.
- Test the personalization.