Deep Links
Universal Links, Android App Links, URI schemes, and hosted association files.
`mach deeplink setup` configures the project-side pieces needed for iOS Universal Links, Android App Links, app URI schemes, and optional Smart App Banner metadata. It can also enable iOS Web Credentials for HTTPS OAuth callbacks and Android Login Credentials for website password and passkey sharing. The command reads from `mach.config.json` first. When Mach Web Hosting is configured, it offers the stable Production Mach address, active Production customer domains, or a manual HTTPS URL—never a temporary preview or Staging address.
Mach Web Hosting setup
mach deeplink setup
# Choose project.getmach.dev, an active customer domain, or manual URL
mach web deploy --output dist
mach deeplink verify --live
Command flags always win over config. Existing `deepLinks` values, profile-specific fields, root config, Expo config inference, and then prompts are used as fallbacks. A hostname is compiled into Android and iOS configuration; rerun setup and release a new native build when you later switch from the Mach address to a customer domain.
What Setup Writes
mach.config.json
Adds a compact deepLinks block. Values already available from root config or the selected profile are not duplicated.
Apple AASA
Writes apple-app-site-association files under the selected output directory, including .well-known copies.
Android assetlinks.json
Writes .well-known/assetlinks.json with package name and SHA256 certificate fingerprints. mach web deploy includes generated association files in each static release, even when its output directory differs from the deep-link source directory.
iOS web credentials
When enabled, adds webcredentials:<domain> to Expo and a webcredentials app entry to the Apple AASA file for HTTPS OAuth callbacks.
Android login credentials
When enabled, adds delegate_permission/common.get_login_creds to assetlinks.json for Credential Manager password and passkey sharing.
Expo plugin
Expo projects are wired through @radhya/mach/expo-plugin when @radhya/mach is installed locally.
Flutter native setup
Flutter projects receive idempotent Android App Links, iOS Associated Domains, Xcode entitlement wiring, and the custom URI scheme. Dart routing remains app-owned.
Typical config
{
"scheme": "example",
"ios": {
"bundleIdentifier": "com.example.app",
"appleTeamId": "ABCDE12345",
"ascAppId": "1234567890"
},
"android": {
"package": "com.example.app"
},
"deepLinks": {
"baseUrl": "https://app.example.com",
"ios": {
"webCredentials": true
},
"android": {
"loginCredentials": true
},
"web": {
"outputDir": "deep-links"
}
}
}
Expo Projects
Expo is the fully automated path. Setup installs `@radhya/mach` as a dev dependency when needed and inserts the packaged config plugin into `app.json`, `app.config.json`, `app.config.js`, or normal `app.config.ts` plugin arrays.
Expo setup
mach deeplink setup --framework expo --base-url https://app.example.com
# CI or non-interactive runs
mach deeplink setup --yes --framework expo --base-url https://app.example.com
Plugin entry
plugins: ['@radhya/mach/expo-plugin']
The plugin reads `mach.config.json` at Expo config resolution time and applies `scheme`, `extra.deepLinkBaseUrl`, `ios.associatedDomains`, and `android.intentFilters`. When iOS Web Credentials is enabled, the associated domains also include `webcredentials:<domain>`. It does not create a second `mach.deep-links.json` file.
If package installation is declined or unavailable, setup falls back to `./plugins/withMachDeepLinks` so EAS/Expo prebuild can still resolve the plugin from the app project.
Bare React Native Projects
For vanilla React Native, setup currently generates `mach.config.json` metadata and hosted association files, then verification checks your native project. Mach does not automatically patch `AndroidManifest.xml`, Xcode entitlements, or `.pbxproj` wiring yet; keep those native changes under your normal code review process.
React Native setup
mach deeplink setup --framework react-native --base-url https://app.example.com
mach deeplink verify
Android manifest shape
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="app.example.com" />
</intent-filter>
iOS associated domains
applinks:app.example.com
# Add this when you enable iOS Web Credentials
webcredentials:app.example.com
Verification warns when native Android or iOS entries are missing. Treat that as a checklist for manual native changes until native patching is shipped.
Hosting Requirements
Host the generated files at the exact app domain. Apple AASA endpoints must be reachable over HTTPS and should not redirect. Android allows assetlinks redirects more often, but direct HTTPS hosting is still the safest setup.
Required URLs
https://app.example.com/.well-known/apple-app-site-association
https://app.example.com/apple-app-site-association
https://app.example.com/.well-known/assetlinks.json
AASA limit
Apple requires the uncompressed apple-app-site-association file to stay under 128 KB.
Android fingerprints
Add every release signing SHA256 fingerprint that should verify Android App Links.
Credential sharing
Enable the optional iOS or Android prompt only when your app needs HTTPS OAuth callbacks or website password/passkey sharing.
Verification
Hosted files over HTTPS
mach deeplink verify --live
Android device checks
mach deeplink verify --android-device
A passing verification confirms the App Link association files, plus iOS Web Credentials or Android Login Credentials entries whenever you enabled them during setup.
See Configuration for the `deepLinks` field reference.