Link Navigation Request Message
Overview
The Link Navigation Request message is sent only when a partner specifies overrideLinkNavigation as true on their launcher (see Integration Launcher Options). Once this has been opted in you will receive a LINK_NAVIGATION_REQUEST
message on subscribing to a Selection or a Placement.
For example, after opting into overrideLinkNavigation on the launcher, you can subscribe with the following code to receive events each time a user clicks on a link to navigate to another page.
// Rokt script already loaded
const selection = await launcher.selectPlacements({
attributes: {
// attributes required by Rokt to retrieve the catalog items
eventId: "eventId",
venueName: "venueName",
// any additional attributes
email: "email",
},
});
selection.on("LINK_NAVIGATION_REQUEST").subscribe((event) => {
// Handle the navigation request using the url property
window.open(event.body.url);
});
Properties
url
• url: string
If a customer clicks on an offer link when overrideLinkNavigation is enabled, they will not automatically open a new browsing tab. Instead the Rokt SDK will send an event containing the url
as a string that needs to be handled by the partner. This url should be immediately opened in the browsing context required (web view or native browser as agreed), to avoid any degration to the customer experience.
iOS WKWebView
If you are using WKWebView within your iOS application you can use overrideLinkNavigation
and LINK_NAVIGATION_REQUEST
to direct your users to the appropriate location for your desired user experience. This is good for where you have an entirely web view user journey and need to direct the user to their standard browser or similar.
In the example below we use roktMessageHandler
as the shared message name used between the Web and iOS implementation.
JS implemenation
When creating your launcher you'll need to specify overrideLinkNavigation
which is necessary to stop Rokt from immediately opening the URL with window.open()
.
// Rokt script already loaded
const launcher = await window.Rokt.createLauncher({
accountId: "rokt-account-id",
overrideLinkNavigation: true
});
Additionally you need to listen for the event LINK_NAVIGATION_REQUEST
and specify how to handle opening the URL.
selection.on("LINK_NAVIGATION_REQUEST").subscribe((event) => {
// Handle the navigation request using the url property
// This will be intercepted by WKWebView's WKScriptMessageHandler protocol
window.webkit?.messageHandlers?.roktMessageHandler?.postMessage(body.url);
});
iOS implementation
In the below iOS implemenation we are using WKWebView to register the userContentController
for the agreed message name roktMessageHandler
. Then we implement the protocol WKScriptMessageHandler
with the function userContentController
to listen to URL open events that match the agreed message name and then choose how to open them.
func webViewSetup() {
let webView = WKWebView()
// Rest of your WKWebView setup here
// Register the listener for the agreed message name
webView.configuration.userContentController.add(implOfWKScriptMessageHandler, name: "roktMessageHandler")
}
public func userContentController(_ contentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "roktMessageHandler" {
if let urlString = message.body as? String,
let url = URL(string: urlString) {
// Choose where to open the URL
if #available(iOS 10.0, *) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.openURL(url)
}
}
}
}
Android WebView
In the example below we use roktLinkOpener
as the shared message name used between the Web and Android implementation.
JS Implementation
When creating your launcher you'll need to specify overrideLinkNavigation
which is necessary to stop Rokt from immediately opening the URL with window.open()
.
// Rokt script already loaded
const launcher = await window.Rokt.createLauncher({
accountId: "rokt-account-id",
overrideLinkNavigation: true
});
Additionally you need to listen for the event LINK_NAVIGATION_REQUEST
and specify how to handle opening the URL.
selection.on("LINK_NAVIGATION_REQUEST").subscribe((event) => {
// Handle the navigation request using the url property
if (window.roktLinkOpener && typeof window.roktLinkOpener.openLink === "function") {
window.roktLinkOpener.openLink(url);
}
});
Android implementation
fun webViewSetup() {
// Register the listener for the agreed message name
webView.addJavascriptInterface(WebAppInterface(this), "roktLinkOpener")
}
class WebAppInterface(private val activity: AppCompatActivity) {
@JavascriptInterface
fun openLink(url: String) {
// Choose where to open the URL
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
activity.startActivity(intent)
}
}
Android and iOS JS detection
The above Android and iOS examples can be blended into a single handler that retains the same agreed message names of roktMessageHandler
and roktLinkOpener
for iOS and Android respectively.
selection.on("LINK_NAVIGATION_REQUEST").subscribe((event) => {
const url = event.url;
// iOS detection: WKWebView message handler exists
if (window.webkit && window.webkit?.messageHandlers && window.webkit?.messageHandlers?.roktMessageHandler) {
window.webkit?.messageHandlers?.roktMessageHandler?.postMessage(body.url);
}
// Android detection: injected JavaScript interface exists
else if (window.roktLinkOpener && typeof window.roktLinkOpener.openLink === "function") {
window.roktLinkOpener.openLink(url);
}
// Fallback
else {
// Handle URL some other way
}
});