Code examples for client-side template implementations
JavaScript Dynamic Yield server-side integration example
import Mustache from "mustache";
Mustache.tags = ["${", "}"];
const host = "https://api-templates-dev.dynamicyield.com";
const CHOICE_TYPES = {
RECS_DECISION: "RECS_DECISION",
DECISION: "DECISION"
};
const fetchApiTemplate = async (token, extension) => {
const sectionId = DY.section;
const url = `${host}/${sectionId}/${token}.${extension}.template`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.text();
} catch (error) {
console.error("Error in fetchApiTemplate:", error);
throw error;
}
};
const render = (template, data) => {
try {
return Mustache.render(template, data);
} catch (err) {
return template;
}
};
const getTemplateProductData = (slot, templateProductData) => {
const { productData, sku } = slot;
const result = {
slotId: slot.slotId
};
for (const variableName in templateProductData) {
const productFieldName = templateProductData[variableName];
result[variableName] = productFieldName === "sku" ? sku : productData[productFieldName];
}
return result;
};
const transformDataByType = (choice, variation) => {
if (choice.type !== CHOICE_TYPES.RECS_DECISION) {
return {
...variation.payload.data
};
}
const { custom, slots } = variation.payload.data;
return {
...custom,
decisionId: choice.decisionId,
Recommendation: slots.map(slot => getTemplateProductData(slot, custom.TemplateProductData))
};
};
const handleVariation = async (choice, variation) => {
if (!variation.template) {
return null;
}
const { template: { files, token } } = variation;
const transformedData = transformDataByType(choice, variation);
const contents = {};
const extensions = ["html", "js", "css"];
for (const extension of extensions) {
if (files[extension]) {
const template = await fetchApiTemplate(token, extension);
contents[extension] = render(template, transformedData);
}
}
return {
contents,
data: transformedData
};
};
export const handleChoices = async (choices) => {
return await Promise.all(choices.map(async choice => {
return {
id: choice.id,
name: choice.name,
template: choice.variations.length > 0 ? await handleVariation(choice, choice.variations[0]) : null
};
}));
};
JavaScript site server example
This is a very basic web server example
const http = require('http');
const templates = handleChoices(choices);
const templatesContent = templates
.map(template => {
if (!template) return ''; // Skip if template is null or undefined
return `
${template.css ? `<style>${template.css}</style>` : ''}
${template.html || ''}
${template.js ? `<script>${template.js}</script>` : ''}
`;
})
.filter(content => content.trim() !== '') // Remove any empty strings
.join('');
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(`
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Server-side Rendering Example</title>
</head>
<body>
${templatesContent}
</body>
</html>
`);
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
});
Template in the Experience OS editor
Response example
{
"id":785442,
"name":"Rcom2",
"type":"RECS_DECISION",
"variations":[
{
"id":29204277,
"payload":{
"data":{
"custom":{
"dyVariationId":"29204277",
"Title":"",
"TemplateProductData":{
"Url":"url",
"Image_url":"image_url",
"Currency Icon":"dy_display_price",
"price":"price",
"Name":"name"
}
},
"slots":[
{
"sku":"119",
"productData":{
"group_id":"119",
"categories":[
"Cats",
"Toys"
],
"keywords":[
],
"in_stock":true,
"publish_time":"2024-07-21T10:27:13",
"name":"Cat Scratch Tower (Midi)",
"description":"Simple, effective and portable. Let your cat keep its claws in a scratch-tastis shape.",
"url":"/product/119",
"image_url":"http://cdn.dynamicyield.com/petshop/images/Group 119.png",
"price":0,
"dy_display_price":"0"
},
"slotId":"mIOobG9jYXRpb27ZUmh0dHBzOi8vZ3ZkeXRlc3RpbmcudHVtYmxyLmNvbS8/JmR5QXBpUHJldmlldz04MWI3NzlkMy1jZjkyLTQ0NjAtYTk1Zi1iOTE1YWRlY2YwYTCkdHlwZahIT01FUEFHRaRkYXRhkM3BPc4AA18BwgCjMTE5CQA=*nLM4NjYxMzYzNDA0OTk1OTY4MTMxzgAcfi+oMTM1NDA3MTYBkJHOAb2fNaU3MzYxNcDAtC01ODYzMjM2MDI5MTk3MzEyMjk5wMA="
},
{
"sku":"120",
"productData":{
"group_id":"120",
"categories":[
"Cats",
"Toys"
],
"keywords":[
],
"in_stock":true,
"publish_time":"2024-07-21T10:27:13",
"name":"Extreme Cat Distractor",
"description":"Your cat has seen it all, and for everything you throw at him you're only rewarded with a sleepy yawn? Well, try this!",
"url":"/product/120",
"image_url":"http://cdn.dynamicyield.com/petshop/images/Group 120.png",
"price":15,
"dy_display_price":"15"
},
"slotId":"mIOobG9jYXRpb27ZUmh0dHBzOi8vZ3ZkeXRlc3RpbmcudHVtYmxyLmNvbS8/JmR5QXBpUHJldmlldz04MWI3NzlkMy1jZjkyLTQ0NjAtYTk1Zi1iOTE1YWRlY2YwYTCkdHlwZahIT01FUEFHRaRkYXRhkM3BPc4AA18BwgGjMTIwCQE=*nLM4NjYxMzYzNDA0OTk1OTY4MTMxzgAcfi+oMTM1NDA3MTYBkJHOAb2fNaU3MzYxNcDAtC01ODYzMjM2MDI5MTk3MzEyMjk5wMA="
},
{
"sku":"122",
"productData":{
"group_id":"122",
"categories":[
"Cats",
"Travel"
],
"keywords":[
],
"in_stock":true,
"publish_time":"2024-07-21T10:27:13",
"name":"Atheletic Performance MAX Cat Collar",
"description":"For cats who love jogging with their humans, with patented Catdex(R) V3 synthetic fabric.",
"url":"/product/122",
"image_url":"http://cdn.dynamicyield.com/petshop/images/Group 122.png",
"price":39,
"dy_display_price":"39"
},
"slotId":"mIOobG9jYXRpb27ZUmh0dHBzOi8vZ3ZkeXRlc3RpbmcudHVtYmxyLmNvbS8/JmR5QXBpUHJldmlldz04MWI3NzlkMy1jZjkyLTQ0NjAtYTk1Zi1iOTE1YWRlY2YwYTCkdHlwZahIT01FUEFHRaRkYXRhkM3BPc4AA18BwgKjMTIyCQI=*nLM4NjYxMzYzNDA0OTk1OTY4MTMxzgAcfi+oMTM1NDA3MTYBkJHOAb2fNaU3MzYxNcDAtC01ODYzMjM2MDI5MTk3MzEyMjk5wMA="
}
]
},
"type":"RECS"
},
"template":{
"token":"0279be6c42caefabc84f463654b03342",
"files":{
"html":true,
"css":false,
"js":false
}
}
}
],
"groups":[
"rcomGroup"
],
"decisionId":"nLMxNjg0MjQ3OTkxOTgyMTY0NDA3zgAW4T+oMTIyNTMwNDYBkJHOAaqJZKU1NzM4OcDZIGU3N2FjYmM2MjVjNWQ4MWQ5NWIxMmIxNzY3YTU3MzIzszEwNjY0NTM4ODI3MjQ0NjE2MTDAwA=="
}
Data object created from the sample response
{
"dyVariationId":"29204277",
"Title":"",
"decisionId":"nLMxNjg0MjQ3OTkxOTgyMTY0NDA3zgAW4T+oMTIyNTMwNDYBkJHOAaqJZKU1NzM4OcDZIGU3N2FjYmM2MjVjNWQ4MWQ5NWIxMmIxNzY3YTU3MzIzszEwNjY0NTM4ODI3MjQ0NjE2MTDAwA==",
"Recommendation":[
{
"Url":"/product/119",
"Image_url":"http://cdn.dynamicyield.com/petshop/images/Group 119.png",
"Currency Icon":"0",
"price":0,
"Name":"Cat Scratch Tower (Midi)"
},
{
"Url":"/product/120",
"Image_url":"http://cdn.dynamicyield.com/petshop/images/Group 120.png",
"Currency Icon":"15",
"price":15,
"Name":"Extreme Cat Distractor"
},
{
"Url":"/product/122",
"Image_url":"http://cdn.dynamicyield.com/petshop/images/Group 122.png",
"Currency Icon":"39",
"price":39,
"Name":"Atheletic Performance MAX Cat Collar"
}
]
}
Updated about 2 months ago