SPA ルーティング

SPA でブラウザの URL とコンポーネントの表示を同期させ、ページ遷移なしで画面を切り替える仕組み

フロントエンド

SPA ルーティングとは

SPA ルーティングは、Single Page Application でブラウザの URL とコンポーネントの表示を同期させる仕組みである。ページ全体をリロードせずに、URL の変更に応じて表示するコンポーネントを切り替える。History API (pushState, popstate) を使って、ブラウザの戻る/進むボタンにも対応する。

仕組み

従来の MPA (Multi Page Application):
  /about にアクセス → サーバーが about.html を返す → ページ全体をリロード

SPA ルーティング:
  /about にアクセス → JavaScript が URL を検知 → About コンポーネントを表示
  (サーバーへのリクエストなし、ページリロードなし)

React Router での実装

import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/users/123">User</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/users/:id" element={<UserProfile />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

Hash ルーティング vs History ルーティング

方式 URL 例 サーバー設定
Hash example.com/#/about 不要
History example.com/about フォールバック設定が必要

History ルーティング (推奨) は # がなくクリーンな URL だが、サーバー側で全パスを index.html にフォールバックする設定が必要だ。

/about にアクセスすると S3 は 404 を返すが、CloudFront が index.html にフォールバックし、SPA の JavaScript がルーティングを処理する。

コード分割との連携

const About = lazy(() => import('./pages/About'));
const UserProfile = lazy(() => import('./pages/UserProfile'));

// /about にアクセスした時だけ About のコードを読み込む
<Route path="/about" element={
  <Suspense fallback={<Loading />}>
    <About />
  </Suspense>
} />

SEO の課題

SPA は初期 HTML が空 (<div id="root"></div>) のため、検索エンジンのクローラーが JavaScript を実行しないとコンテンツを認識できない。対策:

  • SSR (Next.js): サーバーで HTML を生成
  • SSG: ビルド時に静的 HTML を生成
  • プリレンダリング: クローラー向けに事前レンダリング

ルーティング方式の比較

方式 URL 例 サーバー設定
Hash /#/about 不要
History API /about フォールバック必要

実務での活用方法は関連書籍にも詳しい。

関連用語