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" 
      } 
   ] 
}