Delegation
Handle analytics, player lifecycle, widget load, and errors with global and
widget-scoped delegates. Prefer BlazeSDK.addDelegateListener for SDK events
so cleanup and typing stay consistent.
Delegation use cases
- Catch events on the global level and send to your BI endpoint: By listening to global events like onEventTriggered, you can capture analytics data from across the application and send it to your Business Intelligence (BI) endpoint for tracking and analysis.
- Catch errors on the widget or SDK level and handle them gracefully: Using the onErrorThrown event, you can monitor errors within the SDK or widget, allowing you to gracefully handle failures, log issues, or provide fallback behavior to improve user experience.
- Catch empty widget content items and maybe try to fetch a different label: If the widget’s content is empty, you can listen to events like onWidgetDataLoadStarted and onWidgetDataLoadCompleted to detect when content is missing, and attempt to fetch alternative labels or data.
- Player appearance and dismissal: Events like onPlayerDidAppear and onPlayerDismissed allow you to trigger actions, such as fetching additional resources or updating your page’s content, when the story player appears or is dismissed.
Global events
To listen for global events within the application level, you can use either of the following methods:
Using BlazeSDK.addDelegateListener
Using document.addEventListener
- onEventTriggered - This delegate is invoked for all analytics events occurring in the SDK. It can be employed to monitor and track analytics events within the main application's analytical solution, especially when you need to capture application data across various platforms - recommended for analytics, not for Story/Widget lifecycle.
- onPlayerDidAppear - This delegate is triggered whenever the player (story or widget) appears.
- onPlayerDismissed - This delegate is triggered whenever the player (story or widget) is closed or dismissed.
- onErrorThrown - This delegate is triggered whenever an error is thrown from the SDK.
- onEntitlementDenied - This delegate is triggered when protected content can't be played because the viewer is not entitled to it (for example, a subscription is required or the external user token is missing or expired).
e.detailis anEntitlementDeniedDetail, which includes the denialreason. - onContentResolveError - This delegate is triggered when the SDK fails to resolve the playback URL for protected content for any reason other than a denial (for example, a network error, a timeout, a server error, or a response with no playable renditions).
e.detailis aContentResolveErrorDetail;retryAfteris the number of seconds to wait, set only when the server sends aRetry-Afterheader with a value in seconds. - onMomentStart - This delegate is triggered whenever the user start watching a moment.
- onStoryPlayerDidAppear - Deprecated: This event is triggered when the story player appears. Use onPlayerDidAppear instead.
- onStoryPlayerDismissed - Deprecated: This event is triggered when the story player is dismissed. Use onPlayerDismissed instead.
Code examples
1. UsingBlazeSDK.addDelegateListener:
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onEventTriggered, (e) => {
console.log("document onEventTriggered", e.detail);
});
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onPlayerDidAppear, (e) => {
console.log("document onPlayerDidAppear", e.detail);
});
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onPlayerDismissed, (e) => {
console.log("document onPlayerDismissed", e.detail);
});
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onErrorThrown, (e) => {
console.log("document onErrorThrown", e.detail);
});
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onEntitlementDenied, (e) => {
console.log("document onEntitlementDenied", e.detail);
});
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onContentResolveError, (e) => {
console.log("document onContentResolveError", e.detail);
});
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onMomentStart, (e) => {
console.log("document onMomentStart", e.detail);
});
// Deprecated event listeners
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onStoryPlayerDidAppear, (e) => {
console.log("document onStoryPlayerDidAppear", e.detail); // Deprecated
});
BlazeSDK.addDelegateListener(BlazeSDK.Delegations.onStoryPlayerDismissed, (e) => {
console.log("document onStoryPlayerDismissed", e.detail); // Deprecated
});2. Usingdocument.addEventListener:
document.addEventListener(BlazeSDK.Delegations.onEventTriggered, (e) => {
console.log("document onEventTriggered", e.detail);
});
document.addEventListener(BlazeSDK.Delegations.onPlayerDidAppear, (e) => {
console.log("document onPlayerDidAppear", e.detail);
});
document.addEventListener(BlazeSDK.Delegations.onPlayerDismissed, (e) => {
console.log("document onPlayerDismissed", e.detail);
});
document.addEventListener(BlazeSDK.Delegations.onErrorThrown, (e) => {
console.log("document onErrorThrown", e.detail);
});
document.addEventListener(BlazeSDK.Delegations.onEntitlementDenied, (e) => {
console.log("document onEntitlementDenied", e.detail);
});
document.addEventListener(BlazeSDK.Delegations.onContentResolveError, (e) => {
console.log("document onContentResolveError", e.detail);
});
document.addEventListener(BlazeSDK.Delegations.onMomentStart, (e) => {
console.log("document onMomentStart", e.detail);
});
// Deprecated event listeners
document.addEventListener(BlazeSDK.Delegations.onStoryPlayerDidAppear, (e) => {
console.log("document onStoryPlayerDidAppear", e.detail); // Deprecated
});
document.addEventListener(BlazeSDK.Delegations.onStoryPlayerDismissed, (e) => {
console.log("document onStoryPlayerDismissed", e.detail); // Deprecated
});Both BlazeSDK.addDelegateListener and document.addEventListener can be used, depending on your preference. However, it's recommended to use BlazeSDK.addDelegateListener for SDK-specific events as it provides more detailed information and handles SDK-specific event handling more effectively.
Notes:
- Deprecated Events: As indicated in the code comments,
onStoryPlayerDidAppearandonStoryPlayerDismissedare deprecated and will be removed in future versions of the SDK. You should useonPlayerDidAppearandonPlayerDismissedinstead. - Content access resolution events:
onEntitlementDeniedandonContentResolveErrorfire when protected content can't be played, either because access is denied or because the playback URL can't be resolved. Both payload types and theEntitlementDenialReasonenum are exported by the SDK. - Rate limits and outages: An HTTP 429 or 503 response fires
onContentResolveError, notonEntitlementDenied. TheRateLimitedandTemporarilyUnavailabledenial reasons appear only when the server reports them as part of a denial.
interface EntitlementDeniedDetail {
reason: EntitlementDenialReason;
contentId: string;
contentType: 'story' | 'moment' | 'video';
item: IStory | IMoment | IVideo; // the content item that was denied
httpStatus?: number;
paywalls?: string[];
message?: string;
widgetId?: string; // the widget element's id, when playback started from a widget that has one
}
interface ContentResolveErrorDetail {
contentId: string;
contentType: 'story' | 'moment' | 'video';
item: IStory | IMoment | IVideo;
httpStatus?: number;
message?: string;
retryAfter?: number; // seconds, from a numeric Retry-After header
widgetId?: string; // the widget element's id, when playback started from a widget that has one
}
enum EntitlementDenialReason {
SubscriptionRequired = 'SubscriptionRequired',
GeoBlocked = 'GeoBlocked',
VpnBlocked = 'VpnBlocked',
DeviceLimitReached = 'DeviceLimitReached',
ContentNotAvailable = 'ContentNotAvailable',
ExternalUserTokenMissing = 'ExternalUserTokenMissing',
ExternalUserTokenInvalid = 'ExternalUserTokenInvalid',
ExternalUserTokenExpired = 'ExternalUserTokenExpired',
RateLimited = 'RateLimited',
TemporarilyUnavailable = 'TemporarilyUnavailable',
Unknown = 'Unknown',
}Widget events
Available events on the widget level:
- onWidgetDataLoadStarted - This delegate is activated when the widget begins fetching stories from the server.
- onWidgetDataLoadCompleted - This delegate is activated when the widget has completed fetching stories from the server.
- onWidgetTriggerCTA - This delegate is activated when a user clicks on the CTA (Call to Action).
- onWidgetPlayerDismissed - This delegate is activated when the widget's player is dismissed.
- onWidgetStoryPlayerDismissed - Deprecated: This delegate is triggered when the widget's story player is dismissed. Use onWidgetPlayerDismissed instead.
const widgetView = BlazeSDK.WidgetGridView('stories-container', {
labels: ['top-stories'],
delegates: {
[BlazeSDK.Delegations.onWidgetDataLoadStarted]: (e) => console.log("widgetRowView onWidgetDataLoadStarted", e.detail),
[BlazeSDK.Delegations.onWidgetDataLoadCompleted]: (e) => console.log("widgetRowView onWidgetDataLoadCompleted", e.detail),
[BlazeSDK.Delegations.onWidgetTriggerCTA]: (e) => console.log("widgetRowView onWidgetTriggerCTA", e.detail),
[BlazeSDK.Delegations.onWidgetPlayerDismissed]: (e) => console.log("widgetRowView onWidgetPlayerDismissed", e.detail),
// Deprecated event listener
[BlazeSDK.Delegations.onWidgetStoryPlayerDismissed]: (e) => console.log("widgetRowView onWidgetStoryPlayerDismissed", e.detail), // Deprecated
}
})The delegate event encompasses an object that provides extensive information regarding the event, encompassing eventData and eventType. In the following example, we've already extracted e.detail to enhance clarity and transparency for your understanding.
<script>
BlazeSDK.Initialize('API-KEY')
const myTheme = BlazeSDK.Theme('grid-2-columns', 'story');
myTheme.layoutStyle.labelStyle.fontSize = "20px";
document.addEventListener(BlazeSDK.Delegations.onEventTriggered, (e) => { console.log("document onEventTriggered", e.detail) })
document.addEventListener(BlazeSDK.Delegations.onPlayerDidAppear, (e) => { console.log("document onPlayerDidAppear", e.detail) })
document.addEventListener(BlazeSDK.Delegations.onPlayerDismissed, (e) => { console.log("document onPlayerDismissed", e.detail) })
document.addEventListener(BlazeSDK.Delegations.onErrorThrown, (e) => { console.log("document onErrorThrown", e.detail) })
document.addEventListener(BlazeSDK.Delegations.onEntitlementDenied, (e) => { console.log("document onEntitlementDenied", e.detail) })
document.addEventListener(BlazeSDK.Delegations.onContentResolveError, (e) => { console.log("document onContentResolveError", e.detail) })
// Deprecated event listeners
document.addEventListener(BlazeSDK.Delegations.onStoryPlayerDidAppear, (e) => { console.log("document onStoryPlayerDidAppear", e.detail) }) // Deprecated
document.addEventListener(BlazeSDK.Delegations.onStoryPlayerDismissed, (e) => { console.log("document onStoryPlayerDismissed", e.detail) }) // Deprecated
let widgetRowView;
document.addEventListener("onBlazeSDKConnect", () => {
widgetRowView = BlazeSDK.WidgetGridView('stories-container', {
labels: ['top-stories'],
orderType: 'ZtoA',
maxDisplayItemsCount: 5,
theme: myTheme,
delegates: {
[BlazeSDK.Delegations.onWidgetDataLoadStarted]: (e) => console.log("widgetRowView onWidgetDataLoadStarted", e.detail),
[BlazeSDK.Delegations.onWidgetDataLoadCompleted]: (e) => console.log("widgetRowView onWidgetDataLoadCompleted", e.detail),
[BlazeSDK.Delegations.onWidgetTriggerCTA]: (e) => console.log("widgetRowView onWidgetTriggerCTA", e.detail),
[BlazeSDK.Delegations.onWidgetPlayerDismissed]: (e) => console.log("widgetRowView onWidgetPlayerDismissed", e.detail),
// Deprecated event listener
[BlazeSDK.Delegations.onWidgetStoryPlayerDismissed]: (e) => console.log("widgetRowView onWidgetStoryPlayerDismissed", e.detail), // Deprecated
}
})
});
</script>Error codes:
FailedToFindContainerId = 1,
FailedContainerIdHasWidgetAlready = 2,
FailedLoadingAppConfigurations = 3,
FailedLoadingStories = 100,
FailedEnrichStories = 101,
FailedToHaveLabels = 103,
FailedLoadingMoments = 110,
FailedEnrichMoments = 111,
FailedLoadingVideos = 120,
FailedEnrichVideos = 121,
// When user zooms in and scale is bigger than 1
VisualViewportScaled = 150,
// Invalid numberOfPlays in a moments playback configuration (replaced with 1)
InvalidLoopAndAdvanceConfiguration = 400,
// Missing or unknown loopBehavior in a moments playback configuration (falls back to infiniteLoop)
InvalidMomentsPlaybackConfiguration = 401,
// Unrecognized follow button icon source in the theme
InvalidFollowIconSource = 402,Delegation Enum
Delegation {
onEventTriggered = 'blaze-event-triggered',
onErrorThrown = 'blaze-error-event',
onPlayerDidAppear = 'blaze-player-did-appear',
onPlayerDismissed = 'blaze-player-dismissed',
onEntitlementDenied = 'blaze-entitlement-denied',
onContentResolveError = 'blaze-content-resolve-error',
onWidgetDataLoadStarted = 'blaze-widget-data-load-started',
onWidgetDataLoadCompleted = 'blaze-widget-data-load-completed',
onWidgetPlayerDismissed = 'blaze-widget-player-dismissed',
onWidgetTriggerCTA = 'blaze-widget-trigger-CTA',
// Deprecated - These events will be removed in future versions. Use the corresponding events above.
onStoryPlayerDidAppear = 'blaze-story-player-did-appear', // Deprecated: Use onPlayerDidAppear
onStoryPlayerDismissed = 'blaze-story-player-dismissed', // Deprecated: Use onPlayerDismissed
onWidgetStoryPlayerDismissed = 'blaze-widget-story-player-dismissed', // Deprecated: Use onWidgetPlayerDismissed
}Updated 2 days ago
