All Collections
Share & Embed
Widgets Embed/iframe APIs (Advanced)
Widgets Embed/iframe APIs (Advanced)

This article provides an explanation of APIs for controlling widget embeds programmatically using JavaScript.

Dima Mjakotnyj avatar
Written by Dima Mjakotnyj
Updated over a week ago

Opinion Stage widget embeds (general embed or iframe) send different event messages (e.g., the widget's height change) to the host using the JavaScript window.postMessage facility.

The event messages originate from "https://www.opinionstage.com" and are serialized as JSON strings. The event data JSON has a mandatory "name" key (string) that signals the event type.

IMPORTANT: The widgets send multiple event messages to their JavaScript loader code for different reasons. Events that do not have the "name" key are internal and may be subject to change in the future. Please do not use these events because they are unreliable.

Use the latest general embed or iframe code when implementing this functionality.

To subscribe to the public events API, use the following code:

window.addEventListener('message', function (event) {
if (event.origin !== 'https://www.opinionstage.com') { return }

var payload

try {
payload = JSON.parse(event.data)
} catch(e) {
(console.error || console.log)('failed parsing OpinionStage event data:', e)
return
}

if ( payload.name === 'EVENT NAME, see documentation below for exact names' ) {
console.log('received OpinionStage event:', payload)
}
}, false)

Height change event (name: opinionstage:v1:widget:height:change)

The height change event is posted each time the widget's IFRAME height changes due to a user action. The event is not posted when the height doesn't change (even if the user interacted with the widget).

Example payload:

{
name: "opinionstage:v1:widget:height:change",
widgetId: "(string)",
height: {
previous: 200,
current: 590,
},
widgetIframe: "(string)",
widgetLoaderPlaceholder: "(string)",
}

Payload data explained:

  • payload.name - mandatory event name (for the height change event, it's always "opinionstage:v1:widget:height:change")

  • payload.widgetId - ID of the widget in the form of UUID. This is the same UUID that can be found as part of the widget's landing page URL (for example: "https://www.opinionstage.com/page/311dc3f9-63d7-4ef0-b8df-2fd8241e9fb8" - the 311dc3f9-63d7-4ef0-b8df-2fd8241e9fb8 is widget ID)

  • payload.height.current - the current height of the widget's IFRAME tag (can be null on the first load)

  • payload.height.previous - the previous height of the widget IFRAME tag

  • payload.widgetIframe - CSS selector of the widget IFRAME tag

  • payload.widgetLoaderPlaceholder - CSS selector of the widget placeholder DIV tag (this DIV tag is displayed in the widget JavaScript embed code and is absent when the widget is embedded with the iframe code)

NOTE: Please do not rely on the exact values of the CSS selectors mentioned above.

The exact values are subject to change; please always use the values from payload variables.

Example usage with jQuery:

window.addEventListener('message', function (event) {
if (event.origin !== 'https://www.opinionstage.com') { return }

var payload

try {
payload = JSON.parse(event.data)
} catch(e) {
(console.error || console.log)('failed parsing OpinionStage event data:', e)
return
}

if ( payload.name === 'opinionstage:v1:widget:height:change' ) {
console.log('OpinionStage widget height change')
$(payload.widgetIframe).height(payload.height.current)
}
}, false)

Answer click event (name: opinionstage:v1:widget:answer:click)

The click event is posted each time the user clicks the widget answer.

Example payload:

{
name: "opinionstage:v1:widget:answer:click",
widgetId: "(string)",
widgetIframe: "(string)",
widgetLoaderPlaceholder: "(string)",
}

Example usage with jQuery:

window.addEventListener('message', function (event) {
if (event.origin !== 'https://www.opinionstage.com') { return }

var payload

try {
payload = JSON.parse(event.data)
} catch(e) {
(console.error || console.log)('failed parsing OpinionStage event data:', e)
return
}

if ( payload.name === 'opinionstage:v1:widget:answer:click' ) {
console.log('OpinionStage widget answer click')
// update ads code can be here
}
}, false)

Result calculated event (name: opinionstage:v1:widget:result:calculated)

NOTE: Specific to these widgets:

  • trivia quiz

The result calculated event happens when the user answers all widget questions.

Example payload:

{
name: "opinionstage:v1:widget:result:calculated",
widgetId: "(string)",
result: {
id: "(string)",
title: "(string)",
description: "(string)",
},
details: {
correct_answers_count: integer,
questions_count: integer,
},
widgetIframe: "(string)",
widgetLoaderPlaceholder: "(string)",
}

Payload data explained:

  • payload.name - mandatory event name (for the height change event, it's always "opinionstage:v1:widget:height:change")

  • payload.widgetId - ID of the widget in the form of UUID. This is the same UUID that can be found as part of the widget's landing page URL (for example: "https://www.opinionstage.com/page/311dc3f9-63d7-4ef0-b8df-2fd8241e9fb8" - the 311dc3f9-63d7-4ef0-b8df-2fd8241e9fb8 is the widget ID)

  • payload.result.id - ID of the result card in the form of UUID.

  • payload.result.title - The title of the result card is shown to the user.

  • payload.result.description - The text (description) of the result card is shown to the user.

  • payload.details.correct_answers_count - (trivia quiz only) number of correct answers the user got.

  • payload.details.questions_count - number of all question cards in the widget.

  • payload.widgetIframe - CSS selector of the widget IFRAME tag

  • payload.widgetLoaderPlaceholder - CSS selector of the widget placeholder DIV tag (this DIV tag is displayed in the widget JavaScript embed code and is absent when the widget is embedded with the iframe code)

Did this answer your question?