PWA manifest and assetlinks.json: get your web app ready for a Trusted Web Activity on Google Play

Updated Oct 27, 2026 · Pewterkit Guides

A Trusted Web Activity (TWA) is an Android app that opens your website full screen, which is how many web apps reach Google Play. Two files on your site make it work: a web app manifest that meets Chrome's install criteria, and /.well-known/assetlinks.json proving the app and the site belong together. If assetlinks.json is missing, redirected, served with the wrong type or lists the wrong signing fingerprint, the app opens with a browser bar at the top instead of full screen.

The manifest

Chrome's installability criteria on web.dev: a short_name or name, a 192px and a 512px icon, a start_url, a display of fullscreen, standalone, minimal-ui or window-controls-overlay, prefer_related_applications absent or false, and the site "served over HTTPS". Android's TWA overview says TWAs are expected to "meet the same Add to Home Screen requirements".

{
  "name": "Acme Rota",
  "short_name": "Rota",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#0f172a",
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
    { "src": "/icon-512-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
  ]
}

Link it from index.html with <link rel="manifest" href="/guides/manifest.webmanifest">, and put the file and icons in public/.

assetlinks.json

Android's Digital Asset Links file, at exactly https://<your-domain>/.well-known/assetlinks.json:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.acmerota.app",
    "sha256_cert_fingerprints": ["<SHA-256 of your app signing key>"]
  }
}]

Android's hosting rules:

  • "The assetlinks.json file is served with content-type application/json."
  • It "must be accessible over an HTTPS connection".
  • It "must be accessible without any redirects (no 301 or 302 redirects)", so serve it on the exact host the app opens, with no www hop.
  • With several hosts, "you must publish the assetlinks.json file on each domain."

In a Vite, Lovable or Bolt project, put it at public/.well-known/assetlinks.json. Then open the address in a browser and check it shows JSON, not your app's homepage.

The fingerprint that trips everyone up

With Play App Signing, Google signs the app you upload. Android's docs: "the certificate fingerprint produced by running keytool locally will usually not match the one on users' devices." Copy the SHA-256 from Play Console (Release > Setup > App signing, which also offers a ready-made Digital Asset Links snippet). Chrome's TWA guide recommends listing both the app signing key and your upload key, so installs from Play and local test installs both pass.

Chrome's guide also gives the symptom: if your app is "launching as a Chrome Custom Tab (with the browser bar visible)", the file likely lacks the right fingerprint; adb logcat shows messages such as "Statement failure matching fingerprint".

Building the Android app

Bubblewrap, listed by Android as "a NodeJs library / CLI to generate and build Trusted Web Activity projects", reads your manifest to create the project.

What Pewterkit Check looks for

A free check reads your linked web app manifest and lists any missing installability fields (name, 192 and 512 icons with purpose "any", start_url, display mode). It requests /.well-known/assetlinks.json once and flags invalid JSON, a redirect, or a content type other than application/json. The signing fingerprint lives in Play Console, so compare that part yourself.

FAQ

Why does my TWA show a URL bar?

Usually Digital Asset Links failed: the file is missing, redirected, served with the wrong type, or lists a fingerprint that doesn't match the installed app's signing key.

Which SHA-256 fingerprint goes in assetlinks.json?

For installs from Google Play, the app signing key certificate from Play Console. Chrome's guide suggests adding your upload key's fingerprint too for local testing.

Do maskable icons count for the 192 and 512 sizes?

Keep regular icons (purpose "any", the default) at 192 and 512 as well, and add maskable versions as an extra. Pewterkit Check counts only icons with purpose "any" toward the two sizes.

Where does assetlinks.json go in a Vite app?

public/.well-known/assetlinks.json, which Vite copies to /.well-known/assetlinks.json in the build.

Sources

  1. web.dev: What does it take to be installable? — read 27 Oct 2026: manifest fields, display values, HTTPS
  2. Android Developers: Trusted Web Activities overview — read 27 Oct 2026: what a TWA is, Digital Asset Links trust, Add to Home Screen requirements, Bubblewrap
  3. Android Developers: Configure website associations (assetlinks.json) — read 27 Oct 2026: content type, HTTPS, no redirects, each domain, Play App Signing fingerprint
  4. Chrome for Developers: Android concepts for web developers (TWA) — read 27 Oct 2026: browser bar symptom, logcat message, both fingerprints
  5. Google Digital Asset Links: Getting started — read 27 Oct 2026: exact file location, statement example
  6. Vite: Static Asset Handling, the public directory — read 27 Oct 2026: public files copied to the build root

How this page was made: drafted with AI from the sources listed, reviewed by Pewterkit. Docs checked Oct 27, 2026. Spotted something out of date? Tell us.

Related guides