Overview of steps
Suppose a user enters a URL into a browser which sends a request to your web server. When fulfilling that request:
-
The server reads the visitor and target cookies from the request.
-
The server makes a call to the
getOffers
method of the Target SDK, specifying the visitor and target cookies if available. -
When the
getOffers
call is fulfilled, values fortargetCookie
andvisitorState
from the response are used.- A cookie is set on the response with values taken from
targetCookie
. This is done using theSet-Cookie
response header, which tells the browser to persist the target cookie. - An HTML response is prepared that initializes
VisitorAPI.js
and passes invisitorState
from the target response.
- A cookie is set on the response with values taken from
-
The HTML response is loaded in the browser…
VisitorAPI.js
is included in the document header.- VisitorAPI is initialized with
visitorState
from thegetOffers
SDK response. This will cause the visitor cookie to be set in the browser so it will be sent to the server on subsequent requests.
Example code
The following code sample implements each of the steps outlined above. Each step appears in the code as an inline comment next to its implementation.
Node.js
This sample relies on express, a Node.js web framework.
const fs = require("fs");
const express = require("express");
const cookieParser = require("cookie-parser");
const Handlebars = require("handlebars");
const TargetClient = require("@adobe/target-nodejs-sdk");
const CONFIG = {
client: "acmeclient",
organizationId: "1234567890@AdobeOrg",
timeout: 10000,
logger: console,
};
const targetClient = TargetClient.create(CONFIG);
const TEMPLATE = fs.readFileSync(`${__dirname}/index.handlebars`).toString();
const handlebarsTemplate = Handlebars.compile(TEMPLATE);
Handlebars.registerHelper("toJSON", function (object) {
return new Handlebars.SafeString(JSON.stringify(object, null, 4));
});
const app = express();
app.use(cookieParser());
app.use(express.static(__dirname + "/public"));
app.get("/", async (req, res) => {
// The server reads the visitor and target cookies from the request.
const visitorCookie =
req.cookies[
encodeURIComponent(
TargetClient.getVisitorCookieName(CONFIG.organizationId)
)
];
const targetCookie = req.cookies[TargetClient.TargetCookieName];
const address = { url: req.headers.host + req.originalUrl };
const targetRequest = {
execute: {
mboxes: [
{ name: "homepage", index: 1, address },
{ name: "SummerShoesOffer", index: 2, address },
{ name: "SummerDressOffer", index: 3, address }
],
},
};
res.set({
"Content-Type": "text/html",
Expires: new Date().toUTCString(),
});
try {
// The server makes a call to the `getOffers` method of the Target SDK specifying the visitor and target cookies if available.
const targetResponse = await targetClient.getOffers({
request: targetRequest,
visitorCookie,
targetCookie,
});
// When the `getOffers` call is fulfilled, values for `targetCookie` and `visitorState` from the response are used.
// A cookie is set on the response with values taken from `targetCookie`. This is done using the `Set-Cookie` response header which tells the browser to persist the target cookie.
res.cookie(
targetResponse.targetCookie.name,
targetResponse.targetCookie.value,
{ maxAge: targetResponse.targetCookie.maxAge * 1000 }
);
// An HTML response is prepared that initializes VisitorAPI.js and passes in `visitorState` from the target response.
const html = handlebarsTemplate({
organizationId: CONFIG.organizationId,
targetResponse,
});
res.status(200).send(html);
} catch (error) {
console.error("Target:", error);
res.status(500).send(error);
}
});
app.listen(3000, function () {
console.log("Listening on port 3000 and watching!");
});
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ECID (Visitor API) Integration Sample</title>
<!-- VisitorAPI.js is included in the document header. -->
<script src="VisitorAPI.js"></script>
<script>
// VisitorAPI is initialized with visitorState from the `getOffers` SDK response. This will cause the visitor cookie to be set in the browser so it will be sent to the server on subsequent requests.
Visitor.getInstance("{{organizationId}}", {serverState: {{toJSON targetResponse.visitorState}} });
</script>
</head>
<body>
<h1>response</h1>
<pre>{{toJSON targetResponse}}</pre>
</body>
</html>
Java
This sample uses spring, a Java web framework.
@SpringBootApplication
public class ClientSampleApplication {
public static void main(String[] args) {
System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "DEBUG");
SpringApplication.run(ClientSampleApplication.class, args);
}
@Bean
TargetClient marketingCloudClient() {
ClientConfig clientConfig = ClientConfig.builder()
.client("acmeclient")
.organizationId("1234567890@AdobeOrg")
.defaultDecisioningMethod(DecisioningMethod.SERVER_SIDE)
.build();
return TargetClient.create(clientConfig);
}
}
@Controller
@RequestMapping("/")
public class TargetController {
@Autowired
private TargetClientService targetClientService;
@GetMapping
public String index(Model model, HttpServletRequest request, HttpServletResponse response) {
// The server reads the visitor and target cookies from the request.
List<TargetCookie> targetCookies = getTargetCookies(request.getCookies());
Address address = getAddress(request);
List<MboxRequest> mboxRequests = new ArrayList<>();
mboxRequests.add((MboxRequest) new MboxRequest().name("homepage").index(1).address(address));
mboxRequests.add((MboxRequest) new MboxRequest().name("SummerShoesOffer").index(2).address(address));
mboxRequests.add((MboxRequest) new MboxRequest().name("SummerDressOffer").index(3).address(address));
TargetDeliveryResponse targetDeliveryResponse = targetClientService.getOffers(mboxRequests, targetCookies, request,
response);
// An HTML response is prepared that initializes VisitorAPI.js and passes in `visitorState` from the target response.
model.addAttribute("visitorState", targetDeliveryResponse.getVisitorState());
model.addAttribute("targetResponse", targetDeliveryResponse);
model.addAttribute("organizationId", "1234567890@AdobeOrg");
return "index";
}
}
@Service
public class TargetClientService {
private final TargetClient targetJavaClient;
public TargetClientService(TargetClient targetJavaClient) {
this.targetJavaClient = targetJavaClient;
}
public TargetDeliveryResponse getOffers(List<MboxRequest> executeMboxes, List<TargetCookie> cookies, HttpServletRequest request, HttpServletResponse response) {
Context context = getContext(request);
ExecuteRequest executeRequest = new ExecuteRequest();
executeRequest.setMboxes(executeMboxes);
TargetDeliveryRequest targetDeliveryRequest = TargetDeliveryRequest.builder()
.context(context)
.execute(executeRequest)
.cookies(cookies)
.build();
// The server makes a call to the `getOffers` method of the Target SDK specifying the visitor and target cookies if available.
TargetDeliveryResponse targetResponse = targetJavaClient.getOffers(targetDeliveryRequest);
// When the `getOffers` call is fulfilled, values for `targetCookie` and `visitorState` from the response are used.
// A cookie is set on the response with values taken from `targetCookie`. This is done using the `Set-Cookie` response header which tells the browser to persist the target cookie.
setCookies(targetResponse.getCookies(), response);
return targetResponse;
}
}
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Target Only : GetOffer</title>
<!-- VisitorAPI.js is included in the document header. -->
<script src="https://experienceleague.adobe.com/js/VisitorAPI.js?lang=en"></script>
<script th:inline="javascript">
// VisitorAPI is initialized with visitorState from the `getOffers` SDK response. This will cause the visitor cookie to be set in the browser so it will be sent to the server on subsequent requests.
Visitor.getInstance(/*[[${organizationId}]]*/ "", {serverState: /*[[${visitorState}]]*/ {}});
</script>
</head>
<body>
<h1>response</h1>
<pre>[[${targetResponse}]]</pre>
</body>
</html>
For more information about TargetRequestUtils.java
, see Utility Methods (Java)
Personalization & Experiementation Excellence with Recommendations and AI
Adobe Customer Success Webinars
Tuesday, Mar 4, 4:00 PM UTC
Adobe Target innovations, including GenAI, and best practices on AI-powered personalization and experimentation at scale.
RegisterAdobe Target at Summit
Register for these developer sessions:
- Put the Customer at the Center and Build Relationships That Last a Lifetime (attend online)
- Implement Adobe Target for Optimal Performance (hands-on lab)
- How T-Mobile Personalizes Customer Experiences with AI Decisioning
- AI-Powered Personalization: Prudential's Secret to a 135% Engagement Boost
- Personalization at Scale, with Accuracy: Flexible Identity Graph Management (hands-on lab)
Connect with Experience League at Summit!
Get front-row access to top sessions, hands-on activities, and networking—wherever you are!
Learn more