Testing Universal Links and App Links During Development
Deep links look like: plumvillage://extras/playlists
and continue to work.
We now prefer to use Universal Links (iOS) and App Links (Android) using the website https://web.plumvillage.app
. These links will open directly in the mobile app if installed, or fall back to the web version if the app is not installed. The path of these URLs (eg /item/how-to-dwell-happily-in-the-present-moment-1
) is handled in the mobile app in the same way as deep links.
We previously used Firebase Dynamic Links (e.g., https://link.plumvillage.app/drwK
) but Firebase Dynamic Links is being shut down as of August 25, 2025.
Key differences:
- Firebase Dynamic Links: Worked even when app wasn't installed by redirecting to app stores
- Universal/App Links: Only work when app is installed, but provide better UX and are linked to a website that works as fallback
- Deep Links: Custom URL scheme that only works when app is installed, no web fallback
Configuration Requirements
Universal Links and App Links have been configured for the web.plumvillage.app
domain:
iOS Universal Links
- Associated domains entitlement configured
apple-app-site-association
file hosted
Android App Links
- Intent filters with
android:autoVerify="true"
configured assetlinks.json
file hosted
The configuration files and app associations are already set up. No additional configuration is required for development.
Unit Tests
The deep linking mechanism will map a path to a route state, and vice versa (route state to a path).
It is easy to break this mapping if editing DeepLinkingConfig.ts
, so please add a unit test for each new path to deep-link-tests.ts. Run the tests with yarn test
. This ensures that the new URLs work as expected, but also that the existing URLs continue to work as expected.
You can usually copy and edit another unit test but if doing something more complex you may need to intercept the navigation state and print with console.log(JSON.stringify(state))
in DeepLinkingConfig.ts
.
Testing on Device
Unit tests are the quickest way to check quickly during development, but once you are fairly sure it is working correctly, it is wise to test on a device.
Android
App Links and deep links will launch the debug build if release build is not installed on the test device. App Links may or may not work on Android emulators, so test on a real device if you have problems on the emulator.
Deep link: npx uri-scheme open plumvillage://extras/playlists --android
App Link: npx uri-scheme open https://web.plumvillage.app/extras/playlists --android
iOS
You can test deep links with a normal debug build: npx uri-scheme open plumvillage://extras/playlists --ios
For Universal Links:
- Change build configuration to Release
- Enable verbose logging in release mode
- Test with:
npx uri-scheme open https://web.plumvillage.app/extras/playlists --ios
- Revert these changes when done
Alternative Testing Methods
Besides using npx uri-scheme
, you can test Universal Links and App Links using these methods:
iOS Testing
Share and tap method (recommended):
- Use the share button in the app to generate a link like
https://web.plumvillage.app/item/-LEf3l4wwkuXSXQwoiq7
- Send the link via Messages, Signal, WhatsApp, Notes, Email, or others
- Tap the link from the message - this should open directly in the app (seamless transition, no browser)
- This tests the actual Universal Link behavior that users experience
Browser testing:
- Open Safari, Chrome, or Firefox on your iOS device
- Navigate to a shared URL or manually type
https://web.plumvillage.app/extras/playlists
- Links typed directly into browser address bars will open in the browser
- This is also the web experience for users without the app
- Some browsers may also show an "open in app" option (UX differs by browser)
macOS Safari:
- The app runs as a "built for iPad" app on macOS
- Universal Links work similarly - direct opening in app when tapped from other apps, web fallback when typed in browser
Android Testing
Share and tap method (recommended):
- Use the share button in the app to generate a link like
https://web.plumvillage.app/item/-LEf3l4wwkuXSXQwoiq7
- Send the link via Messages, Signal, WhatsApp, Google Keep, Email, or others
- Tap the link from the message - this should open directly in the app (no disambiguation dialog)
- This tests the actual App Link behavior that users experience
Browser testing:
- Open Chrome, Firefox, or Samsung Internet on your Android device
- Navigate to a shared URL or manually type
https://web.plumvillage.app/extras/playlists
- Links typed directly into browser address bars will open in the browser
- Some browsers may also show an "open in app" option (UX differs by browser)
URL Pattern Examples
The app supports various URL patterns that map to different screens and navigation states:
Homepage
- URL:
https://web.plumvillage.app/
orhttps://web.plumvillage.app/home
- Behavior: Opens the app to the main home screen
Tab Navigation
- URL:
https://web.plumvillage.app/meditations
- Behavior: Opens the app directly to the Meditations tab
- Other tabs: Replace
meditations
with other tab names liketeachings
,extras
, etc.
Folder Navigation
- URL:
https://web.plumvillage.app/meditations/start-here
- Behavior: Opens the app to the "Start Here" folder within the Meditations tab
- Pattern:
https://web.plumvillage.app/[tab]/[folder-slug]
Individual Items
- URL:
https://web.plumvillage.app/item/how-to-dwell-happily-in-the-present-moment-1
- Behavior: Opens the app directly to the specific meditation, teaching, or content item
- Pattern:
https://web.plumvillage.app/item/[item-slug-or-id]
Special Pages
- URL:
https://web.plumvillage.app/latest-updates
- Behavior: Opens the app to the Latest Updates screen