【解説】なぜExpo開発でディープリンクのURLスキームは三つのスラッシュ(///)を使うのか
AIに実装を任せていると、Expo開発でディープリンク実装で、myapp:///home
のように三つのスラッシュ(///
)を提案して、「なぜ二つではなく三つのスラッシュなのか?」と疑問に思い、正誤が分からなかったので調べてみました。
公式ドキュメントを探してみたものの、明確な説明がなかなか見つからなかったので記事に残します。本記事では、この「三つのスラッシュ問題」について、Expoの公式な見解に基づいて解説します。
URLスキームの基本構造
URLの一般的な構造は次のようになっています:
scheme://authority/path?query#fragment
例えば、https://zenn.dev/articles/123?mode=edit#section1
では:
- scheme:
https
- authority(ホスト部分):
zenn.dev
- path:
/articles/123
- query:
mode=edit
- fragment:
section1
三つのスラッシュが現れる理由
ディープリンクのURLスキームでは、通常ホスト部分が存在しないため、この部分が空になります。しかし、URL構造では scheme://
の後に何もなければ、それはパスの開始なのか、単にホスト部分が省略されているのかが曖昧になってしまいます。
そこで、RFC 3986(URI構文を定義する国際標準規格)に従い、ホスト部分が空の場合は次のような記法になります:
scheme:///path
この形式では、://
の後に何も記述せずに、すぐに三つ目のスラッシュでパスの開始を示しています。
ExpoでのURLスキームの変遷とRFC 3986への準拠
Expo SDK 37のアップデート前後でURLスキームの仕様が変わりました。GitHubのIssue(#10012)では、以前はmyapp://
の形式で動作していたアプリが、アップデート後にmyapp:///
の形式を要求するようになったことが報告されています。
この変更に対し、Expoの開発チームは以下のように明確に回答しています:
we changed this in SDK 37. Custom URIs with only 2 slashes aren't valid URIs, usually it consists of :///[/...]. In these custom URIs, we don't have a host and must leave that blank in order to comply with RFC 3986.
(訳:SDK 37でこの仕様を変更しました。二つのスラッシュだけのカスタムURIは有効なURIではありません。通常は :///[/...] の形式です。これらのカスタムURIではホストがないため、RFC 3986に準拠するためにその部分を空白にしておく必要があります。)
つまり、Expoの公式見解によれば:
- RFC 3986に準拠するための変更である
- ディープリンクではホスト部分が存在しないことが多い
- その場合、正しいURI形式は
scheme:///path
となる
RFC 3986の関連規定
Expoチームが言及している「RFC 3986への準拠」について、実際のRFC 3986の関連規定を見てみると:
RFC 3986のSection 3では、URIの一般構文を次のように定義しています:
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
さらにRFC 3986の同セクションには以下のような重要な記述があります:
If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character.
つまり、authorityコンポーネント(ホスト部分)が存在する場合、そのパスは空かスラッシュ「/」で始まる必要があるということです。
モバイルアプリのディープリンクでは通常authorityが空なので:
myapp:///home
という形になり、三つ目のスラッシュはパスの開始を示すことになります。
Expoでの実装方法
Expoでは、以下のようにLinking.createURL()
メソッドを使用すると、自動的に正しい形式のURLが生成されます:
// Expoの場合
import * as Linking from 'expo-linking';
// 例:'myapp:///profile' が生成される
const url = Linking.createURL('/profile');
Expo SDK 37以降では、この方法が推奨されています。
ディープリンクのURLスキームパターン
Expoの実装に基づくと、モバイルアプリのディープリンクにおいて、URLスキームのパターンは次のようになります:
myapp:/// // ホーム画面
myapp:///profile // プロフィール画面
myapp:///settings // 設定画面
ここでの三つ目のスラッシュは、空のホスト部分の後に続くパスの開始を示しています。
実装上の留意点
古いExpoコード(SDK 37以前)でmyapp://home
のようなURLを使用している場合は、myapp:///home
に修正することで、最新のExpo環境での安定した動作が期待できます。
また、URLスキームを実装する際は、次の点に注意しましょう:
- Expo SDK 37以降では、三つのスラッシュ形式(
scheme:///path
)を使用する - アプリ内での動的なリンク生成には
Linking.createURL()
を活用する - 外部からアプリを開く場合も同様の形式のURLを使用する
まとめ
Expoにおいて、URLスキームで三つのスラッシュ(///)を使用するのは、Expo開発チームがRFC 3986に準拠した実装を選択したからです。特に:
-
scheme://authority/path
の形式において - ディープリンクではホスト部分(authority)が空になる
- その結果
scheme:///path
という形式になる
この形式を使うことで、Expo環境でより安定した動作が期待できます。
次回Expoでディープリンクを実装する際には、この「三つのスラッシュ」を思い出してみてください。
Discussion