😂
iOS ChromeでInertia.jsのブラウザバックがGoogle検索画面に飛ぶ問題の解決策
概要
Laravel + Inertia.js + Reactで構築したSPAで、iOS Chromeでのブラウザバックボタンが意図しないGoogle検索画面に遷移してしまう問題を解決した方法を紹介します。えげつない時間沼りましたが、結局根本解決ではなく、一時的な苦肉の策での実装(泣)
問題の詳細
発生環境
- フレームワーク: Laravel 12 + Inertia.js + React
- 問題ブラウザ: iOS Chrome(Safariは正常動作)
- 環境: 本番環境(HTTPS)で発生、開発環境(HTTP)では発生しない
問題の症状
- ログイン → ダッシュボード → ページ1 → ページ2
- ブラウザバックボタンを押す
- 期待: ページ1に戻る
- 実際: 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