Prerequisites
Your app must be configured to handle deep links on both Android and iOS.Register the custom URL scheme
ReplaceAPP_TOKEN with your app’s Userpilot token, which you can obtain from your Environments Page. For example, if your token is NX-12345678, your scheme value is userpilot-nx-12345678.
For iOS, uri-scheme writes the Info.plist entry for you:
android/app/src/main/AndroidManifest.xml on the main Activity. Set android:launchMode="singleTop" so an incoming link is delivered to the running Activity rather than creating a second instance of it:
android:host="sdk" in the filter. The native Userpilot SDK validates the URL host before handling a preview or notification link.
Run npx cap sync after editing native configuration.
Handle the custom URL scheme
Listen for theappUrlOpen event from @capacitor/app and pass each URL to Userpilot.didHandleURL.
Supported links
The SDK only claims a URL when the scheme matches your token and the host issdk. Every other URL is passed back to your app.
On iOS, notification taps are handled natively by the SDK and never reach the
appUrlOpen event, so follow Push Notifications for that setup.Preview an experience with a QR code
Userpilot can render a draft experience on your device before you publish it, so you can check layout, copy, and behavior on a real screen. Preview is supported for Flows and Surveys. The preview is delivered over the custom URL scheme. It works once your app is installed on the device and the scheme is registered and handled as described above.1
Open the experience
Open a Flow or Survey in the Experience Builder and enter Edit Mode.
2
Start the preview
Select Preview in the top-right corner of the builder. A popup with a QR code appears.
3
Scan the QR code
Scan the code with your device camera. Your app opens and the experience appears.
- You don’t need to apply or save your changes before previewing them.
- The experience doesn’t need to be live.
- A preview bypasses the experience’s targeting and frequency settings, so it appears even when the current user wouldn’t normally qualify for it.
- Once you close the experience, the app resumes normal behavior.
Test push notifications
You can send a test push to a specific user from the Userpilot dashboard and verify delivery and tap handling on a real device without sending anything to your wider audience. The notification doesn’t need to be live, so you can test it while it’s still a draft.- Test pushes work in both the staging and production environments.
- Test pushes are not counted as real sends, and they’re excluded from analytics.
- Test pushes bypass the notification’s targeting and frequency settings.
appUrlOpen handling there. If the notification appears but tapping it does nothing, the scheme registration is the first thing to check.
Test a deep link from the command line
Open a link directly to confirm your scheme is registered and your listener runs, without going through the Builder:12345 with a real experience ID.
Troubleshooting
Nothing happens when I scan the QR code
Nothing happens when I scan the QR code
Confirm the registered scheme matches your token exactly, lowercased. Then confirm you ran
npx cap sync and rebuilt, since a scheme is native configuration and won’t appear in an older build. Verify with the commands above.My own link handling never runs
My own link handling never runs
You’re most likely not awaiting
didHandleURL. It returns a promise that resolves to { handled: boolean }, so if (!result) is always false against the promise object. Destructure handled from an awaited call, as shown above.The app opens but the experience doesn't appear
The app opens but the experience doesn't appear
The OS routed the link, so registration is correct. Check that
AppUrlListener is mounted at the root of your app rather than inside a page that may not be rendered when the link arrives, and confirm the SDK is initialized with the same token that generated the QR code.Tapping an Android push notification does nothing
Tapping an Android push notification does nothing
Notification taps travel over this same URL scheme on Android, so they need the intent filter and the
appUrlOpen forwarding described above. Confirm the host in your filter is exactly sdk.Preview works in production but not in staging
Preview works in production but not in staging
Each environment has its own token, and the scheme follows the token. Confirm the staging build registers the scheme for the token it initializes the SDK with.