expo-app-clip について
expo-app-clip は、Expo アプリに iOS App Clip ターゲットを追加し、関連ドメインとメタデータを設定して TestFlight 向けにビルドする手順を示すガイドです。親アプリとともに URL から起動する Clip を組み込む Expo 開発者向けです。
主な機能
- 01App Clip ターゲットの作成
- 02関連ドメインと AASA の設定
- 03App Store と Clip のメタデータ設定
- 04Clip を含む親アプリのビルドと提出
- 05App Clip コンテキストの任意検出
活用シーン
- 01Expo アプリに URL 起動の Clip を追加
- 02Clip 起動用のドメイン関連付けを設定
- 03Expo アプリと Clip の TestFlight 版を準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ expo/ skills --skill expo-app-clipインストール後、Claude Code で/expo-app-clipを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlreferences/native-module.md
詳細
Expo アプリに App Clip を追加する
要件。 App Clip ターゲットの追加はオープンソースです。App Clip を配信するには、Apple Developer Program への加入と App Store の審査が必要です。また、AASA ファイルはドメイン上で HTTPS 経由で配信する必要があります(HTTPS に対応したホストであれば利用でき、EAS Hosting も選択肢の 1 つです)。EAS Build または
bunx testflightを使用してビルドすると、EAS プランのビルド時間を消費します。詳しくは https://expo.dev/pricing および https://developer.apple.com/app-clips/ をご覧ください。
Expo プロジェクトに iOS App Clip ターゲットを追加します。Clip は targets/clip/ に配置され、親アプリとともに配信されます。Apple App Site Association(AASA)ファイルを使って、アプリのドメイン上の URL から起動します。
親アプリのバンドル ID は com.<username>.<app-name> になり、Clip のバンドル ID は <parent>.clip として自動的に生成されます(例:com.bacon.may20.clip)。
1. bundleIdentifier と appleTeamId を設定する
これらが設定されていない場合、bun create target は警告を表示します。app.json に追加します。
{
"expo": {
"ios": {
"bundleIdentifier": "com.<username>.<app-name>",
"appleTeamId": "XX57RJ5UTD"
}
}
}
2. App Clip ターゲットを追加する
bun create target clip
これにより、@bacons/apple-targets がインストールされ、app.json の plugins 配列に追加され、以下のファイルが作成されます。
targets/clip/expo-target.config.js— ターゲットの設定プラグインtargets/clip/Info.plist— Clip の Info.plisttargets/clip/AppDelegate.swift、Assets.xcassetsなど
適切なアイコンを選ぶか、アプリに設定済みのアイコンを再利用してください。bunx expo config を実行し、icon または ios.icon キーを確認します。
3. 関連付けられたドメインを設定する
親アプリと Clip の両方で、AASA ファイルをホストするドメインを指定する Associated Domains エンタイトルメントが必要です。
app.json に applinks:(親アプリ)と appclips:(Clip の起動)の両方の項目を追加します。
{
"expo": {
"ios": {
"associatedDomains": [
"applinks:may20.expo.app",
"appclips:may20.expo.app"
]
}
}
}
targets/clip/expo-target.config.js で Clip のエンタイトルメントを宣言します。
/** @type {import('@bacons/apple-targets/app.plugin').ConfigFunction} */
module.exports = (config) => ({
type: "clip",
icon: "https://github.com/expo.png",
entitlements: {
"com.apple.developer.associated-domains": ["appclips:may20.expo.app"],
},
});
これを省略すると、
expo prebuildは次のメッセージを出力します:Apple App Clip may require the associated domains entitlement but none were found。
4. バンドル ID を登録し、App Store のエントリーを作成する
bunx setup-safari
Apple Developer アカウントにログインし、com.bacon.may20 を登録して App Store Connect のエントリーを作成した後、以下を出力します。
apple-app-site-associationのひな形となる JSON- iTunes アプリ ID を含む
<meta name="apple-itunes-app">タグ - Team ID、iTunes ID、バンドル ID
5. AASA ファイルをホストする
iOS が https://<your-domain>/.well-known/apple-app-site-association を取得し、一致する appclips 項目を見つけると、App Clip が起動します。
mkdir -p public/.well-known
touch public/.well-known/apple-app-site-association
setup-safari が出力した JSON を貼り付けますが、Clip の完全なアプリ ID(<TeamID>.<ClipBundleID>)を指定する appclips ブロックを追加してください。setup-safari の出力に含まれるのは親アプリの設定のみです。
{
"applinks": {
"details": [
{
"appIDs": ["XX57RJ5UTD.com.bacon.may20"],
"components": [{ "/": "*", "comment": "Matches all routes" }]
}
]
},
"appclips": {
"apps": ["XX57RJ5UTD.com.bacon.may20.clip"]
},
"activitycontinuation": {
"apps": ["XX57RJ5UTD.com.bacon.may20"]
},
"webcredentials": {
"apps": ["XX57RJ5UTD.com.bacon.may20"]
}
}
注意事項:
- このファイルに拡張子はなく、そのまま配信されること以外に**
Content-Typeの要件もありません**。Expo Router の静的エクスポートでは、public/内のファイルがそのまま配信されます。 - ドメイン上の URL から Clip を起動できるようにするのが
appclipsブロックです。 webcredentialsは、Web サイト、親アプリ、App Clip 間で認証情報を共有するために使用します。activitycontinuationは任意で、モバイルとデスクトップの間でリンクを共有するために使用します。expo-routerのHeadと併用する必要があります。詳しくは https://docs.expo.dev/router/advanced/apple-handoff/ をご覧ください。- 記法とルートを無効にする方法については、https://sosumi.ai/documentation/xcode/supporting-associated-domains をご覧ください。
6. Smart App Banner の meta タグを追加する
src/app/+html.tsx(Expo Router の HTML シェル)を作成し、setup-safari のタグを追加します。バージョン付きテンプレートが存在しない場合は作成します。
bunx expo customize src/app/+html.tsx
<head> に meta タグを追加します。
import { ScrollViewStyleReset } from "expo-router/html";
export default function Root({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="apple-itunes-app" content="app-id=6771566491" />
<ScrollViewStyleReset />
</head>
<body>{children}</body>
</html>
);
}
Web サイトにインストールカードではなく App Clip カードを表示するには、次のようにします。
<meta
name="apple-itunes-app"
content="app-id=6771566491, app-clip-bundle-id=com.bacon.may20.clip, app-clip-display=card"
/>
7. Web サイトをデプロイする
iOS が関連付けを信頼するには、AASA ファイルが公開されている必要があります。EAS Hosting を使用します。
bunx expo export -p web
eas deploy --prod
これにより、サイト(/.well-known/apple-app-site-association を含む)が https://<slug>.expo.app に公開されます。次のように確認します。
curl https://may20.expo.app/.well-known/apple-app-site-association
8. 権限をそろえる
プリビルド後に、親アプリの権限を確認します。
npx expo config --type introspect
infoPlist オブジェクトを確認し、一致する API を Clip から利用できるよう、App Clip の Info.plist に同じ権限キーを設定します。
Clip のターゲット設定で deploymentTarget: "17.6" を設定します。iOS 17.6 では、App Clip の最小サイズ制限が引き上げられています。
アプリでプッシュ通知または位置情報サービスを使用する場合は、必要な権限を要求するため、App Clip の Info.plist に以下を追加します。
<key>NSAppClip</key>
<dict>
<key>NSAppClipRequestEphemeralUserNotification</key>
<false/>
<key>NSAppClipRequestLocationConfirmation</key>
<true/>
</dict>
9. ビルドして TestFlight に提出する
bunx testflight
これにより、以下が行われます。
eas.jsonがない場合は生成します。- 両方のターゲット(親アプリと Clip)の認証情報を設定します。それぞれ専用のプロビジョニングプロファイルを使用しますが、単一の Distribution Certificate を共有できます。
- 機能を同期します。Clip ターゲットの
Enabled: Associated Domainsに注目してください。 - ビルド、アップロードを行い、TestFlight への提出を予約します。
10. App Clip のメタデータを設定する
既存の App Store メタデータをローカルに取得します。
eas metadata:pull
store.config.json に apple.appClip を追加します。ウェブページから Clip を起動する呼び出し URL は、最大 3 つ設定できます。
{
"configVersion": 0,
"apple": {
"appClip": {
"defaultExperience": {
"action": "PLAY",
"releaseWithAppStoreVersion": true,
"reviewDetail": {
"invocationUrls": ["https://may20.expo.app/", null, null]
},
"info": {
"en-US": {
"subtitle": "Instantly native with Expo",
"headerImage": "store/apple/app-clip/en-US/asc-app-clip.png"
}
}
}
}
}
}
headerImage は、1800x1200 の不透明な PNG である必要があります。
ストアに反映します。
eas metadata:push
Apple が推奨する App Clip メタデータのガイドライン:https://sosumi.ai/documentation/appclip/configuring-the-launch-experience-of-your-app-clip
得られるもの
- 親アプリのターゲット:
com.bacon.may20 - App Clip のターゲット:
com.bacon.may20.clip。targets/clip/にあります https://may20.expo.app/.well-known/apple-app-site-associationでホストされる AASA- すべてのウェブルートに Smart App Banner のメタタグを設定
- すべてのルートを対応するネイティブルートにリンク
- Clip を埋め込んだ親アプリの TestFlight ビルド
Apple がドメイン上の URL から Clip を起動すると、iOS は targets/clip/ のエントリーポイントを開き、React Native アプリを読み込みます。
ネイティブでの検出(任意)
JS で App Clip 内で実行されているかどうかを検出し、フルアプリのインストールを促すメッセージを表示するには、navigator.appClip.prompt() を公開するローカル Expo モジュール(bunx create-expo-module --local)を作成します。
Swift モジュール、TypeScript インターフェイス、使用方法については、./references/native-module.md を参照してください。
参考資料
- ./references/native-module.md — App Clip のコンテキストを検出し、SKOverlay のインストールプロンプトを表示するローカル Expo モジュール
フィードバックの送信
このスキルに関するエラー、誤解を招く情報、古い情報に気づいた場合は、Expo が改善できるよう報告してください。
npx --yes @expo/agent-cli@latest feedback --category skills --subject "expo-app-clip" "<actionable feedback>"
具体的かつ実行可能な報告事項がある場合にのみ送信してください。関連するコンテキストをできるだけ詳しく記載してください。
エージェントが Expo のタスクを繰り返し失敗する場合、またはユーザーが介入しなければならない場合は、タスク、期待される結果、問題点を簡潔に報告し、--category evals と、関連する Expo パッケージまたはコマンドを --subject として指定してください。