Skip to main content

Personalization

The Experiences SDK and Profiles SDK may be used together to personalize experiences using profiles and segments. This guide provides a number of example use cases and recommended practices for personalizing experiences.

Pre-requisites

  • Review the intro to the Profiles SDK
  • Define a data model in Profiles > Data Model
  • Define sample segments in Profiles > Segments
  • Create some profiles using the SDK, or by mapping forms using the Profiles Connector

Load and initialize Profiles SDK

To set up any of the personalization use cases described here or develop other experiences that use the Profiles SDK, turn on Enable Personalization using Profiles in Settings > Personalization within the experience editor. This will load and initialize the Profiles SDK, so the functions can be used from JavaScript code within an experience.

Use cases

To get you started with personalied experiences, this section provides example code and templates for a number of common use cases.

Sample data model

The example use cases assume a sample data model with the following fields:

IDNameTypeValuesNotes
uidsUIDssetAnonymous visitor ID
emailEmailtextStrong ID
skin_shadeSkin ShadesetVery Light, Light, Medium, Medium Dark, DarkUser preference
skin_toneSkin TonesetPink, Tan, Olive, Brown, BlackUser preference
undertoneUndertonetextUser preference
favorite_sportFavorite SportsetFootball, Basketball, Baseball, HockeyUser preference

Here is the sample data model in JSON format. This can be copied directly into your account, if you do not already have a data model defined. Reach out to Wyng support if you do not know how to do that:

{
"strong_id": "email",
"ids_priority": [
"email",
"uids"
],
"fields": [
{
"is_key": true,
"status": "active",
"type": "set",
"is_hash_field": false,
"relevance_window": null,
"allow_other_values": true,
"values": [],
"id": "uids",
"is_personal_data": false,
"name": "UIDs",
"retention_window": null
},
{
"is_key": false,
"status": "active",
"type": "set",
"is_hash_field": false,
"relevance_window": null,
"allow_other_values": false,
"values": [
"Very Light",
"Light",
"Medium",
"Medium Dark",
"Dark"
],
"id": "skin_shade",
"is_personal_data": false,
"name": "Skin Shade",
"retention_window": null
},
{
"is_key": false,
"status": "inactive",
"type": "set",
"is_hash_field": false,
"relevance_window": null,
"allow_other_values": false,
"values": [
"Pink",
"Tan",
"Olive",
"Brown",
"Black"
],
"id": "skin_tone",
"is_personal_data": false,
"name": "Skin Tone",
"retention_window": null
},
{
"is_key": false,
"status": "active",
"type": "text",
"is_hash_field": false,
"relevance_window": null,
"allow_other_values": false,
"values": [],
"id": "undertone",
"is_personal_data": false,
"name": "Undertone",
"retention_window": null
},
{
"is_key": true,
"status": "active",
"type": "text",
"is_hash_field": false,
"relevance_window": null,
"allow_other_values": false,
"values": [],
"id": "email",
"is_personal_data": false,
"name": "email",
"retention_window": null
},
{
"is_key": false,
"status": "active",
"type": "set",
"is_hash_field": false,
"relevance_window": null,
"allow_other_values": false,
"values": [
"Football",
"Basketball",
"Baseball",
"Hockey"
],
"id": "favorite_sport",
"is_personal_data": false,
"name": "Favorite Sport",
"retention_window": null
}
]
}

Progressive form

This experience will show and hide form fields based on which attributes are already known about the current visitor. If an attribute is known, the corresponding field will be hidden in the form, so that the user only has to fill in data that is not already known.

info

Experience SDK functions used

Profiles SDK functions used

Sample code

Add this code to Settings > Custom JavaScript in the experience editor:

 // This object maps the profile fields IDs to their 
// corresponding form fields. Modify this to match your
// data model attributes and form field IDs.

const profileFields = {
email: 'email_2699878814220',
skin_shade: 'skin_shade_9297486054716',
skin_tone: 'skin_tone_6450818205917',
undertone: 'undertone_4781332509380',
};

const formFields = Object.values(profileFields);

window.wyng['_WYNG_ID_'].hideFields(formFields);
window.wyng['_WYNG_ID_'].requireFields(formFields);

window.wyng.profiles.getProfile().then(p => {
const fieldsToAskFor = Object.keys(profileFields)
.filter(field => !p.field_list.includes(field))
.map(field => profileFields[field]);
window.wyng['_WYNG_ID_'].revealFields(fieldsToAskFor);
});

Show varying content to users with known and unknown emails

This experience contains multiple sub-pages and will show one sub-page if the current visitor's email is already known in their profile, and show a different sub-page if the email is not yet known. A practical use for this would be to show an email opt-in form on your website to only those visitors whose email address you do not already know.

info

Experience SDK functions used

Profiles SDK functions used

Sample code

Add this code to Settings > Custom JavaScript in the experience editor:

// The profile field ID we are looking for in the profile 
const profileFieldToCheck = 'email';

// The sub-page to show if this field exists in the visitor's profile
const fieldIsKnownPage = 'page_2862183555770';

// The sub-page to show if this field does not exist in the visitor's profile
const fieldIsNotKnownPage = 'page_8693326991244';

window.wyng.profiles.getProfile().then(profile => {
if (profile.field_list.indexOf(profileFieldToCheck) === -1) {
window.wyng['_WYNG_ID_'].setPage(fieldIsNotKnownPage);
} else {
window.wyng['_WYNG_ID_'].setPage(fieldIsKnownPage);
}
}).catch(() => window.wyng['_WYNG_ID_'].setPage(fieldIsNotKnownPage));

Show varying content to users if they are in a certain segment

This experience contains multiple sub-pages and will show one sub-page if the current visitor is in a specific segment, and a different sub-page if the visitor is not in the segment.

info

Experience SDK functions used:

Profiles SDK functions used:

Sample code

Add this code to Settings > Custom JavaScript in the experience editor:

// The segment to check for
const segmentId = '6154a971721d14700095967d';

// The sub-page to show if the visitor is in the segment
const hasSegmentPage = 'page_2862183555770';

// The sub-page to show if the visitor is not in the segment
const doesNotHaveSegmentPage = 'page_8693326991244';

// The sub-page to show if the visitor does not yet have a profile
const profileDoesNotExistPage = doesNotHaveSegmentPage;

window.wyng.profiles.hasSegment(
segmentId,
() => window.wyng['_WYNG_ID_'].setPage(hasSegmentPage),
() => window.wyng['_WYNG_ID_'].setPage(doesNotHaveSegmentPage),
() => window.wyng['_WYNG_ID_'].setPage(profileDoesNotExistPage)
);

Personalize by segment after a user identifies themselves by email

This experience contains a form that collects a visitor's email address, and then uses the email to look up a profile. One sub-page is shown if the user is in a certain segment, and a different sub-page is shown if the user is not in the segment.

info

Experience SDK functions used

Profiles SDK functions used

Sample code

Add this code to Settings > Custom JavaScript in the experience editor:

// The segment to check for
const segmentId = '626b3328249e784750cab233';

// ID of email field in form component
const emailFormField = 'email_address_6820235339147';

// The sub-page to show if the user is in the segment
const hasSegmentPage = 'page_2862183555770';

// The sub-page to show if the user is not in the segment
const doesNotHaveSegmentPage = 'page_9462781714101';

// The sub-page to show if the user does not yet have a profile
const profileDoesNotExistPage = doesNotHaveSegmentPage;

window.wyng['_WYNG_ID_'].addEventListener('form_submit_success', (event) => {
const email = event.fields.find(f => f.name === emailFormField).answer;

window.wyng.profiles.identify({ email });

window.wyng.profiles.hasSegment(
segmentId,
() => window.wyng['_WYNG_ID_'].setPage(hasSegmentPage),
() => window.wyng['_WYNG_ID_'].setPage(doesNotHaveSegmentPage),
() => window.wyng['_WYNG_ID_'].setPage(profileDoesNotExistPage)
);
});

Reveal hidden components based on a visitor's segments

This experience will reveal one of two hidden components based on whether a visitor is or is not in a certain segment.

info

Experience SDK functions used

Profiles SDK functions used

Sample code

Add this code to Settings > Custom JavaScript in the experience editor:

 // The segment to check for
const segmentId = '6154a971721d14700095967d';

// The component name (or id) to hide if visitor is in the segment
const componentToHideWhenMatch = 'text_9182330751973';

// The component name (or id) to hide if visitor is not in the segment
const componentToHideWhenNoMatch = 'text_5032145531053';

// Hide both components initially
window.wyng['_WYNG_ID_'].hideComponents(
[componentToHideWhenMatch, componentToHideWhenNoMatch]
);

function hideInSegmentComponent() {
window.wyng['_WYNG_ID_'].revealComponent(componentToHideWhenNoMatch);
}

function hideNotInSegmentComponent() {
window.wyng['_WYNG_ID_'].revealComponent(componentToHideWhenMatch);
}

window.wyng.profiles.hasSegment(
segmentId,
hideInSegmentComponent,
hideNotInSegmentComponent,
hideNotInSegmentComponent // this function is called if visitor has no profile
);

Authenticate a user to access their private profile data

This experience uses native Email Identity Verification in Wyng to identify a visitor and authenticate them with a one-time password. Once authenticated, a privileged access token is used to access the user's private profile fields, and fill them into a form.

In the form configuration, the IDs of the form fields have been renamed to exactly match the data model field IDs. When using multiple choice or checkbox fields, ensure that the values line up with the allowed values for the corresponding data model attribute.

info

Experience SDK functions used

Profiles SDK functions used

Sample code

Add this code to Settings > Custom JavaScript in the experience editor:

// Data model field with email address
const profileEmailFieldId = 'email';

// Component ID of the Identity Verification form
const componentId = 'sign_up_8872875208687';
let profileFields = {};

function loadPreferenceCenter(event) {
if (event.componentId === componentId) {
window.wyng.profiles.exchangeToken(
event.token,
profileEmailFieldId
).then(() => {
window.wyng.profiles.get().then(fields => {
profileFields = fields;
return new Promise((resolve, reject) => {
setTimeout(resolve, 100);
});
})
.then(() => window.wyng['_WYNG_ID_'].setFields(profileFields));
}).catch(error => console.error(error));
}
}

window.wyng['_WYNG_ID_'].addEventListener(
'form_identity_verification_success',
loadPreferenceCenter
);