> For the complete documentation index, see [llms.txt](https://docs.buildnatively.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.buildnatively.com/natively-platform/features/deep-links/universal-links.md).

# Universal Links

## What are Universal Links

Universal Links associate your website domain directly with your app - no third-party service required. When a user taps a link to your website, the device recognizes it as a deep link and opens your app instead of a browser, navigating them directly to the right page or content.

If the app is not installed on the device, the link opens normally in the browser, so your website always works as a fallback.

{% hint style="info" %}
Setups differ between iOS and Android. Use the sections below to follow the correct setup for your platform, or complete both if your app supports both platforms.
{% endhint %}

## iOS

### Prerequisites

* An [Apple Developer account](https://developer.apple.com/account).
* Your iOS app is already [published](/natively-platform/app-info/ios-build.md) in the Natively Dashboard.

### App Capabilities Configuration

{% hint style="info" %}
App capabilities define what system-level features your app is allowed to use on iOS. Before Natively can include Universal Links in your build, the **Associated Domains** capability must be explicitly enabled in your Apple Developer account for your app's Bundle ID.
{% endhint %}

1. Open your [Apple Developer account](https://developer.apple.com/account) and navigate to [Certificates, IDs & Profiles > Identifiers](https://developer.apple.com/account/resources/identifiers/list).
2. Select your app's Bundle ID.
3. Scroll down the **Capabilities** list and enable **Associated Domains**.
4. Click **Save** and confirm.

### apple-app-site-association

For Universal Links to work, your website must [host](#website-setup) a special verification file called the **Apple App Site Association (AASA)** file. This file tells iOS that your website and app are associated, allowing links to your domain to open in your app instead of a browser.

#### Download AASA template

{% file src="/files/nUsWhd1y36Vvx1yTDGXj" %}

{% hint style="danger" %}
The `webcredentials` section is required if you are using [Social Auth](/natively-platform/features/social-auth.md) in your app. Without it, OAuth authentication will not work correctly on iOS.
{% endhint %}

```json
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "TEAM_ID.BUNDLE_ID",
                "paths": [
                    "*"
                ]
            }
        ]
    },
    "webcredentials": {
        "apps": [
            "TEAM_ID.BUNDLE_ID"
        ]
    }
}
```

Replace `TEAM_ID` with your Apple Team ID and `BUNDLE_ID` with your iOS app's Bundle ID.&#x20;

{% hint style="info" %}
Your Apple **Team ID** is located in your [Apple Developer account](https://developer.apple.com/account) under **Membership details**.
{% endhint %}

<div><figure><img src="/files/txyHVYvLY3uNj8Wn9aMw" alt=""><figcaption><p>Team ID under Membership Detail</p></figcaption></figure> <figure><img src="/files/DAaG9cgA5fsXkuy34OP5" alt=""><figcaption><p>Bundle ID from App Store Connect iOS app</p></figcaption></figure></div>

{% hint style="warning" %}
On iOS 14 and later, Apple's CDN retrieves and caches the AASA file. When your app is installed, devices immediately download the file from the CDN. Devices check for updates approximately once per week after the app is installed. To download a newer version of the AASA file, reinstall the app. There is no direct CDN invalidation option.
{% endhint %}

{% hint style="warning" %}
It is up to third-party web browsers to enable Universal Links functionality. Universal Links may not be enabled in every web browser. Safari implements all of the functionality described in this page. For information about other browsers, check with the browser's vendor.
{% endhint %}

## Android

### Prerequisites

* Your Android app is already [published](/natively-platform/app-info/android-build.md) in the Natively Dashboard.
* Your app is [uploaded](https://support.google.com/googleplay/android-developer/answer/9845334#zippy=%2Cinternal-test-manage-up-to-testers) to the **Google Play Console** - required to access the **Upload key** SHA-256 certificate fingerprints.

### assetlinks.json

For Android App Links to work, your website must [host](#website-setup) a **Digital Asset Links** file. This file tells Android that your website and app are associated, allowing links to your domain to open in your app instead of a browser.

#### Download assetlinks.json template

{% file src="/files/XMFuKA52yvTJFcjuQ3ge" %}

```json
[
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "BUNDLE_ID",
      "sha256_cert_fingerprints": [
        "APP_SIGNING_KEY_SHA256",
        "UPLOAD_KEY_SHA256"
      ]
    }
  }
]
```

Replace `BUNDLE_ID` with your app's Bundle ID. As for the SHA256 fingerprints:

* `APP_SIGNING_KEY_SHA256` — your **App signing key** SHA-256 certificate fingerprint.
* `UPLOAD_KEY_SHA256` — your  **Upload key** SHA-256 certificate fingerprint.

Both can be found in your **Google Play Console** app page under **Protected With Play** > **Play Store protection** > **Protect app signing key** > **Manage Play App Signing**.

{% hint style="info" %}
If you don't see the **Upload key certificate** content, you need to [upload](https://support.google.com/googleplay/android-developer/answer/9845334#zippy=%2Cinternal-test-manage-up-to-testers) your app first.
{% endhint %}

<div><figure><img src="/files/ReoNA0pNzW0p3SHHztJc" alt=""><figcaption><p>Google Play Console Manage Play app signing</p></figcaption></figure> <figure><img src="/files/s71lOvMgwc4u8kVnPOfU" alt=""><figcaption><p>SHA-256 fingerprints</p></figcaption></figure></div>

## Website setup

Before proceeding, make sure you have already created and configured your verification files for [iOS](#apple-app-site-association) and [Android](#assetlinks.json).

Once your files are ready, follow the instructions below for your platform to host them on your website.

{% tabs %}
{% tab title="General" %}
To make Universal Links work, your website needs to host two special files at specific locations that Apple and Google can access to verify your domain.

Upload the relevant file(s) for your platform::

* `apple-app-site-association` - required for iOS, must be accessible at <mark style="color:red;">`https://yourdomain.com/.well-known/apple-app-site-association`</mark>
* `assetlinks.json` - required for Android, must be accessible at <mark style="color:red;">`https://yourdomain.com/.well-known/assetlinks.json`</mark>&#x20;

Files must be publicly accessible without any redirects.

{% hint style="warning" %}
Files must be served with the content type `application/json`. If the content type is incorrect, Apple and Google might not be able to verify your domain even if the files are accessible.
{% endhint %}

If you are unsure how to host files on your website, check the other tabs for platform-specific instructions.
{% endtab %}

{% tab title="Bubble.io" %}

1. Open your Bubble project.
2. Go to the **Settings > SEO / metatags**.
3. Scroll down and find the **Hosting files in the root directory** section.
4. For iOS: set the name to `.well-known/apple-app-site-association` and upload your **AASA** file.
5. For Android: set the name to `.well-known/assetlinks.json` and upload your **assetlinks.json** file.
6. Publish the changes.

![](/files/XgQ1iwyrnipw2XxtbzpR)
{% endtab %}

{% tab title="AI Agents" %}
Lovable, Replit, and Base44 all use React/Vite under the hood, which copies everything in the `public/` folder to the build output root as-is. This means you can host the verification files simply by asking your AI assistant to create them at the correct paths.

{% hint style="warning" %}
Copy your configured file content from the [iOS](#apple-app-site-association) or [Android](#assetlinks.json) sections above, paste it into the placeholder at the end of the copied text, then send it to your AI agent.
{% endhint %}

For the iOS app, copy the line below and paste it into your AI agent:

```
Create a file at public/.well-known/apple-app-site-association with the following content: [paste your configured apple-app-site-association content here]
```

For the Android app, copy the line below and paste it into your AI agent:

```
Create a file at public/.well-known/assetlinks.json with the following content: [paste your configured assetlinks.json content here]
```

Once published, the files will be automatically accessible on your domain.
{% endtab %}
{% endtabs %}

## How to verify?

Once your verification files are hosted, confirm everything is configured correctly before proceeding to the [Natively Dashboard Setup](#natively-dashboard-setup).

{% hint style="info" %}
Both tools check the live hosted files, not your local copies. Make sure you have published your changes before running the verification.
{% endhint %}

### iOS

{% embed url="<https://branch.io/resources/aasa-validator/>" %}

Use the Branch AASA Validator to verify your `apple-app-site-association` file. Enter the following details to confirm the file is accessible, correctly served, and valid:

* **Domain** - your website domain.

### Android

{% embed url="<https://developers.google.com/digital-asset-links/tools/generator>" %}

Use the Google Digital Asset Links tool to verify your `assetlinks.json` file. Enter the following details to confirm the file is correctly hosted and your app is properly associated with your domain:

* **Hosting site domain** - your website domain.
* **App package name** - your app's Bundle ID.
* **App package fingerprint (SHA256)** - either your app signing key or upload key SHA256 fingerprint from the Google Play Console.

#### Checking via Android device settings

You can also verify directly on your Android device. Go to **Settings > Apps > \[your app] > Open by default** (also called **Supported web addresses** on some devices):

* If the toggles are **enabled** or the link is present but there are **no toggles** (behavior depends on Android vendor) - Android Universal Links are correctly configured.
* If the toggles are **present but disabled** - the `assetlinks.json` is incorrect or couldn't be verified by Android. The app is configured for deep links, but Android couldn't confirm domain ownership.

## Natively Dashboard Setup

{% hint style="info" %}
Before proceeding, make sure your verification files are hosted and accessible. You can confirm this using the tools in the [How to verify](#how-to-verify) section above. If there are any issues with your files, Natively Dashboard will indicate a configuration problem, and the feature cannot be enabled until they are resolved.
{% endhint %}

1. Open your Natively app dashboard and navigate to **Features** > **Deep Links** > **Universal Links**.
2. Toggle the feature to **Enabled**.
3. Enter your **Associated Domain** - your website domain (e.g. `yourdomain.com`).
4. Click **Save**.
5. Rebuild your app(s).

{% hint style="warning" %}
You must rebuild your app for these changes to take effect.
{% endhint %}

{% hint style="info" %}
Natively will prefill the **Associated Domain** with your app's URL configured in the Natively Dashboard. You can modify it if your deep links domain differs from your app's main URL.
{% endhint %}

## Troubleshooting

<details>

<summary>Website Links are opening in a browser instead of the app</summary>

Most commonly caused by one of the following:

* Verification files are not correctly hosted or formatted.
* The Associated Domain in the Natively Dashboard doesn't match the domain where your files are hosted.
* App not rebuilt after enabling the feature.

</details>

<details>

<summary>Universal Links are not working after updating the AASA file</summary>

Apple's CDN caches the AASA file and checks for updates approximately once per week. To force a refresh, reinstall the app on your device.

</details>

<details>

<summary>Universal Links are not working in third-party browsers</summary>

Third-party browsers may not support Deep Links on either platform. On iOS, Universal Links are only guaranteed to work in Safari. On Android, behavior varies by browser - some browsers, like Samsung Internet, may not open the app correctly, while others, like Firefox on the same device, may work fine. If Universal Links are not working in a specific browser, check with the browser's vendor for more information.

</details>

<details>

<summary>Android app not opening from an Associated Domain link</summary>

Check the following:

* The file is served with the content type `application/json` .
* The file is accessible without any redirects.
* Both SHA-256 fingerprints (app signing key and upload key) are present in the file; if either one is missing, the app will not open.
* The package name matches your app's Bundle ID exactly.

</details>

<details>

<summary>iOS app not opening from an Associated Domain link</summary>

Check the following:

* The file is served with the content type `application/json` .
* The file is accessible without any redirects.
* Both `applinks` and `webcredentials` sections are present and correctly formatted.
* The Team ID and Bundle ID are correct.

</details>
