개인화된 콘텐츠 렌더링
Adobe Experience Platform Web SDK는 Adobe Target, Offer decisioning 및 Adobe Journey Optimizer을(를) 포함하여 Adobe 개인화 솔루션에서 개인화된 콘텐츠를 검색할 수 있도록 지원합니다.
또한 Web SDK는 Adobe Target 및 사용자 지정 개인화 연결과 같은 Adobe Experience Platform 개인화 대상을 통해 동일한 페이지 및 다음 페이지 개인화 기능을 지원합니다. 동일 페이지 및 다음 페이지 개인화에 대한 Experience Platform을 구성하는 방법에 대해 알아보려면 전용 안내서를 참조하세요.
Adobe Target의 시각적 경험 작성기 및 Adobe Journey Optimizer의 웹 캠페인 UI 내에서 만든 콘텐츠를 SDK에서 자동으로 검색하고 렌더링할 수 있습니다. Adobe Target의 양식 기반 경험 작성기, Adobe Journey Optimizer의 코드 기반 경험 채널 또는 Offer decisioning 내에서 만들어진 콘텐츠는 SDK에서 자동으로 렌더링할 수 없습니다. 대신 SDK를 사용하여 이 콘텐츠를 요청한 다음 직접 콘텐츠를 수동으로 렌더링해야 합니다.
자동으로 콘텐츠 렌더링 automatic
서버에 이벤트를 보낼 때 renderDecisions
옵션을 true
(으)로 설정할 수 있습니다. 이렇게 하면 SDK가 자동 렌더링에 적합한 개인화된 콘텐츠를 자동으로 렌더링합니다.
alloy("sendEvent", {
"renderDecisions": true,
"xdm": {
"commerce": {
"order": {
"purchaseID": "a8g784hjq1mnp3",
"purchaseOrderNumber": "VAU3123",
"currencyCode": "USD",
"priceTotal": 999.98
}
}
}
});
개인화된 콘텐츠를 렌더링하는 것은 비동기적이므로 특정 콘텐츠가 렌더링을 완료한 시기에 대해 가정해서는 안 됩니다.
수동으로 컨텐츠 렌더링 manual
개인화 콘텐츠에 액세스하려면 SDK가 서버로부터 성공적인 응답을 받은 후에 호출되는 콜백 함수를 제공할 수 있습니다. 콜백에는 반환된 개인화 콘텐츠가 포함된 propositions
속성이 포함될 수 있는 result
개체가 제공됩니다. 다음은 이벤트를 전송할 때 콜백 함수를 제공하는 방법의 예입니다.
alloy("sendEvent", {
"xdm": {}
}).then(function(result) {
if (result.propositions) {
// Manually render propositions and send "display" event
}
});
이 예에서 result.propositions
은(는) 존재하는 경우 이벤트와 관련된 개인화 제안이 포함된 배열입니다. 기본적으로 자동 렌더링에 적합한 제안만 포함됩니다.
propositions
배열은 다음 예제와 유사할 수 있습니다.
[
{
"id": "AT:eyJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ9",
"scope": "__view__",
"items": [
{
"id": "11223344",
"schema": "https://ns.adobe.com/personalization/dom-action",
"data": {
"content": "<h2 style=\"color: yellow\">An HTML proposition.</h2>",
"selector": "#hero",
"type": "setHtml"
},
"meta": {}
}
],
"scopeDetails": {
...
},
"renderAttempted": false
},
{
"id": "AT:PyJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ8",
"scope": "__view__",
"items": [
{
"id": "11223345",
"schema": "https://ns.adobe.com/personalization/dom-action",
"data": {
"content": "<h2 style=\"color: yellow\">Another HTML proposition.</h2>",
"selector": "#sidebar",
"type": "setHtml"
},
"meta": {}
}
],
"scopeDetails": {
...
},
"renderAttempted": false
}
]
이 예제에서 sendEvent
명령을 실행할 때 renderDecisions
옵션이 true
(으)로 설정되지 않았으므로 SDK에서 콘텐츠를 자동으로 렌더링하지 않았습니다. 그러나 SDK는 자동 렌더링에 적합한 콘텐츠를 계속 자동으로 검색했으며, 원하는 경우 수동으로 렌더링하도록 제공했습니다. 각 제안 개체의 renderAttempted
속성이 false
(으)로 설정되어 있습니다.
이벤트를 보낼 때 대신 renderDecisions
옵션을 true
(으)로 설정했다면 SDK에서 자동 렌더링에 적합한 제안을 렌더링하려고 시도했을 것입니다(앞에서 설명한 대로). 따라서 각 제안 객체의 renderAttempted
속성은 true
(으)로 설정됩니다. 이 경우 이러한 제안을 수동으로 렌더링할 필요가 없습니다.
지금까지 자동 렌더링에 적합한 개인화 콘텐츠(즉, Adobe Target의 시각적 경험 작성기 또는 Adobe Journey Optimizer의 웹 캠페인 UI에서 만들어진 모든 콘텐츠)에 대해서만 논의했습니다. 자동 렌더링에 적합하지 않은 개인화 콘텐츠를 검색하려면 이벤트를 전송할 때 decisionScopes
옵션을 채워 콘텐츠를 요청해야 합니다. 범위는 서버에서 검색할 특정 제안을 식별하는 문자열입니다.
다음은 한 예입니다.
alloy("sendEvent", {
"xdm": {},
"decisionScopes": ['salutation', 'discount']
}).then(function(result) {
if (result.propositions) {
// Manually render propositions and send "display" event
}
});
이 예제에서 salutation
또는 discount
범위와 일치하는 서버에 제안이 있으면 반환되어 result.propositions
배열에 포함됩니다. renderDecisions
또는 decisionScopes
옵션을 구성하는 방법에 관계없이 자동 렌더링에 적합한 제안이 propositions
배열에 계속 포함됩니다. 이 경우 propositions
배열은 다음 예제와 비슷합니다.
[
{
"id": "AT:cZJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ2",
"scope": "salutation",
"items": [
{
"schema": "https://ns.adobe.com/personalization/json-content-item",
"data": {
"id": "4433221",
"content": {
"salutation": "Welcome, esteemed visitor!"
}
},
"meta": {}
}
],
"scopeDetails": {
"id": "AT:cZJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ2",
"activity": {
"id": "384456"
}
},
"renderAttempted": false
},
{
"id": "AT:FZJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ0",
"scope": "discount",
"items": [
{
"schema": "https://ns.adobe.com/personalization/html-content-item",
"data": {
"id": "4433222",
"content": "<div>50% off your order!</div>",
"format": "text/html"
},
"meta": {}
}
],
"scopeDetails": {
"id": "AT:FZJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ0",
"activity": {
"id": "384457"
}
},
"renderAttempted": false
},
{
"id": "AT:eyJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ9",
"scope": "__view__",
"items": [
{
"id": "11223344",
"schema": "https://ns.adobe.com/personalization/dom-action",
"data": {
"content": "<h2 style=\"color: yellow\">An HTML proposition.</h2>",
"selector": "#hero",
"type": "setHtml"
},
"meta": {}
}
],
"scopeDetails": {
"id": "AT:PyJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ8",
"activity": {
"id": "384459"
}
},
"renderAttempted": false
},
{
"id": "AT:PyJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ8",
"scope": "__view__",
"items": [
{
"id": "11223345",
"schema": "https://ns.adobe.com/personalization/dom-action",
"data": {
"content": "<h2 style=\"color: yellow\">Another HTML proposition.</h2>",
"selector": "#sidebar",
"type": "setHtml"
},
"meta": {}
}
],
"scopeDetails": {
"id": "AT:PyJhY3Rpdml0eUlkIjoiMTI3MDE5IiwiZXhwZXJpZW5jZUlkIjoiMCJ8",
"activity": {
"id": "384459"
}
},
"renderAttempted": false
}
]
이 시점에서 맞춤법이 보이는 대로 제안 콘텐츠를 렌더링할 수 있습니다. 이 예에서 discount
범위와 일치하는 HTML은 Adobe Target의 양식 기반 경험 작성기를 사용하여 작성된 경험 제안입니다. 페이지에 ID가 daily-special
인 요소가 있고 discount
제안의 콘텐츠를 daily-special
요소로 렌더링하려는 경우 다음을 수행하십시오.
result
개체에서 제안을 추출합니다.discount
범위의 제안을 찾아 각 제안을 반복합니다.- 명제를 찾으면 명제의 각 항목을 반복하여 HTML 콘텐츠인 항목을 찾습니다. (가정하는 것보다 확인하는 것이 좋습니다.)
- HTML 콘텐츠가 들어 있는 항목을 찾으면 페이지에서
daily-special
요소를 찾아 해당 HTML을 개인화된 콘텐츠로 바꾸십시오. - 콘텐츠가 렌더링되면
display
이벤트를 보냅니다.
코드는 다음과 같습니다.
alloy("sendEvent", {
"xdm": {},
"decisionScopes": ['salutation', 'discount']
}).then(function(result) {
var propositions = result.propositions;
var discountProposition;
if (propositions) {
// Find the discount proposition, if it exists.
for (var i = 0; i < propositions.length; i++) {
var proposition = propositions[i];
if (proposition.scope === "discount") {
discountProposition = proposition;
break;
}
}
}
var discountHtml;
if (discountProposition) {
// Find the item from proposition that should be rendered.
// Rather than assuming there a single item that has HTML
// content, find the first item whose schema indicates
// it contains HTML content.
for (var j = 0; j < discountProposition.items.length; j++) {
var discountPropositionItem = discountProposition.items[i];
if (discountPropositionItem.schema === "https://ns.adobe.com/personalization/html-content-item") {
discountHtml = discountPropositionItem.data.content;
// Render the content
var dailySpecialElement = document.getElementById("daily-special");
dailySpecialElement.innerHTML = discountHtml;
// For this example, we assume there is only a signle place to update in the HTML.
break;
}
}
// Send a "display" event
alloy("sendEvent", {
"xdm": {
"eventType": "decisioning.propositionDisplay",
"_experience": {
"decisioning": {
"propositions": [
{
"id": discountProposition.id,
"scope": discountProposition.scope,
"scopeDetails": discountProposition.scopeDetails
}
],
"propositionEventType": {
"display": 1
}
}
}
}
});
}
});
플리커 관리
SDK는 개인화 프로세스 중에 깜박임을 관리할 수 있는 기능을 제공합니다.
지표를 증가시키지 않고 단일 페이지 애플리케이션에서 제안 렌더링 applypropositions
applyPropositions
명령을 사용하면 Analytics 및 Target 지표를 증가시키지 않고 Target 또는 Adobe Journey Optimizer의 제안 배열을 단일 페이지 애플리케이션으로 렌더링하거나 실행할 수 있습니다. 이렇게 하면 보고 정확도가 높아집니다.
__view__
범위(또는 웹 표면)에 대한 제안이 렌더링되면 해당 renderAttempted
플래그가 true
(으)로 설정됩니다. applyPropositions
명령은 renderAttempted: true
플래그가 있는 __view__
범위(또는 웹 표면) 제안을 다시 렌더링하지 않습니다.사용 사례 1: 단일 페이지 애플리케이션 뷰 제안 다시 렌더링
아래 샘플에 설명된 사용 사례는 디스플레이 알림을 보내지 않고 이전에 가져와서 렌더링된 장바구니 보기 제안을 다시 렌더링합니다.
아래 예에서 sendEvent
명령은 보기 변경 시 트리거되고 결과 개체를 상수에 저장합니다.
그런 다음 보기 또는 구성 요소가 업데이트되면 이전 sendEvent
명령의 제안을 사용하여 applyPropositions
명령을 호출하여 보기 제안을 다시 렌더링합니다.
var cartPropositions = alloy("sendEvent", {
"renderDecisions": true,
"xdm": {
"web": {
"webPageDetails": {
"viewName": "cart"
}
}
}
}).then(function(result) {
var propositions = result.propositions;
// Collect response tokens, etc.
return propositions;
});
// Call applyPropositions to re-render the view propositions from the previous sendEvent command.
alloy("applyPropositions", {
"propositions": cartPropositions
});
사용 사례 2: 선택기가 없는 제안 렌더링
이 사용 사례는 Target Form-based Experience Composer 또는 Adobe Journey Optimizer의 코드 기반 경험 채널을 사용하여 작성된 경험에 적용됩니다.
applyPropositions
호출에 선택기, 작업 및 범위를 제공해야 합니다.
지원되는 actionTypes
은(는)
setHtml
replaceHtml
appendHtml
// Retrieve propositions for salutation and discount scopes
alloy("sendEvent", {
"decisionScopes": ["salutation", "discount"]
}).then(function(result) {
var retrievedPropositions = result.propositions;
// Render propositions on the page by providing additional metadata
return alloy("applyPropositions", {
"propositions": retrievedPropositions,
"metadata": {
"salutation": {
"selector": "#first-form-based-offer",
"actionType": "setHtml"
},
"discount": {
"selector": "#second-form-based-offer",
"actionType": "replaceHtml"
}
}
}).then(function(applyPropositionsResult) {
var renderedPropositions = applyPropositionsResult.propositions;
// Send the display notifications via sendEvent command
function sendDisplayEvent(proposition) {
const {
id,
scope,
scopeDetails = {}
} = proposition;
alloy("sendEvent", {
"xdm": {
"eventType": "decisioning.propositionDisplay",
"_experience": {
"decisioning": {
"propositions": [{
"id": id,
"scope": scope,
"scopeDetails": scopeDetails
}],
"propositionEventType": {
"display": 1
}
}
}
}
});
}
});
});
결정 범위에 대한 메타데이터를 제공하지 않으면 관련 제안이 렌더링되지 않습니다.