😂

iOS ChromeでInertia.jsのブラウザバックがGoogle検索画面に飛ぶ問題の解決策

に公開

概要

Laravel + Inertia.js + Reactで構築したSPAで、iOS Chromeでのブラウザバックボタンが意図しないGoogle検索画面に遷移してしまう問題を解決した方法を紹介します。えげつない時間沼りましたが、結局根本解決ではなく、一時的な苦肉の策での実装(泣)

問題の詳細

発生環境

  • フレームワーク: Laravel 12 + Inertia.js + React
  • 問題ブラウザ: iOS Chrome(Safariは正常動作)
  • 環境: 本番環境(HTTPS)で発生、開発環境(HTTP)では発生しない

問題の症状

  1. ログイン → ダッシュボード → ページ1 → ページ2
  2. ブラウザバックボタンを押す
  3. 期待: ページ1に戻る
  4. 実際: Google検索画面に遷移してしまう

原因分析

根本原因の予想!

iOS Chromeの履歴管理とInertia.jsのSPA機能が競合し、ブラウザの履歴スタックが正しく管理されないことが原因と予想!!

環境による違い

  • 開発環境(HTTP): 問題なし
  • 本番環境(HTTPS): 問題発生
  • Safari: 問題なし
  • Android Chrome: 問題なし

解決策

アプローチ

いっぱい履歴管理のコード書いてみたんです、、、でも解決せずで、、、(泣)
複雑な履歴管理コードを書く代わりに、条件分岐リンクコンポーネントを作成して解決しました。

1. SmartLinkコンポーネントの作成

resources/js/components/smart-link.tsx
import { Link } from '@inertiajs/react';
import { ComponentProps } from 'react';

type SmartLinkProps = ComponentProps<typeof Link> & {
    children: React.ReactNode;
};

/**
 * iOS Chrome専用のスマートリンクコンポーネント
 * iOS Chromeではaタグ、その他のブラウザではInertia.jsのLinkタグを使用
 */
export default function SmartLink({ children, ...props }: SmartLinkProps) {
    // iOS Chromeかどうかを判定
    const isIOSChrome = () => {
        const userAgent = navigator.userAgent;
        const isIOS = /iPhone|iPad|iPod/.test(userAgent);
        const isChrome = /CriOS/.test(userAgent);
        return isIOS && isChrome;
    };

    // iOS Chromeの場合はaタグを使用
    if (isIOSChrome()) {
        return (
            <a href={props.href} className={props.className}>
                {children}
            </a>
        );
    }

    // その他のブラウザではInertia.jsのLinkタグを使用
    return <Link {...props}>{children}</Link>;
}

2. サイドバーナビゲーションでの使用

resources/js/components/nav-main.tsx
import SmartLink from '@/components/smart-link';

// 従来のLinkタグをSmartLinkに置き換え
<SmartLink href={item.href} prefetch>
    {isLearned && <Check className="mr-1 h-4 w-4 !text-green-600" />}
    {item.icon && <item.icon />}
    <span>{item.title}</span>
</SmartLink>

解決策のメリット

1. シンプルな実装

  • 複雑な履歴管理コードが不要
  • 約30行のコンポーネントで解決
  • 保守性が高い

2. ブラウザ別最適化

  • iOS Chrome: 通常のaタグによるページ遷移(ブラウザバック正常動作)
  • その他のブラウザ: SPAの利点を保持(高速遷移、プリフェッチ)

解決策のデメリット

パフォーマンス

iOS Chromeでは通常のページ遷移になるため、初期読み込み時間が若干増加する可能性があります。

まとめ

この解決策により、以下の成果を得ることができました。

  • ✅ iOS Chromeでのブラウザバック問題を解決
  • ✅ その他のブラウザではSPAの利点を保持
  • ✅ コードの簡潔性を維持
  • ✅ 保守性の向上

複雑な履歴管理コードを書く代わりに、条件分岐による適切なリンク方式の選択というシンプルなアプローチで問題を解決できました。

参考リンク


この記事が同じ問題に悩む開発者の方々の参考になれば幸いです。もっといい解決方法があればどなたか教えてください!!Laravel×Inertia.jsではデフォルトでiOSのCromeブラウザバックエラーがあると思います!今後もLaravelを使っていく私としては深刻な悩みです(;_;)

Discussion