0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ブラウザのデフォルトモーダルを制御してブランドコアを守る

Posted at

はじめに

多くのWebサービスでは、ユーザーが編集中のページから離脱しようとする際に確認モーダルを表示します。この機能は非常に重要なUXの一部ですが、実装する際に思わぬ課題に直面することがありましたので、記事を書こうと思います。

image.png

上の画像のようなモーダルを見たことはありませんか?

編集フォームの入力中に、間違えてリロードしてしまった時に出てくる時があります。

このようなモーダルですが、自分/自社で作成してしまおうという場合があります。
特に、プロダクトのブランドコアとしてカスタムデザインのモーダルを実装している場合、ブラウザのデフォルトの離脱防止モーダルと競合してしまう問題があります。この記事では、その解決方法について詳しく解説します。

問題:ブラウザのデフォルトモーダルとの競合

発生する問題

  • カスタムデザインの離脱防止モーダルを実装している
  • ページ遷移時に、カスタムモーダルとブラウザのデフォルトモーダルが両方表示される
  • 結果として、UXが著しく低下し、ブランドの一貫性が損なわれる

なぜこれが重要か

  1. ブランドの一貫性
    • カスタムデザインのモーダルは、プロダクトのブランドアイデンティティの一部
    • ブラウザのデフォルトモーダルは、そのブランド体験を損なう
  2. ユーザー体験
    • 2つのモーダルが表示されることで、ユーザーを混乱させる
    • 操作の手順が増え、フローが煩雑になる

解決策:ブラウザモーダルの制御

実装例

const historyPushState = useCallback((path: string) => {
  // 1. beforeunloadイベントを一時的に無効化
  const defaultLeaveEvent = window.onbeforeunload;
  window.onbeforeunload = null;
  try {
    // 2. React Routerのnavigateを使用
    navigate(path);
  } finally {
    // 3. 遷移後にbeforeunloadを復元
    window.onbeforeunload = defaultLeaveEvent;
  }
}, [navigate]);

解決策の詳細説明

  1. beforeunloadイベントの一時的な無効化
    • ページ遷移時に一時的にブラウザのデフォルトモーダルを無効化
    • 元のイベントハンドラは保存して後で復元
  2. 制御された遷移の実装
    • React Routerのnavigateを使用して適切な遷移を実現
    • ブラウザネイティブの遷移を避けることで、よりコントロールされた挙動を実現
  3. 安全な状態管理
    • try-finallyブロックで確実にイベントハンドラを復元
    • エラーが発生しても、アプリケーションの他の部分は正常に動作

このアプローチのメリット

  1. ブランドの一貫性維持
    • カスタムデザインのモーダルのみが表示される
    • プロダクトのデザインシステムに沿った体験を提供
  2. UXの改善
    • シンプルで明確な離脱フロー
    • ユーザーの混乱を防止
  3. 保守性
    • クリーンな実装で、将来的な変更にも対応しやすい
    • エラーハンドリングが適切に行われている

実装時の注意点

  1. イベントハンドラの管理
    • beforeunloadイベントの無効化は必要な時のみ行う
    • 必ず元の状態に復元する
  2. ルーティング
    • 適切なルーティングライブラリを使用する
    • ブラウザネイティブの遷移は避ける

まとめ

プロダクトのブランドコアを守りながら、優れたユーザー体験を提供することは現代のWebサービスにとって重要な課題です。この記事で紹介した方法を使用することで、ブラウザのデフォルトモーダルを適切に制御し、一貫性のあるブランド体験を実現できました。
また、この解決策は単なる技術的な問題解決以上の価値があります。プロダクトのブランドアイデンティティを守り、ユーザー体験を向上させることで、サービスの品質向上に貢献します。
今後のWeb開発において、このようなブランドコアを意識した実装がますます重要になっていくでしょう。今後も精進します。ではまたっ!

補足

beforeunloadイベント

ウェブページが閉じられる直前に発生するイベントです。以下のような場合に発火します:

  • ページのリロード
  • ブラウザタブを閉じる
  • 新しいURLへの遷移
  • ブラウザを閉じる

ページ遷移の種類と特徴

location.href による遷移

最も基本的なページ遷移方法で、ページ全体をリロードします。

// - 履歴に新しいエントリーが追加される
// - ブラウザの「戻る」ボタンで前のページに戻れる
// - beforeunloadイベントが発火する
window.location.href = '/new-page';

location.replace による遷移

現在のページを履歴から完全に置き換える遷移方法です。

// - 現在のページを履歴から置き換える
// - ブラウザの「戻る」ボタンで前のページに戻れない
// - beforeunloadイベントが発火する
window.location.replace('/new-page');

history.pushState による遷移

SPAで一般的な、ページリロードなしでの遷移を実現します。

// - 履歴に新しいエントリーを追加
// - ページのリロードは発生しない
// - beforeunloadイベントは発火しない
history.pushState({}, '', '/new-page');

React Router の navigate

React アプリケーションで推奨される、宣言的な遷移方法です。

// - SPAの文脈での遷移
// - デフォルトではページリロードなし
// - アプリケーションの状態を保持したまま遷移
navigate('/new-page');

これらの遷移方法は、それぞれ異なる特性を持っています。SPAでは主にReact RouterのnavigateやhistoryPushStateを使用し、必要に応じてlocation.replaceやlocation.hrefを使い分けることになります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?