Links & routing
How the SDK handles outbound links tapped inside chat — an in-app browser by default, or your own native routing.
When a shopper taps a product or any other link inside the chat, the web widget
hands the outbound URL to the native SDK over the bridge (the openExternalUrl
action). The URL is passed verbatim, with its full query string intact —
including any attribution parameters (utm_* or loops_ref) the runtime appended.
Default: in-app browser
Out of the box the SDK opens the URL in an in-app browser —
SFSafariViewController on iOS. This keeps the shopper in your app, and because the
full query string is preserved, the destination loads in a real web context where
your analytics (e.g. GTM) fire normally.
_blank / window.open links are intercepted and routed the same way — the SDK
never spawns a second WebView or leaves your app unexpectedly.
Override: your own routing
To send links somewhere else — a native product screen, the system browser, or a deep link into another app — implement the open-URL callback. When you handle it, your routing takes precedence and the in-app browser default does not run.
UIKit, via LoopsAIChatDelegate:
func loopsAIChat(_ vc: LoopsAIChatViewController,
didRequestOpenURL url: URL) {
router.open(url)
}SwiftUI, via the onOpenURL modifier:
LoopsAIChatView(config: config)
.onOpenURL { url in
router.open(url)
}If you route a link into a native screen instead of a web page, the
attribution parameters in the URL (utm_* / loops_ref) no longer reach web
analytics — there is no web page load to run GTM. See
Conversion attribution for
what this means for measurement.
Next: Analytics.