JS Bridge - Internal
Art. no. 216626341
What is JS Bridge?
A common problem when adding a custom tab with non-Prenly content has been that this content resides on a separate web page and cannot communicate with the Prenly content.
To solve that challenge, we've created an API called JS Bridge that can be used to provide your users with a seamless app experience.
What is it used for? / What are its functions?
When you implement JS Bridge on your web page, the web pages in your custom tabs will be able to communicate directly with the Prenly part of the app.
For the login, this means that the user only needs to login once, whether it is from the Prenly section or from your custom web content tabs. Even users' consent settings will be synchronized between Prenly and your web application.
Through JS Bridge, users can also play audio found on your custom pages directly in our built-in audio player.
For the user, the experience becomes an integrated app that can offer several different services, for example the latest news, other customized web content, an online store or a crossword portal.
Technical details
JS Bridge - JavaScript API specification
Public API: JavaScript functions that the web page may run
Functions
Login
Trigger a login flow in the app.
prenlyApp.login(): Promise<UserDataJwt|RequestError>
Logout
Trigger a logout flow in the app.
prenlyApp.logout(): Promise<UserDataJwt|RequestError>
Show no access alert
Triggers show no access alert flow in the app.
prenlyApp.showNoAccessAlert(): Promise<void>
Get user JWT
Retrieve information about the user as a Jwt.
prenlyApp.getUserJwt(): Promise<UserDataJwt|RequestError>
Get user consent
Retrieve the current consent that the user granted, or null if no CMP is used.
prenlyApp.getUserConsent(): Promise<UserConsent|null|RequestError>
Play pause audio
Add audio to native player and start playing or pause it if it is playing.
prenlyApp.playPauseAudio(AudioData): Promise<void|RequestError>
Add or remove audio from queue
Add/remove audio to native audio queue.
prenlyApp.queueDequeueAudio(AudioData): Promise<void|RequestError>
Get audio status
Retrieve status of audio initialized by the SDK.
prenlyApp.getAudioStatus(AudioId): Promise<AudioStatus|RequestError>
Show user consent dialog
Triggers show consent dialog flow in the app.
prenlyApp.showUserConsentDialog(): Promise<void|RequestError>
Event listeners
Start listening
prenlyApp.on(EventType, (current: Object, previous?: Object) => void): void
Stop listening
To stop a single listener, the reference to the callback handler function used as argument in prenlyApp.on must be included:
prenlyApp.off(EventType, handler): void
To stop listening to all events for a type within the prenlyApp instance:
prenlyApp.off(EventType): void
Events
Types
Type | Data | Description |
userConsentChange | UserConsent | Triggers when the user consent changes. |
userLogin | UserDataJwt | Triggers when the user logs in. |
userLogout | UserDataJwt | Triggers when the user logs out. |
audioStatusChange | AudioStatus | Triggers when the status of audio initialized by the SDK is changed. |
Callback
Parameter | Description |
Parameter 1 | The response object of the current event. |
Parameter 2 | The response object of the previous event, or undefined when no previous event exists. |
Example
prenlyApp.on('userConsentChange', (data: UserConsent) => {
// ...
});
Request/Response data
UserDataJwt
{
jwt: string;
}
UserConsent
{
cmp: string;
prenly_purpose_grants?: {
functional: boolean;
analytical: boolean;
marketing: boolean;
};
tc_string?: string;
cmp_purpose_grants?: { [purpose: string]: boolean };
cmp_vendor_grants?: { [vendor: string]: boolean };
}
AudioId
{
id: string;
}
AudioData
{
id: string;
audio_url: string;
image_url?: string;
title: string;
description: string;
duration: number; // in seconds
}
AudioStatus
{
id: string;
status:
| 'playing'
| 'paused'
| 'loading';
queued: boolean;
}
RequestError
{
code:
| 'rejected'
| 'feature_disabled'
| 'login_failed'
| 'logout_failed'
| 'play_pause_audio_failed'
| 'queue_dequeue_audio_failed';
message?: string;
}
Internal message interface
The communication layer interface between JavaScript and the native apps.
Types overview
Type | Kind | Public interface |
prenly_login | request | login() |
prenly_logout | request | logout() |
prenly_get_user_jwt | request | getUserJwt() |
prenly_show_no_access_alert | request | showNoAccessAlert() |
prenly_get_user_consent | request | getUserConsent() |
prenly_play_pause_audio | request | playPauseAudio(AudioData) |
prenly_get_audio_status | request | getAudioStatus(AudioId) |
prenly_show_user_consent_dialog | request | showUserConsentDialog() |
prenly_queue_dequeue_audio | request | queueDequeueAudio(AudioData) |
prenly_on_user_consent_change | event | userConsentChange |
prenly_on_user_login | event | userLogin |
prenly_on_user_logout | event | userLogout |
prenly_on_audio_status_change | event | audioStatusChange |
Requests
A two-way-communication initialized from the website.
A request consists of an object with the following properties:
{ type: string, requestId: string, data?: object }
The native app then send the object back in response including the new data object:
{ type: string, requestId: string, data: object }
Request data
Type | Request data | Response data |
prenly_login | - | UserDataJwt |
prenly_logout | - | UserDataJwt |
prenly_get_user_jwt | - | UserDataJwt |
prenly_get_user_consent | - | UserConsent |
prenly_play_pause_audio | AudioData | - |
prenly_queue_dequeue_audio | AudioData | - |
prenly_get_audio_status | AudioId | AudioStatus |
prenly_show_no_access_alert | - | - |
prenly_show_user_consent_dialog | - | - |
Error handling
In order for requests to trigger the reject function of the client Promise, an error object should be included in the response:
{ type: string, requestId: string, error: RequestError }
Example
Get user consent request:
{
type: 'prenly_get_user_consent',
requestId: 'some-random-id'
}
Get user consent response:
{
type: 'prenly_get_user_consent',
requestId: 'some-random-id',
data: {
cmp: 'some-cmp-provider',
prenly_purpose_grants: {
functional: true,
analytical: true,
marketing: false
},
cmp_vendor_grants: {
some_vendor_1: true,
some_vendor_2: false
}
}
}
Events
A one-way-communication initialized from the native app and picked up by the listener on the website.
An event consists of an object with the following properties:
{ type: string, data: object }
Event data
Type | Response data |
prenly_on_user_consent_change | UserConsent |
prenly_on_user_login | UserDataJwt |
prenly_on_user_logout | UserDataJwt |
prenly_on_audio_status_change | AudioStatus |
Example
On user consent change event:
{
type: 'prenly_on_user_consent_change',
data: {
cmp: 'some-cmp-provider',
prenly_purpose_grants: {
functional: true,
analytical: true,
marketing: false
},
cmp_vendor_grants: {
some_vendor_1: true,
some_vendor_2: false
}
}
}
How is JS Bridge implemented? - What actions are needed from us?
Activate JS Bridge in Superadmin:
- In clients PWS, click the Ninja → Applications
- Choose Application and click Edit
- Scroll down and click the box next to Js Bridge, and Save.
Supply the customer with this documentation.
How is JS Bridge implemented? - What actions are needed from the customer?
To allow your custom web content to communicate with the Prenly app, follow these steps:
1. Install the JS Bridge Library
JS Bridge is a custom-built JavaScript library that needs to be installed on the webpage displayed in the Prenly app.
Visit GitHub and npm to find instructions on the installation.
https://github.com/Textalk/prenly-js-bridge/
https://www.npmjs.com/package/prenly-js-bridge
2. Notify us to activate the feature
Once the JS Bridge is added to your page, let us know—we’ll activate the integration on the Prenly side to complete the setup.
3. Use JS Bridge
Once installed, you can use the JavaScript functions provided by the library to interact with the Prenly app. For example:
• Trigger login sync
• Share consent settings
• Use the in-app audio player for media on your page
For a complete list of the actions currently supported by JS Bridge, please see our technical specification.