| この記事の要点 |
|
History API とは
HTML5 History API は、ブラウザの戻る/進む履歴を JavaScript から操作する API です。ページをリロードせずに URL を変更できるため、SPA(Single Page Application)のルーティング機構の中核として広く使われています。Vue Router、React Router、Next.js Client Router、SvelteKit などのフレームワークも内部では History API を呼んでいます。
主要メソッド一覧
| API | 動作 | 履歴に追加 |
|---|---|---|
history.pushState(state, title, url) | 新エントリ追加 | ○ |
history.replaceState(state, title, url) | 現エントリを置換 | × |
history.back() | 1 つ戻る(戻るボタン同等) | - |
history.forward() | 1 つ進む | - |
history.go(n) | n エントリ移動(負数で戻る) | - |
history.length | 現セッションの履歴数 | - |
history.state | 現エントリの state オブジェクト | - |
history.scrollRestoration | 戻り時のスクロール位置復元(auto/manual) | - |
pushState / popstate の最小例
<nav>
<a href="/home" data-link>Home</a>
<a href="/about" data-link>About</a>
</nav>
<main id="view">Home Page</main>
<script>
function render(path) {
document.getElementById('view').textContent = path + ' Page';
}
// リンククリックで pushState
document.querySelectorAll('[data-link]').forEach(a => {
a.addEventListener('click', (e) => {
e.preventDefault();
const url = a.getAttribute('href');
history.pushState({ path: url }, '', url);
render(url);
});
});
// 戻る/進むで popstate
window.addEventListener('popstate', (e) => {
const path = (e.state && e.state.path) || location.pathname;
render(path);
});
</script>
pushState と replaceState の違い
| 用途 | 選択 |
|---|---|
| 通常のページ遷移 | pushState |
| クエリ更新(フィルタ変更等)で戻る対象にしたくない | replaceState |
| ログイン後のリダイレクト(ログイン画面を履歴に残さない) | replaceState |
| モーダルの開閉を URL に反映 | 状況次第(戻るで閉じたいなら pushState) |
location.hash 方式との比較
// 古典: ハッシュベース(HTML5 以前)
location.hash = '#/about';
window.addEventListener('hashchange', () => {
console.log(location.hash);
});
// URL: https://example.com/#/about
// モダン: History API
history.pushState(null, '', '/about');
// URL: https://example.com/about
| 比較 | hash 方式 | History API |
|---|---|---|
| URL 見た目 | # 入りで不格好 | 通常 URL でクリーン |
| SEO | 通常クロール対象外 | SSR / プリレンダリングで対応可 |
| サーバ設定 | 不要 | ★ 全パスを index.html へフォールバックが必要 |
| 古い IE 対応 | IE6+ で動く | IE10+ |
SPA フォールバックの設定例
History API で /about という URL に切り替えても、ブラウザをリロードするとサーバが本当に /about を返そうとして 404 になります。これを防ぐためサーバで「全パスを index.html に返す」設定を入れます。
# Nginx
location / {
try_files $uri $uri/ /index.html;
}# Apache (.htaccess)
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]// Express
const path = require('path');
app.use(express.static('dist'));
app.get('*', (_req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
URL / URLSearchParams との連携
// 現在の URL からクエリ取得
const params = new URLSearchParams(location.search);
const page = params.get('page') || '1';
// クエリだけ書き換え(履歴に追加せず replace)
params.set('page', '2');
history.replaceState(null, '', '?' + params.toString());
// URL オブジェクトで安全に組み立て
const url = new URL(location.href);
url.pathname = '/items';
url.searchParams.set('sort', 'asc');
history.pushState(null, '', url);
scrollRestoration
「戻る」操作で前ページのスクロール位置を復元するかをコントロールできます。SPA では自前で復元したい場合があるので manual にする運用が一般的です。
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
// 自前でスクロール位置を保存
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('scroll:' + location.pathname, scrollY);
});
window.addEventListener('load', () => {
const y = sessionStorage.getItem('scroll:' + location.pathname);
if (y) window.scrollTo(0, +y);
});
Router フレームワークの内部
| フレームワーク | History API の使い方 |
|---|---|
| Vue Router (createWebHistory) | history.pushState + popstate リスナ |
| React Router (BrowserRouter) | history パッケージ経由で History API |
| Next.js App Router | 独自 Router、Soft Navigation に History API |
| SvelteKit | fetch + History API + クライアントナビ |
| Astro View Transitions | History API + ViewTransition API |
FAQ
Q: pushState の第 2 引数 title は何を入れる?
A: ほとんどのブラウザで無視されます。空文字 "" で OK。document.title を別途代入してください。
Q: popstate が pushState 直後にも発火する?
A: 発火しません。popstate はユーザの戻る/進む操作と history.back() 等のメソッド呼び出しでのみ発火します。
Q: 別オリジンに pushState できる?
A: できません。同一オリジン内のパス変更のみ許可。クロスオリジンは location.href 代入で通常遷移。
子ページ
子ページはありません
同階層のページ
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- djangoのテンプレートの作成とヘッダー・フッターの共通化 2026-10-03 21:41:49
- テンプレートフラグメント(ヘッダー等の共有化) 2026-10-03 21:41:49
- reCAPTCHA v3 使い方(サンプル付き) 2026-10-03 21:37:05
- Content-Type一覧|MIMEタイプとはとHTTPでの主な使用場面 2026-10-03 21:37:05
- SpringにおけるAOPの使い方 2026-10-03 21:37:05
- X (Twitter) API でツイートできないがエラーが出ない問題の原因と対処 2026-10-03 11:33:01
- X (Twitter) API アプリケーション登録完全ガイド|v2・Bearer Token・OAuth 2.0 PKCE 2026-10-03 11:33:01
- X (Twitter) API 完全ガイド|従量課金の料金・単価(2026年10月)と v2 移行 2026-10-03 11:32:40
- Google DeepMind とは?Gemini・AlphaFold の開発元 2026-10-03 11:26:56
- Cursor とは?AI 統合型コードエディタの使い方・料金 2026-10-03 11:26:56
- Claude (Anthropic) とは?AIチャットの使い方・モデルファミリ・API 2026-10-03 11:26:56
- AIベンダー一覧:OpenAI・Anthropic・Google DeepMind・Microsoft・Meta 2026-10-03 11:26:56
- クラウド・インフラ完全ガイド — AWS/Azure/GCP/Kubernetes 2026-10-03 11:26:56
- テキストエディタ完全比較 (VS Code / Cursor / Vim / Emacs / IDE) 2026-10-03 11:26:56
- プログラミング学習プラットフォーム|Scratch・micro:bit ほか 2026-10-03 11:26:56