placement.js arguments
placement.js arguments
This article describes the arguments passed to your renderPlacement
function.
meta
module.exports = function renderPlacement ({ meta }) {
console.log(meta)
}
The meta
object contains information about the currently executing Placement and its context:
Attribute | Description |
---|---|
cookieDomain |
the domain value that cookies have been configured to be stored against. This is useful if you need to store cookies in a consistent way |
isPreview |
Whether the variant is executing in preview mode (can be useful if you want to avoid sending data while previewing |
for example) |
trackingId |
The tracking id of the property on which the experience is executing |
namespace |
The value of your configured namespace if you have one. This allows you to define a custom schema |
vertical |
A code representing your industry sector. This affects what events you should send and their prefix |
placementId |
the id of the currently executing Placement |
visitorId |
elements
module.exports = function renderPlacement ({ elements }) {
console.log(elements)
}
The elements
array contains the results of evaluating all the Polling for
simple triggers.
onImpression
module.exports = function renderPlacement ({ onImpression }) {
onImpression()
}
You should call the onImpression
function whenever your Placement might have been seen by an eligible visitor.
When a campaign is live that targets your Placement, this will allow us to report on who saw it and what impact it may have had on them.
It’s important to call onImpression
both when there’s content and when there isn’t so that the reporting can compare visitors who saw the campaign with those that didn’t.
The criteria used to decide whether to call onImpression
should be equivalent regardless of whether there’s content or not.
This equivalence helps avoid introducing bias when performing A/B tests on campaigns.
Note
See our guide on impressions and clickthroughs for more details. |
onClickthrough
module.exports = function renderPlacement ({ onClickthrough }) {
onClickthrough()
}
You should call the onClickthrough
function whenever your Placement gets clicked or interacted with.
When a campaign is live that targets your Placement, this will allow us to report on visitor engagement with your campaign.
If your Placement is replacing an element such as a carousel, it’s important to set up click handlers that call onClickthrough
both for the original element you’re replacing and for the one you’re replacing it with.
This approach will allow the reporting to compare the engagement of visitors who saw the campaign with those that did not.
See our guide on impressions and clickthroughs for more details.
log
module.exports = function renderPlacement (options) {
console.log(options.log)
}
A stylish logger, useful for development of Placements. See https://github.com/QubitProducts/driftwood for more info:
module.exports = function renderPlacement ({ log }) {
try {
log.info('hello from variation ' + options.variationMasterId)
throw new Error('stone')
} catch (eek) {
log.error('', eek)
}
}
getVisitorState
module.exports = function renderPlacement ({ getVisitorState }) {
getVisitorState().then(function (state) {
console.log(state)
})
}
This method allows you to get useful information about a user, including an IP address.
The getVisitorState
method returns a sync-p
style promise usually resolved synchronously, but on the first view of a session, syncing with the lookup API will cause it to be asynchronous.
Cross-domain setups will always have an asynchronous getVisitorState
method.
However, this setup is rare.
state
:
Attribute | Description |
---|---|
viewTs |
A timestamp for the most recent view event |
pageViewNumber |
The number of views the visitor has had |
cookiePersists |
False if the user’s cookie fails to persist |
timezoneOffset |
The timezone offset of the visitor in minutes from UTC |
visitorId |
Equivalent of context Id and cookie Id that’s randomly assigned to each visitor to identify them on your site - device specific |
conversionNumber |
The number of conversions the visitor has made - updated on the next view event after a conversion |
conversionCycleNumber |
The number of conversion cycles the visitor has had across their lifetime.The conversionCycleNumber increments only on the session following a session with one or more conversions |
lifetimeValue |
The total amount transacted by the visitor over their lifetime - updated at the beginning of the next session |
firstViewTs |
The date of the first View for the visitor |
lastViewTs |
The date of the last View for the visitor |
viewNumber |
The number of view event across the user’s lifetime |
entranceViewNumber |
The number of views the visitor has seen in the entrance |
sessionNumber |
The number of sessions the visitor has had across their lifetime |
entranceNumber |
The number of entrances the visitor has had across their lifetime |
ipAddress |
The IP Address of the device |
entranceTs |
Timestamp for when the entrance was initiated |
sessionViewNumber |
The number of views the visitor has seen in the session |
eventNumber |
The sequence number of the event for the current page view |
sessionTs |
Timestamp for when the session was initiated |
sample |
A number between 0 and 99 999 based on a hash of the visitor Id |
city |
The city name |
cityCode |
The city code |
country |
The country name |
countryCode |
The ISO 4217 currency code for the user (for example, |
latitude |
The latitude value |
longitude |
The longitude value |
area |
The area name |
areaCode |
The area code |
region |
The region name |
regionCode |
The region code |
Leading practice
A typical use case for getting a user’s IP address is to exclude a range of IP addresses from Qubit tests. |
getBrowserState
module.exports = function renderPlacement (options) {
options.getBrowserState().then(function (state) {
console.log(state)
})
}
Returns useful information about the user’s browser.
The getBrowserState
method returns a sync-p
style promise that always resolves synchronously.
state
:
Attribute | Description |
---|---|
url |
The current URL |
host |
The current host |
referrerUrl |
The referrer URL |
doNotTrack |
Whether the user has expressed a preference not to be tracked by web sites |
ua.deviceType |
The users' device type |
ua.deviceName |
The users' device name |
ua.osName |
The users' OS name |
ua.osVersion |
The users' OS version |
ua.browserName |
The users' Browser name |
ua.browserVersion |
The users' Browser version |
ua.userAgent |
The users' User Agent string |
isBot |
Whether the user is a bot |
time |
A timestamp for when the users' browser state was computed |
screenWidth |
The users screen width |
screenHeight |
The users screen height |
poll
Poll allows you to wait for:
-
The presence of DOM elements
-
The presence of window variables
-
Arbitrary conditions
and returns a promise for those elements, variables or the results of your custom poll functions:
// Wait for the presence of DOM elements by passing in a selector:
options.poll('body > .nav').then(function (nav) {
console.log(nav)
})
// Wait for window variables to be defined:
options.poll('window.foo.bar').then(function (bar) {
console.log(bar)
})
// Wait for arbitrary conditions to become truthy by passing in a custom function:
options.poll(() => true).then(result => console.log(result))
// Mix and match:
options.poll(['body > .nav', 'window.foo', () => 1234]).then(function ([nav, foo, id]) {
console.log(nav, foo, id)
})
// Create a poller instance with several targets
const poller = options.poll([
'body > .nav',
'window.foo.bar',
() => true
])
// Start polling
poller
// returns a promise for the items being polled for
.then(function ([nav, bar, truthy]) {
console.log(nav, bar, truthy)
})
// Stop polling
poller.stop()
// Start polling again
poller.start()
This uses @qubit/poller under the hood but is configured to provide useful logging when in preview mode.
uv
Our UV API is accessible as an argument and enables developers to build Placements that take advantage of our event-based protocol.
on
uv.on(type, handler, [context])
Attaches an event handler to be called when a certain event type is emitted. The handler will be passed the event data and will be bound to the context object if one is passed. If a regex is passed, the handler will execute on events that match the regex:
uv.on('ecProduct', function (data) {
console.log(data)
})
// => logs data when an `ecProduct` event is emitted
var subscription = uv.on(/.*/, function (data) {
console.log(data)
})
// => logs data for all events
The on
method returns a subscription object that can detach the handler using the dispose method and can also be used to replay events currently in the event array:
subscription.dispose()
// => detaches the event handler
subscription.replay()
// => calls the handler for all events currently in uv.events
Note
Subscriptions that have been disposed of won’t call the handler when replay is called. |
Note
On Single Page Applications that emit multiple |
once
uv.once(type, handler, [context])
Attaches an event handler that will be called once, only on the next event emitted that matches the type specified. The handler will be passed the event data and will be bound to the context object if one is passed. Returns a subscription object which can detach the handler using the dispose method. If a regex is passed, the handler will execute on the next event to match the regex:
uv.once('ecProduct', function (data) {
console.log(data)
})
emit('ecProduct')
// => logs data
emit('ecProduct')
// => does not log
The once
method returns a subscription object, which can detach the handler using the dispose method, and can also be used to replay events currently in the event array:
subscription.dispose()
// => detaches the event handler
subscription.replay()
// => calls the handler for all events currently in uv.events
Note
Subscriptions that have been disposed of will not call the handler when replay is called. |
Note
On single-page applications that emit multiple |
emit
uv.emit(type, [data])
Emits an event with the type and data specified.
The data should conform to the schema for the event type emitted.
All events that are emitted are given a meta
property with the event type
:
uv.emit('ecProduct', {
product: {
id: '112-334-a',
price: 6.99,
name: '18th Birthday Balloon',
category: ['Party Accessories', 'Birthday Parties']
},
color: 'red',
stock: 6,
eventType: 'detail'
})
// => emits an ecProduct event
The emitted event will have metadata attached:
{
"meta": {
"type": "ecProduct"
},
"product": {
"id": "112-334-a",
"price": 6.99,
"name": "18th Birthday Balloon",
"category": ["Party Accessories", "Birthday Parties"]
},
"color": "red",
"stock": 6,
"eventType": "detail"
}
Events
The events array is a cache of events emitted since the last page load. By iterating over the array, it is possible to interpret the visitor journey or the current state of the page.
onRemove
This hook lets you register any cleanup functions such as removing event listeners, which will be called if Smartserve restarts. This is particularly important in a single page application (SPA), as it allows you to prevent side effects carrying over between virtual page views.
If you implement this method, you will also be able to use the hot reloading feature of Coveo Qubit CLI.
module.exports = function renderPlacement ({ onRemove }) {
onRemove(cleanup)
return true
}