
デザインの視点から考える、共有可能なモーダルダイアログの設計パターン
ここではモーダルダイアログをそもそも採用すべきかどうかについてを対象としていません。この話についてはすでに多くの記事があり、ここでは次のサイトを紹介しておきます。
前提
この記事で扱うのは、次の2つの条件が重なる場合の設計パターンです。
- モーダルダイアログを表示された状態をアプリケーションの利用ユーザーが他の人に共有したい、あるいはブックマークしたいこと
- Next.jsを使用していること
このような場合、モーダルダイアログのデザインだけでなく、その内容を単独で表示する詳細ページも必要になります。
わかりにくいので、実際の例としてInstagramを見てみましょう。
(1)投稿一覧 | (2)投稿一覧から画像クリック | (3)画像クリック後、リロード |
---|---|---|
![]() |
![]() |
![]() |
「(1)投稿一覧」の画面から画像をクリックすると「(2)投稿一覧から画像クリック」の表示になり、URLも変化します。この例の場合ではhttps://www.instagram.com/hbsnow.dev/
からhttps://www.instagram.com/p/DJyTikyTdUv/
に変化します。
重要なのは、この新しいURLを他の人に共有した場合、受け取った人には「(3)画像クリック後、リロード」のようにモーダルではなく独立した詳細ページとして表示される点です。
つまり、アプリのデザインとしてはモーダルダイアログと、その内容を表示する詳細ページの両方が必要になります。この二つの異なる表示形式がなぜ必要になるかが本記事のテーマです。
サンプルサイトで考える対応策の例
サンプルサイトとしてECサイト風のデモを作ってみました。デザインはほとんどv0に作ってもらい、コンポーネントを調整しています。
商品一覧 | モーダルダイアログ |
---|---|
![]() |
![]() |
商品の一覧ページから、商品をクリックするとモーダルダイアログが表示されて、カートに追加できるといったサイトになります。
こういったサイトの場合、ダイアログを開いて商品の詳細が見られる状態で誰かに共有したくなるニーズがありそうです。
対応策1: モーダルダイアログをやめる
そもそもモーダルダイアログである必要でなければ、モーダルダイアログをやめて商品の詳細ページを別に作ればよいだけです。
商品一覧 | 詳細ページ |
---|---|
![]() |
![]() |
対応策2: モーダルダイアログを開いた状態のURLを用意する
モーダルを開いたときのURLを別に用意することで、URLを共有可能にする方法です。
商品一覧 | モーダルダイアログ |
---|---|
![]() |
![]() |
商品一覧のURLが/products
だとすると、モーダルダイアログを開いた状態のURLは/products?id=1
あるいは/products/1
になるでしょうか。サンプルサイトでは前者の方法で実装しています。
悪くはなさそうに見えますが、おそらくこういったことをしているアプリは少ないはずです。少なくとも自分は見つけることができませんでした。
デメリットを考えてみます。
1. URLとして扱ったとき、唐突にモーダルダイアログが表示される
例えばSNSでシェアして受け取った人が、どんなページかわからないままいきなりモーダルが開いた状態になったりします。そのため急に重なって表示されるページがやや唐突に感じられる可能性があります。
特にモーダルダイアログの展開にアニメーションが有効になっている場合、初回表示でもアニメーションをしてしまうため違和感は大きくなります。
2. モーダルとページの「優先度」や「文脈」を伝えにくい
通常のページ遷移であれば、個別の商品詳細ページが「メインコンテンツ」であることをユーザーに明確に示せます。しかしURLで直接共有された場合、一覧ページがあってそこにオーバーレイ表示されているコンテンツであるという文脈が見えにくくなります。
アプリケーションや状況によってはモーダルの下に表示されているコンテンツが一覧にはならない可能性もあるはずです。
3. SEOの考慮
SEOの考慮が必要であれば/products?id=1
ではなく/products/1
での実装が必要になります。
ただし/products/1
で実装した場合にも、裏に一覧を持つのでコンテンツ量があるため考慮点は多くなりますし、複数ページからダイアログが呼び出しされる場合には注意が必要です。
例えば/categories
からモーダルダイアログが呼び出される場合には、/products/1
にリンクすると裏側が商品一覧になってしまうため、/categories/1
の実装も必要になりcanonical urlの設定が必要になります。そしてこれは呼び出し元が増えるたびその数だけ増え続けるため、呼び出し元が複数になりそうであればこの実装は避けたほうが良さそうです。
4. 実装面
ページ読み込み時にモーダルを表示するための状態管理やルーティング処理が複雑になります。SSRしている場合にはデータの取得方法を考える必要もでてきます。
またそもそも必要なものは詳細のデータのみであるため、モーダルの下で読み込むデータだったり表示するためのリソースが無駄になります。
対応策3: 一覧からの遷移ではモーダルを表示させて、直接商品表示する場合には詳細ページを表示させる
商品一覧 | モーダルダイアログ | 詳細ページ |
---|---|---|
![]() |
![]() |
![]() |
商品一覧から商品を選択したときにはモーダルダイアログを表示させ、モーダルダイアログを表示したときのURLをそのまま開いたときには詳細ページとして表示させる方法です。
実際にサンプルサイトを開いてみて、商品一覧から商品を開いてモーダルダイアログを表示させてからリロードすると、どういった動作なのかがわかりやすいはずです。
対応策2であげた課題はおおむね解消されています。
まとめ
モーダルダイアログを使用する際、ユーザーがその状態を共有したいというニーズに応えるためには、単にUIの設計だけでなく、URLの設計と詳細ページの用意が必要です。
本記事で紹介した対応策3のアプローチは、多くのケースで最適な解決策となるでしょう。一覧からの遷移時にはモーダルダイアログを表示し、直接URLにアクセスした場合には詳細ページを表示するという方法です。これによって、ユーザー体験を損なうことなく、共有可能性とSEOの両方に配慮したデザインが実現できます。
デザイナーとエンジニアが協力して、モーダルダイアログと詳細ページの両方のデザインを初期段階から考慮することで、後からの修正や追加実装の手間を大幅に減らすことができるでしょう。ぜひサンプルサイトを参考に、あなたのプロジェクトに最適な実装を検討してみてください。