Dynamic Creatives for the Cortex Player
Reading Time: ±6 minutes
Introduction
A dynamic creative is an ad that changes based on variables such as location or time. Dynamic creatives let you show a message that's relevant to a specific audience or situation instead of displaying the same general creative.
This topic explains how to build dynamic creatives for the Cortex Player and support their playback.
Note: This topic applies only to dynamic creatives launched through Vistar's Ad Server. Dynamic creatives launched through Vistar's DSP are pre-rendered and delivered to the Player as static images.
What You’ll Learn
In this topic, you'll learn how to:
Configure Dynamic Creative Support
Before the Cortex Player can display dynamic creatives on your device, you must enable support for the Cortex bundle MIME (Multipurpose Internet Mail Extensions) type. The required configuration depends on the app your device uses:
UAS (Unified Ad Serving) app: Update the Mime Types parameter to include application/cortex-bundle. Then, restart the Player.
VSA (Vistar Scheduling App): In Trafficking, select Cortex Supported for the venue that your device maps to.
Structure Dynamic Creative Files
Package your dynamic creative as a ZIP file so the Cortex Player can display it correctly. The ZIP file must include index.html in the root directory. Upload the ZIP file to an order in Ad Serving.
You can organize other files, such as JavaScript, CSS, images, and videos, as needed.
Figure 1. Example Dynamic Creative File Structure
Track Creative Visibility Using Player Signals
Cortex prepares dynamic creatives before displaying them on-screen. Player signals let your creative track when the creative is ready, visible, or no longer visible. Use these signals to control actions that depend on the creative's state. For example, wait for cortex-ready before retrieving Player configuration data, or wait for cortex-visible before starting animations or videos.
cortex-ready: The creative is set up in the background but isn't visible yet.
cortex-visible: The creative is visible on-screen.
cortex-hidden: The creative is no longer visible.
The time between cortex-ready and cortex-visible depends on the app your device uses:
The UAS app prepares creatives a few milliseconds before they appear.
-
VSA prepares creatives about five seconds before they appear.
When using VSA, all content in the dynamic creative's iframe must load before cortex-visible fires. The creative then appears on-screen. If the content hasn't finished loading, VSA raises a slot-cancelled event and serves fallback content instead.
Tip: For animated creatives, pause animations and videos until cortex-visible fires so they don't begin before the creative appears on-screen.
Retrieve Player Configuration Data
After cortex-ready fires, call getConfig() to retrieve Player configuration data and custom parameters that your dynamic creative can use. For example, you can add device location as a custom parameter and use it to change the creative based on where the device is located.
Function
window.Cortex.app.getConfig()
Example Response
The following example response shows that custom parameters are returned as string values.
{
// UAS app parameters
"venue_id": "my-awesome-venue",
"network_id": "abcd1234",
"allow_audio": false,
"static_duration": 15,
// Custom parameters
"my_custom_parameter": "always a string value",
"my_custom_boolean_parameter": "true",
"my_custom_number_parameter": "300"
}HTML and JavaScript Example
The following example waits for cortex-ready before calling getConfig(). It then retrieves and displays the venue and network IDs.
<head>
<style>
body {
background-color: white;
color: black;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
h2 {
margin-bottom: 20px;
}
</style>
<script>
window.addEventListener("cortex-ready", function() {
var config = window.Cortex.app.getConfig();
document.getElementById("venueId").innerHTML = config.venue_id;
document.getElementById("networkId").innerHTML = config.network_id;
});
</script>
</head>
<body>
<h2>Cortex Configuration:</h2>
<div>
<strong>Venue ID:</strong> <span id="venueId"></span>
</div>
<div>
<strong>Network ID:</strong> <span id="networkId"></span>
</div>
</body>Retrieve Device Custom Attributes
After cortex-ready fires, call getDeviceAttributes() to retrieve the custom attributes set on the device.
Function
window.Cortex.extra.getDeviceAttributes()
Example Response
[
{
name: "Station Name",
value: "HQ"
},
{
name: "Temperature",
value: "80"
}
]Send Custom Events to Fleet
Dynamic creatives can call window.Cortex.event.raise() to add custom events to the Player's local event database. The Player stores the events locally and publishes them to Fleet when the device is connected to the internet.
Use custom events to track details about what rendered on-screen. For example, an event can record whether the creative displayed a local fallback or successfully fetched and rendered real-time data. The event message can also record what data was retrieved. You can also use events to debug dynamic creatives during development and testing.
In Fleet, these events can have custom names and messages, an Information, Warning, or Critical priority. They appear with Dynamic Creative as the source.
If multiple events with the same name are sent within five seconds, they're rate limited and don't appear in Fleet.
Function
window.Cortex.event.raise(name, severity, message, source)
Arguments
The following table describes the arguments for window.Cortex.event.raise():
Argument |
Description |
|---|---|
name |
Unique event name. Maximum 64 characters. Use English characters only and don't include spaces. Events that don't meet these requirements are rejected and don't appear in Fleet. |
severity |
Event severity. Must be info, warning, or critical. |
message |
Event message. Maximum 512 characters. Fleet truncates longer messages. Use English characters only. |
source |
Event source. Must be vistar.dynamic-creative. Events with another source are rejected and don't appear in Fleet. |
Table 1. Function Arguments and Descriptions
Example
The following example publishes a warning event when the creative displays a local fallback:
window.Cortex.event.raise(
'dynamic-fallback-rendered',
'warning',
'Dynamic creative couldn\'t load website and showed local fallback instead',
'vistar.dynamic-creative'
);Support Offline Playback
The Cortex Player caches the dynamic creative ZIP file and its included assets, so the creative can still play when the device isn't connected to the internet. The Player doesn't cache assets or data retrieved from the internet in real time. If your creative depends on real-time requests, include an offline-friendly fallback so it can continue displaying content when those requests are unsuccessful.
When using VSA, all content in the dynamic creative's iframe must load before cortex-visible fires. The creative then appears on-screen. If the content hasn't finished loading, VSA raises a slot-cancelled event and serves fallback content instead.
If the dynamic creative ends before all network requests complete, VSA may be unable to prepare subsequent slots. This can cause fallback content to continue playing until the pending requests finish.
To help prevent this behavior, implement a four-second timeout. The timeout cancels outstanding network requests and displays the offline-friendly backup creative stored in the asset.
Sample Dynamic Creatives
When building a dynamic creative, you can reference the following sample dynamic creatives:
animated-dynamic-creative-sample: Uses cortex-ready and cortex-visible to start animations and videos when the dynamic creative appears on-screen. The sample includes two examples. Each subfolder has its own index.html file. To use an example, ZIP the applicable subfolder so index.html is in the root directory. Then, upload it as a creative to an Ad Serving order.
signals-and-parameter-dynamic-creative-sample: Responds to cortex-ready, cortex-visible, and cortex-hidden. It uses getConfig() to retrieve Player properties.
webpage-with-fallback-and-custom-events-dynamic-creative-sample: Attempts to load a webpage and displays a local cached image if the webpage doesn't load. It sends a custom info event when the webpage renders and a custom warning event when the local fallback renders instead.