ディープリンクは、OSがブラウザではなくアプリに渡すURLです。アプリがインストールされた状態でタップするとアプリが開き、アプリがなければブラウザがWebページを読み込みます。iOSではUniversal Links、AndroidではApp Linksと呼ばれ、どちらもSDKを必要としません。
設定は、自分で管理するドメイン上の二つのJSONファイルと、アプリ内のエンタイトルメントまたはintent filter一つです。以下では、二つのファイル、短縮リンクのドメインの位置付け、多くのガイドが省略する部分 (アプリが受け取るのはリダイレクト先ではなく短縮URLであること)、そしてSDKのほうが得意な三つの仕事を説明します。
これは以前より重要になっています。GoogleはFirebase Dynamic Linksを2025年8月25日に終了し、そのFAQでは、該当リンクはHTTP 404を返すとされています (Firebaseサポート FAQ、2026-10-24 閲覧)。そのFAQは、機能を完全に引き継ぐベンダーと、インストール時に開くだけで足りるアプリ向けのApp LinksとUniversal Linksを挙げています。印刷物からインストールに誘導する場合は、アプリダウンロード用のQRコードが、読み取り可能なコードの裏に同じルーティングを置きます。
要点
- AndroidのApp Links (Android 6、API 23以降) とiOSのUniversal Linksは、サードパーティのSDKなしで「インストール済みならアプリで開き、なければWebページ」を実現します。
- どちらも、自分で管理するドメインをHTTPSで配信し、
/.well-known/配下に関連付けファイルを置く必要があります。 - 短縮リンクのドメインでは、アプリは短縮URLで起動されます。アプリのコードがそれを画面に解決する必要があります。302は実行されません。
- 遅延ディープリンク、インストールアトリビューション、アイデンティティの結合では、SDKは今でもコストに見合います。それらが不要なら不要です。
OSがアプリを開くかどうかを判断する仕組み
どちらのシステムも、ドメインとアプリの間の検証済みの関係を前提にします。Androidのドキュメントは、App Linksによって検証済みのWebサイトのURLが「ユーザーに選択ダイアログからアプリを選ばせることなく、Androidアプリ内の対応するコンテンツをすぐに開く」こと、アプリを持たないユーザーは「代わりにWebサイトに移動する - 404もエラーもなし」であることを述べています (developer.android.com/training/app-links/about、2026-10-24 閲覧)。
Androidはインストール時に検証します。intent filterがandroid:autoVerify="true"を持つ場合、Android 6以降のデバイスは、アプリのインストール中に、宣言されたホストをhttps://hostname/.well-known/assetlinks.jsonと照合します (developer.android.com/training/app-links/verify-android-applinks、2026-10-24 閲覧)。テストする前に、このチェックのため少なくとも20秒待ってください。Android 15以降では、再検証も定期的に実行され、ファイルの変更が反映されるまで最大7日かかることがあります。Android 14以前は、インストールまたは更新時にのみ変更を取り込みます。
Appleのデベロッパーページ (developer.apple.com、Supporting associated domainsとSupporting universal links) は、2026-10-24の取得時に表示されなかったため、公開されている例が示す内容を超えてAppleの挙動を引用することはしません。ファイルは/.well-known/apple-app-site-associationにあり、アプリはAssociated Domainsエンタイトルメントでapplinks:your-domainを宣言し、Universal LinkはURLを持つWeb閲覧のユーザーアクティビティとしてアプリに届きます。公開前に、特にキャッシュと開発モードの挙動について、最新のAppleのページを確認してください。
短縮リンクへの帰結は、そこから直接導かれます。OSは、タップされたURLに基づいて判断します。それはサーバーへのリクエストより前に行われます。そのURLのドメインがあなたのアプリ向けに検証されていれば、アプリはそのURLで開きます。短縮リンクへのHTTPリクエストは発生しないので、リダイレクトは実行されません。
二つのファイル
プラットフォームごとに1ファイルで、それぞれ同じドメイン上の固定パスに置きます。
apple-app-site-association
AASAファイルはhttps://yourdomain.example/.well-known/apple-app-site-associationで配信する必要があります。有効な証明書チェーン、200ステータス、Content-Type: application/jsonを使い、リダイレクトなしでHTTPS配信してください。
Appleのフォーマットの参照先はSupporting associated domainsです。2026-10-24には表示されなかったため、以下のサンプルは一般に公開されている形として扱い、そのページと照らして確認してください。
最小限のAASAの形:
{
"applinks": {
"details": [
{
"appIDs": ["ABCDE12345.com.example.acme"],
"components": [
{
"/": "/spring-*",
"comment": "Match any path starting with /spring-"
},
{
"/": "/campaigns/*"
}
]
}
]
}
}
appIDsは、AppleのTeam IDとアプリのバンドル識別子をドットでつないだものです。components配列は、どのパスがアプリへのルーティングを起動するかを制御し、コンポーネントに一致しないものはブラウザに回ります。details配列には複数のアプリを登録できます。同じドメイン上に、同じ製品の一般向けとエンタープライズ向けのバリアントがある場合に便利です。
はっきり述べておくべき細部が一つあります。/spring-*のようなワイルドカードパターンを持つ"/"は、パスの前方一致です。同じリファレンスのパターン構文には、* (任意の部分文字列)、? (任意の1文字)、除外オブジェクトが含まれます。ドメイン上のすべてのパスに一致させたいなら、"/" : "/*"を使います。特定のパスをアプリのルーティングから除外したい場合、たとえば/account/deleteページは常にブラウザで開くようにしたい場合は、ワイルドカードの前に除外オブジェクトを追加します。
{
"/": "/account/delete",
"exclude": true
}
ルールは最初から最後の順に評価されるので、除外はワイルドカードより前に置いてください。
assetlinks.json
AndroidのDigital Asset Linksファイルはhttps://yourdomain.example/.well-known/assetlinks.jsonにあります。Googleはそのフォーマットをdevelopers.google.com/digital-asset-links/v1/getting-startedで文書化しています。
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example.acme",
"sha256_cert_fingerprints": [
"AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
]
}
}
]
package_nameは、Play StoreでのアプリのアプリケーションIDです。sha256_cert_fingerprintsには、アプリの署名証明書のSHA-256フィンガープリントを入れます (Googleのページは、モバイルアプリのターゲットは証明書のハッシュとパッケージ名で識別されると述べています)。keytool -list -v -keystore your.keystoreで、またはPlayが署名する場合はPlay Consoleの署名設定から取得します。デバッグ用も含め、インストールするビルドが使うすべての証明書を列挙してください。
AASAファイルと違って、Androidのファイルにはパスのルールがありません。App Linksのパス照合は、AndroidManifest.xmlの<intent-filter>でandroid:pathPrefix、android:pathPatternを使って行います。assetlinks.jsonファイルはドメインの所有を表明し、マニフェストはアプリが扱うパスを宣言します。
短縮リンクのドメインの位置付け
go.acme.example/spring-launchのようなリンクは、ドメイン上のただのURLです。go.acme.exampleに二つの関連付けファイルを配置し、アプリで宣言すれば、そのリンクのタップは、インストール済みのデバイスでアプリを開きます。それが仕掛けであり、同時に落とし穴でもあります。アプリが受け取るのはhttps://go.acme.example/spring-launchであり、リンクのリダイレクト先のページではありません。
アプリのコードには二つの選択肢があります。一つ目は、パスを自分で照合する方法 (/spring-launchはspringの画面を意味する) で、スラッグを自分で管理している場合に機能します。二つ目は、サーバーに短縮リンクの遷移先を問い合わせ、その答えからルーティングする方法です。Elidoには、アプリがスラッグを遷移先に解決するための文書化されたエンドポイントはありません。公開リダイレクトは302で応答するだけです。現時点で確実なのは一つ目で、そのギャップは私たちのバックログにあります。
アプリがないデバイスや、リンクをOSに渡さない場所でタップされた場合、短縮リンクはこれまでどおり動作します。エッジがリダイレクトで応答し (デフォルトは302で、リンクごとに301や307にも設定可)、ブラウザがそれをたどります。Elidoのターゲティングルールは、OSで照合できるため、一つのリンクで、アプリがない場合にiOSの訪問者をApp Storeのページへ、AndroidをGoogle Playへ送れます。
現時点でElidoがこれに対して行うこと、行わないことを、コードで確認した内容は次のとおりです。
| 機能 | 状況 | 場所 |
|---|---|---|
カスタムドメイン向けにapple-app-site-associationを配信 | あり | ダッシュボードでドメインごとにJSONを貼り付け |
カスタムドメイン向けにassetlinks.jsonを配信 | あり | 同じパネル |
| ドメインにファイルが設定されていない場合は404を返す | あり | アプリのないドメインは何も公開しない |
| iOSとAndroidの訪問者を異なるURLにルーティング | あり | ターゲティングルール (OS照合) |
| インストール後の遅延ディープリンク | なし | ベンダーのSDKを使う |
| クリックごとのインストールアトリビューション | なし | ストアのコンソールまたはベンダー |
Elidoは、あなたが作成したJSONを保存し、ドメイン自身の/.well-known/パスの下で、変更せずに配信します。Team ID、バンドルID、署名証明書のフィンガープリントは、Elidoが生成するものではなく、Apple Developerアカウントと署名キーから取得します。ドメイン自体の設定 (CNAMEとTLS) はカスタムドメインの短縮リンクと同じで、ディープリンク機能のページにダッシュボードの流れがあります。短縮リンクをオンボーディングに使うプロダクトチームにとって、このパターンは、バイナリにSDKを追加せずに招待リンクや紹介リンクをカバーします。まだ何もインストールされていない側の問題は、iOSではApp Clip Codesが扱っています。
SDKのほうが得意なこと
OSが提供する範囲の外にある、三つのことがあります。
遅延ディープリンク。 ユーザーがインストール前にタップします。OSにはURLを渡すアプリがないため、タップはブラウザに行き、意図は失われます。ベンダーは、リクエストデータの確率的な照合やクリップボードの引き継ぎで、これを回復します。Appleのトラッキング同意のプロンプトは、エッジケースを厄介なものにします。Elidoは現時点でこれを行いません。
インストールアトリビューション。 SDKがなくても、App Store ConnectやPlay Consoleでインストールは確認できますが、特定のリンクのタップと結び付けることはできません。相対的なシグナルは残ります。スマートリンクの実験を実行して、キャンペーンごとのインストールを比較してください。デバイス単位のアトリビューションにはベンダーが必要です。
アイデンティティの結合。 タップをメールアドレスやCRMの連絡先に結び付けるのは、データプロジェクトです。ベンダーはそのためにデバイスグラフを維持しています。
この三つがどれも重要でないなら、OSのプリミティブで十分です。どれかが重要なら、その仕事に限ってベンダーを雇ってください。
設定のクックブック
正しく設定すべき場所は三つ、サーバー、iOSプロジェクト、Androidのマニフェストです。
HTTPSとパスの要件
両方のファイルを、公開ルートCAにつながる証明書を使ってHTTPSで配信します。GoogleのDigital Asset Linksのページは、ステートメントのリストは/.well-known/assetlinks.jsonに「なければならず」、他の場所や別名のリストは有効ではないと述べています (developers.google.com/digital-asset-links/v1/getting-started、2026-10-24 閲覧)。そのページはリダイレクトがたどられるかどうかは述べていないため、ファイルは200で直接配信し、賭けに出ないでください。Appleのファイルにも同じ助言が当てはまります。
iOS: Associated Domainsエンタイトルメント
Xcodeで、Signing & CapabilitiesからAssociated Domainsケイパビリティを追加し、値をapplinks:go.acme.exampleにします。Appleは、開発ビルド向けに?mode=developerサフィックスを文書化しており、これを付けるとデバイスはAppleのキャッシュを経由せずサーバーからファイルを取得します。2026-10-24にそのページを再確認できなかったため、Appleのドキュメントで確認してください。受信したリンクは、Web閲覧のユーザーアクティビティとして処理し (SwiftUIのonContinueUserActivity(NSUserActivityTypeBrowsingWeb)、またはUIKitのcontinue userActivityデリゲート)、webpageURLを読み取ります。
Android: マニフェストのApp Links
リンクを処理するアクティビティの内側に、次を記述します。
<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="go.acme.example"
android:pathPrefix="/campaigns/" />
</intent-filter>
Androidは、VIEWアクションと上記の二つのカテゴリ、httpまたはhttpsスキームを持つフィルターを自動検証の対象とします。Android 11以前では、マニフェスト内のすべてのホストに対してDigital Asset Linksファイルが見つかった場合にのみ、システムがアプリをデフォルトのハンドラーにするため、一つの不良ホストがすべてを壊します。一つのデバイスでは、同時に一つのアプリだけがドメインに関連付けられます。
動作の確認
Androidでは、インストール後に少なくとも20秒の検証時間を置き、adb shell pm get-app-links com.example.acme (Android 12以降) を実行して、verifiedを探します。adb shell pm verify-app-links --re-verify com.example.acmeで再実行を強制できます。none、denied、legacy_failureなどの結果は、ファイルかフィンガープリントが誤っていることを意味します。
ファイル自体については、GoogleのDigital Asset Links APIが、サイトについて読み取れるステートメントを一覧表示します: https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://go.acme.example&relation=delegate_permission/common.handle_all_urls。空のレスポンスは、Androidがアプリを検証しないことを意味します。
両方のプラットフォームで、クローラーと同じ方法でファイルを取得します。
curl -si https://go.acme.example/.well-known/assetlinks.json | head -20
curl -si https://go.acme.example/.well-known/apple-app-site-association | head -20
200とJSONの本文が返るはずです。Elidoは両方のファイルでapplication/jsonを送ります。よくある間違いは、Team IDやバンドルIDのタイプミス、署名証明書がフィンガープリントのリストにないリリースビルド、リンクがサブドメインを使っているのにファイルがapexにしかないことです。
トレードオフをはっきり述べる
ディープリンクSDKを外すと、アプリのバイナリから依存関係が一つ減り、プライバシー通知からデータ共有の関係が一つ減ります。サイズの数値は示しません。ベンダーによって異なり、私は測定していないからです。代償は、インストール前のタップをインストールに結び付けられないことです。
インストールあたりのチャネル別コストがまだ予算を左右していない初期段階のチームは、OSのプリミティブから始め、データが実行可能になったらアトリビューションのベンダーを追加してください。
ブログの関連記事
よくある質問
FirebaseやサードパーティのSDKなしでディープリンクを実現できますか?
アプリがすでにインストールされている場合に限り、できます。iOSのUniversal LinksとAndroidのApp Linksに必要なのは、自分で管理するドメイン、そのドメイン上のJSONの関連付けファイル、アプリ内の数行のコードです。GoogleのFirebase Dynamic LinksのFAQ自体が、インストール済みアプリへのディープリンクの選択肢としてこの二つの仕組みを挙げています。手放すのは、新規インストール後に適切な画面を開く遅延ディープリンクです。
Universal LinksとApp Linksは短縮リンクのドメインでも機能しますか?
はい、短縮リンクのドメインが関連付けファイルを配信し、アプリがそのドメインを宣言していれば機能します。注意点は、OSがタップされた短縮URLそのものでアプリを開くため、アプリがそのURLを画面に変換しなければならないことです。リダイレクトが実行されたことには頼れません。アプリがインストールされていない場合、同じタップはブラウザで読み込まれ、通常のリダイレクトが適用されます。
関連付けファイルはどこに置きますか?
Androidはhttps://your-domain/.well-known/assetlinks.jsonを読み込み、GoogleのDigital Asset Linksのドキュメントは、これが唯一有効な場所だと述べています。Appleのファイルは、拡張子なしでhttps://your-domain/.well-known/apple-app-site-associationに置きます。どちらも、公開CAにつながる証明書を使ってHTTPSで配信してください。
Androidアプリが直接開かず、選択ダイアログが表示されるのはなぜですか?
直接開くには、検証済みのApp Linkが必要です。Androidは、アプリのインストール時に、intent filterがandroid:autoVerify="true"を持っている場合に限り、ドメインをassetlinks.jsonと照合します。ファイルがない、誤っている、またはインストールされたビルドと異なる署名証明書が記載されている場合、リンクは通常のディープリンクとして動作します。
遅延ディープリンクとは何ですか?省略できますか?
遅延ディープリンクは、リンクの遷移先をアプリのインストールをまたいで引き継ぎ、インストール前にタップしたユーザーが初回起動時に適切な画面に着くようにします。Universal LinksとApp Linksは、タップを受け取るアプリがそこにないため、その場合には何もしません。ホーム画面に着いて問題ないオンボーディングのフローでは省略でき、初回起動時のルーティングが数字を動かす場合にのみ、ベンダーを追加してください。
このうち、Elidoが扱うのはどの部分ですか?
Elidoは、ダッシュボードのドメイン設定に貼り付けたJSONを使って、カスタムドメイン向けにapple-app-site-associationとassetlinks.jsonのファイルを配信します。また、ターゲティングルールでiOSとAndroidの訪問者を異なる遷移先にルーティングします。遅延ディープリンクやインストールアトリビューションは提供していないため、それらが必要ならベンダーのSDKを使ってください。
Elidoを試す
URLを貼り付けて短縮リンクを取得
登録不要。リンクは30日間有効。永久に保存するには登録してください。
登録不要。無料登録すると月 50 件のリンクを作成できます。