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:
ID | Name | Type | Values | Notes |
---|---|---|---|---|
uids | UIDs | set | Anonymous visitor ID | |
email | text | Strong ID | ||
skin_shade | Skin Shade | set | Very Light, Light, Medium, Medium Dark, Dark | User preference |
skin_tone | Skin Tone | set | Pink, Tan, Olive, Brown, Black | User preference |
undertone | Undertone | text | User preference | |
favorite_sport | Favorite Sport | set | Football, Basketball, Baseball, Hockey | User 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.
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.
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.
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.
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.
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.
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
);