All articles

Technical

Managing Asset Links for Staging and Production TWAs

October 11, 2026 · 5 min read

The Necessity of Multi-Environment Asset Links

When launching a Trusted Web Activity (TWA) on the Google Play Store, the connection between your Android wrapper and your Progressive Web App (PWA) relies on Digital Asset Links. This association is verified through a file named assetlinks.json, hosted in the .well-known directory of your domain. While establishing this connection for a single production app is straightforward, professional development workflows require multiple environments, including local development, staging, beta, and production.

A production TWA must never point to a staging web environment, nor should a local debug APK bypass validation and display the URL address bar. To maintain a seamless, brand-focused user experience across all testing and deployment phases, developers must configure a multi-statement assetlinks.json file. This guide explains how to map multiple package names, hostnames, and keystore fingerprints to keep your environments isolated and secure.

Understanding the Three Mapping Variables

To configure Digital Asset Links for staging and production, you must manage three distinct variables for each build variant of your application:

  • The Package Name: The unique identifier of your Android app. Typically, you will use different package names to allow side-by-side installations on testing devices, such as com.example.app for production and com.example.app.staging for testing.
  • The SHA-256 Fingerprint: The cryptographic signature of the signing key. Your local debug build, your staging APK, and your final Google Play production app will all have different SHA-256 signatures.
  • The Web Hostname: The domain or subdomain where the PWA is hosted. For example, your staging app points to staging.example.com, while your production app points to example.com.

Because Google Play requires a strict match between the package name, the SHA-256 fingerprint, and the domain, any discrepancy will fail verification. A failed verification triggers the fallback custom tab behaviour, which exposes the browser URL bar to your users.

Structuring a Multi-Statement assetlinks.json File

The assetlinks.json file is a JSON array that can hold multiple statements. You do not need separate files for your staging and production sites unless they are hosted on entirely different subdomains. If they share the same domain or if you want to support cross-environment verification, you can define multiple statements in a single file.

Here is an example of a multi-statement configuration that declares associations for a local debug build, a staging app, and a production app. It allows different keys to verify against the respective hostnames:

[ { "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.app.debug", "sha256_cert_fingerprints": ["AA:BB:CC:DD:EE:FF:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:11:22:33:44:55:66:77:88:99:00"] } }, { "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.app.staging", "sha256_cert_fingerprints": ["BB:CC:DD:EE:FF:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:11:22:33:44:55:66:77:88:99:00:AA"] } }, { "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.app", "sha256_cert_fingerprints": ["CC:DD:EE:FF:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:11:22:33:44:55:66:77:88:99:00:AA:BB"] } } ]

In this setup, the operating system verifies each application against the JSON array. When the staging app launches, the system checks the file at staging.example.com/.well-known/assetlinks.json, finds the matching package name and fingerprint, and hides the URL bar. When the production app launches, it queries example.com/.well-known/assetlinks.json, validating successfully.

Managing Developer Keystores and SHA-256 Fingerprints

One of the most common mistakes when managing multiple environments is forgetting to register all signing signatures. Every developer machine generates a unique local debug keystore (debug.keystore). If you have three developers working on the TWA, you must add the SHA-256 fingerprints of all three local debug keystores to your development or staging assetlinks.json file. Otherwise, developers will see the URL bar when testing local builds on physical devices.

For production, you must also account for Google Play App Signing. When you upload your signed Android App Bundle (AAB) to the Play Console, Google replaces your upload signature with a final production signing key. Therefore, your production assetlinks.json file must include both your upload key fingerprint and the Google Play App Signing key fingerprint.

Multi-Environment Verification Matrix

To ensure flawless delivery, organise your settings using the following structured approach:

EnvironmentPackage NameSigning Key SourceTarget HostnameAsset Links Location
Local Devcom.example.app.debugLocal debug.keystore (per developer)localhost or local IPlocalhost/.well-known/assetlinks.json (or bypassed via Chrome flags)
Stagingcom.example.app.stagingStaging/Ad-hoc release keystorestaging.example.comstaging.example.com/.well-known/assetlinks.json
Productioncom.example.appGoogle Play App Signing Keyexample.comexample.com/.well-known/assetlinks.json

Best Practices for Domain and Subdomain Isolation

To maintain high security and avoid cross-environment data contamination, follow these strict routing and configuration rules:

  • Isolate Subdomains: Keep your staging assetlinks.json completely isolated on staging.example.com. Do not list production SHA-256 keys on your staging domain, and do not list staging or debug keys on your production domain. This prevents a compromised testing app from acting as a verified handler for your production domain.
  • Automate Fingerprint Extraction: Use the Java keytool command-line utility to extract the SHA-256 fingerprint from your keystore files rather than attempting to copy them from incomplete logs. Run the command: keytool -list -v -keystore your-keystore.jks to obtain the precise SHA-256 hex string.
  • Use Content-Type Headers: Ensure your web server serves the assetlinks.json file with the exact Content-Type header of application/json. If the server delivers the file as text/plain or HTML, the Android system web-to-app verification mechanism will fail.
  • Set Cache Headers Correctly: The Android operating system aggressively caches the Digital Asset Links file to avoid repeating network requests. During active development or staging transitions, set short cache life headers (such as Cache-Control: max-age=300) to ensure changes to your fingerprints are updated swiftly on test devices.

By carefully isolating your package names, tracking your various development and play console keystores, and structuring your JSON statements cleanly, you ensure your TWA displays a perfectly branded, native interface across all development phases.

Ready to ship your Android app?

Paste your PWA URL, get a signed APK and a Google Play ready AAB in minutes.

Build my app