Linking Module
The Linking module opens URLs outside the app’s main web view and tells your web code when the app was opened through a link.
import { Linking } from '@shopgate/native-modules';Example React component
Section titled “Example React component”import { Linking } from '@shopgate/native-modules';
export function ExternalLinkButton() { return ( <button type="button" onClick={() => Linking.openPageExtern({ src: 'https://example.com' })}> Open website </button> );}openPageExtern(params)
Section titled “openPageExtern(params)”await Linking.openPageExtern({ src: 'https://example.com' });| Name | Type | Required | Description |
|---|---|---|---|
src |
string |
yes | URL to open externally. |
Returns Promise<void>.
Events
Section titled “Events”universalLinkOpened
Section titled “universalLinkOpened”Fires when the app is opened through an HTTPS link to your domain (Universal Link on iOS, App Link on Android). The full URL, including its query string, is available as event.detail.link.
deepLinkOpened
Section titled “deepLinkOpened”Fires when the app is opened through a link with a custom URL scheme (for example myshop://…). The URL is available as event.detail.link.
Handling incoming links
Section titled “Handling incoming links”What the app does
Section titled “What the app does”- The app does not navigate the web view to the link. It loads its regular start URL and reports the link as an event. Your web code decides what to do with it, usually navigate to it.
- App not running (cold start): the event is held back until your page signals that it is ready (see below), then delivered.
- App in the background: the event is delivered right away to the page that is currently open.
- The URL is passed on unchanged, including all query parameters (for example
utm_*or affiliate click IDs). - Two special cases: if the URL has an
appLinkquery parameter, its value is passed aslinkinstead of the full URL. If the URL contains/appstore,linkis/.
Signal that your page is ready
Section titled “Signal that your page is ready”The app holds back all module events until the page sends the onload command. Shopgate PWA does this automatically. Any other web app must send it itself, after registering its event listeners:
window.SGJavascriptBridge?.dispatchCommandsForVersion([{ c: 'onload' }], '9.0');Without this command, universalLinkOpened, deepLinkOpened and the events of other modules are never delivered. The same command also hides the native splash screen once the page has finished loading.
Example: open the link and keep its tracking parameters
Section titled “Example: open the link and keep its tracking parameters”Run this as early as possible during page start, in your main bundle, not in a lazily loaded component.
import { isAvailable, Linking } from '@shopgate/native-modules';
// Hosts the app is allowed to navigate toconst ALLOWED_HOSTS = ['www.example.com', 'example.com'];
function handleIncomingLink(event) { const link = event?.detail?.link; if (!link) return;
let target; try { target = new URL(link, window.location.origin); } catch { return; }
// Only follow links to our own website if (!ALLOWED_HOSTS.includes(target.hostname)) return;
// Already on this URL -> nothing to do if (target.href === window.location.href) return;
// Full page load, so analytics and affiliate tags run as on a regular visit window.location.assign(target.href);}
if (isAvailable()) { Linking.addEventListener('universalLinkOpened', handleIncomingLink); Linking.addEventListener('deepLinkOpened', handleIncomingLink);
// Listeners are in place -> let the app deliver queued events window.SGJavascriptBridge?.dispatchCommandsForVersion([{ c: 'onload' }], '9.0');}Custom scheme links (deepLinkOpened) usually need to be mapped to an HTTPS URL of your website first. Adjust handleIncomingLink to your URL structure.
Tracking and campaign parameters
Section titled “Tracking and campaign parameters”- The web view has its own cookie storage, separate from the device browser. Cookies set by a tracking provider in the browser are not available in the app. Campaign data only reaches your website through the URL, so load the URL from
event.detail.linkunchanged. - With a full page load, existing tags (analytics, affiliate, consent) handle the parameters exactly as on a regular visit. No app-specific tracking code is needed.
- On a cold start, the start page loads first and the link second. Expect one additional page view without parameters.
- The app does not pass opened links on to native tracking SDKs. To see link opens in AppsFlyer, log an event from your web code, see AppsFlyer Analytics.
When the app does not open
Section titled “When the app does not open”The link opens in the browser instead of the app when:
- the URL is typed into the browser’s address bar (iOS),
- the link points to the same domain the user is already on in the browser (iOS),
- the link is tapped in the built-in browser of a social media app,
- the app is not installed,
- the path is not included in the app’s link configuration (
apple-app-site-associationon iOS,assetlinks.jsonon Android).
Links that redirect through a tracking domain before reaching your domain usually open the app, but test this with a real link.
Testing
Section titled “Testing”Test every case twice: once with the app closed (cold start) and once with the app in the background.
No extra tools are needed. Install the app on an iPhone, send the link to yourself (for example in Notes or Messages) and tap it. Do not type the URL into Safari’s address bar, iOS does not open the app from there.
Android with adb
Section titled “Android with adb”adb (Android Debug Bridge) is a command line tool that controls an Android device connected to your computer. With it, you can open a link on the device exactly as if the user had tapped it, and repeat this as often as you need with different parameters.
Setup (once):
-
Install adb on your computer. It is part of the Android SDK Platform Tools. Either install Android Studio or download the Platform Tools on their own. On macOS with Homebrew:
Terminal window brew install --cask android-platform-tools -
Enable USB debugging on the phone. Open Settings › About phone and tap Build number seven times to unlock the developer options. Then turn on Developer options › USB debugging. The menu names differ slightly between manufacturers.
-
Connect the phone via USB and confirm the prompt Allow USB debugging? on the phone.
-
Check the connection. The phone must be listed with the status
device. If it showsunauthorized, confirm the prompt on the phone.Terminal window adb devices -
Install the app on the phone (from Google Play or as a test build).
Open a link:
adb shell 'am start -a android.intent.action.VIEW -d "https://www.example.com/?utm_source=test&utm_medium=app"'Keep both pairs of quotes: single quotes around the whole command and double quotes around the URL. The command runs in the phone’s shell, where an unquoted & would cut off the URL after the first parameter.
If the link opens in the browser instead of the app, check whether Android has verified your domain for the app (Android 12 and later). The domain must show the status verified:
adb shell pm get-app-links <package name of the app>To find the package name: adb shell pm list packages | grep -i <part of the app name>.
Looking inside the web view
Section titled “Looking inside the web view”If web view debugging is enabled for your app build, you can inspect the page in the app with the browser developer tools, for example to check window.location.href, cookies and console output of your link handler:
- Android: open
chrome://inspectin Chrome on your computer while the phone is connected. - iOS: turn on Settings › Apps › Safari › Advanced › Web Inspector on the iPhone, connect it to a Mac and open the page in Safari’s Develop menu.

