| この記事の要点 |
|
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アノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38