Native features

Open your website's links in your app

Once your site is an app, a link to it in an email or a message should open the app, not a browser tab. Android App Links do that with an intent filter and one JSON file on your domain. How it works, how to set it up, and why verification fails.

7 min read Updated September 2026

Android can open https://www.yoursite.com/anything in your app instead of the browser, without asking the user, if two things agree: an intent filter in the app that claims the domain, and an assetlinks.json file on the domain that names the app and its signing certificate. Android fetches the file when the app is installed; if it matches, every link to the domain routes to the app. This is called Android App Links, and it is the feature that makes a converted website feel like it was always an app.

A deep link is any URL an app says it can handle. If two apps claim the same link, Android shows a chooser — the "Open with" sheet — which is fine for custom schemes and annoying for a website. An App Link is a deep link over HTTPS that has been verified: the domain has published a file saying this app is allowed, so Android skips the chooser. Only the domain owner can publish the file, which is the whole point.

The two halves

In the app: the intent filter

Inside the activity that shows the site, the manifest declares which hosts and paths it opens, with android:autoVerify="true" so Android checks the domain at install:

<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="www.yoursite.com" /> </intent-filter>

On the domain: assetlinks.json

Served at exactly https://www.yoursite.com/.well-known/assetlinks.json, it names the package and the SHA-256 fingerprint of the certificate the installed app is signed with:

[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.yoursite.app", "sha256_cert_fingerprints": ["AB:CD:…"] } }]

The generator writes both from your domain, package name and fingerprint, and adds the test commands:

Deep Link GeneratorMake your website's links open in your app — intent filter + assetlinks.json Open the tool

Getting the fingerprint right

This is where most setups fail. The fingerprint must be of the certificate on the installed app. If the app is on Google Play, Play App Signing re-signs it, so the fingerprint you need is the App signing key certificate in Play Console (Test and release → App integrity) — not your upload key. For an APK you distribute yourself, it is your keystore's certificate: keytool -list -v -keystore your.jks. You can list several fingerprints in the file, which is useful for a debug build and a release build side by side.

Hosting the file

Testing

With a phone connected over adb:

adb shell pm get-app-links com.yoursite.app # www.yoursite.com: verified ← what you want adb shell am start -a android.intent.action.VIEW -d "https://www.yoursite.com/" com.yoursite.app

Android checks the file once, at install. After fixing a problem, reinstall the app or force a recheck with adb shell pm verify-app-links --re-verify com.yoursite.app. The states you will see are verified, none (no attempt yet) and a numeric error meaning the fetch or the match failed.

Why verification fails

  1. Upload key instead of app signing key. Nine times out of ten.
  2. The file redirects. Check with curl -I that the first response is 200.
  3. Wrong content type.
  4. Only one of www / bare is set up.
  5. Cached failure. Re-verify after fixing.

Claiming part of a site

Leaving the path off claims every link on the host. If only part of the site lives in the app — the shop but not the blog — add android:pathPrefix="/shop/" and blog links keep opening in the browser. Note that pathPrefix is a plain string prefix: /shop also matches /shopping.

Where the builder stands

The generated app keeps navigation inside the app — links between your pages never leave it — but links tapped elsewhere on the phone open the browser, because App Links are not yet a builder option. This guide and the generator are here so the setup is ready for a native project now and for the builder when the option ships. The iOS equivalent, Universal Links, uses the same idea with an apple-app-site-association file; the iOS guide covers where that fits.

Questions people ask

What is the difference between a deep link and an App Link?

A deep link is any URL an app claims; Android may show an 'Open with' chooser. An App Link is an HTTPS deep link verified by an assetlinks.json file on the domain, so Android opens your app without asking.

Where does assetlinks.json go?

At https://yourdomain/.well-known/assetlinks.json exactly — served over HTTPS, with a 200 status, no redirect, and Content-Type application/json. One per host if you serve both www and bare.

Which SHA-256 fingerprint do I use?

The certificate the installed app is signed with. On Google Play that is the App signing key certificate in Play Console, not your upload key. For a self-distributed APK it is your keystore's certificate.

Why do links still open in the browser after I set this up?

Verification failed or has not rerun. Run adb shell pm get-app-links on the package; a state other than 'verified' means the file was unreachable, redirected, mistyped or lists the wrong fingerprint. Fix it and re-verify.

Does the Website to App builder support App Links?

Not yet. Links inside the app stay in the app, but system-wide links open the browser. The generator gives you the intent filter and JSON for a native project and for when the option is added.

Read next

Turn your website into an app today

Paste your URL, pick a name and an icon, and download a signed Android app in minutes. Free to start — no code, no Android Studio, no card.

Convert my website — free