history API は「ブラウザの戻る・進むをコードから操る仕組み」
history は window.history のことで、
ブラウザの「戻る」「進む」ボタンと同じようなことを、JavaScript から行うための API です。
今までに辿ってきたページの履歴
履歴の数
一つ前に戻る
一つ先に進む
URL だけ書き換えて「遷移した風」に見せる(SPA で超重要)
こういったことを扱えます。
特に、pushState / replaceState を使うと、
「ページをリロードせずに URL だけ変える」ことができるので、
シングルページアプリ(SPA)では必須級の API になっています。
一番基本:back / forward / go で履歴を動かす
戻る・進むをコードから呼ぶ
ブラウザの戻るボタンと同じことをするのが history.back() です。
history.back(); // 1つ前のページへ戻る
history.forward(); // 1つ先のページへ進む
JavaScriptback() は「戻るボタン」、forward() は「進むボタン」と覚えてOKです。
「n 個分まとめて動かしたい」ときは history.go() を使います。
history.go(-1); // 1つ戻る(back() と同じ)
history.go(1); // 1つ進む(forward() と同じ)
history.go(-2); // 2つ前に戻る
JavaScriptマイナスで戻る、プラスで進む、というイメージです。
履歴の長さを知る:history.length
history.length で、
「このタブで辿ってきた履歴の数」が分かります。
console.log(history.length); // 例: 5
JavaScriptただし、「何個前まで戻れるか」が正確に分かるわけではありません。
あくまで「このセッションで何ステップ分の履歴があるか」の目安です。
重要ポイント:pushState / replaceState で「リロードせずに URL を変える」
ここが history API の一番おいしいところです。
少し丁寧にやります。
pushState の基本形
pushState は、
「履歴に新しいエントリを追加しつつ、URL を書き換える」メソッドです。
history.pushState(state, title, url);
JavaScriptそれぞれの意味はこうです。
state
好きなオブジェクトを入れられる(後で取り出せる「メモ」)
title
今はほぼ無視されることが多い(空文字でよい)
url
新しく表示したい URL(同一オリジン内に限る)
例えば、タブをリロードせずに /about に「遷移した風」にしたいならこうです。
history.pushState({ page: "about" }, "", "/about");
JavaScriptこれで、アドレスバーの表示は /about に変わりますが、
ページ全体のリロードは起きません。
「SPA のルーティング」がまさにこれです。
replaceState は「履歴を上書き」
replaceState は pushState に似ていますが、
「新しい履歴を追加する」のではなく、
「今の履歴を上書きする」という違いがあります。
history.replaceState({ page: "home" }, "", "/home");
JavaScript戻るボタンで戻ってきてほしくないような場面
(例: ログイン直後のリダイレクト)
では replaceState が使われます。
state は「その履歴に紐づく自由なメモ」
pushState / replaceState の第1引数 state は、
その履歴エントリに紐づく「好きなデータ」を入れておける場所です。
例えば、
history.pushState({ tab: "profile" }, "", "/user/10?tab=profile");
JavaScriptとすると、
「この URL に来たときは tab=profile だった」という情報をstate に持たせておけます。
後でこの履歴に戻ってきたとき、popstate イベントでこの state を受け取れます。
popstate イベントで「戻る・進む」を検知する
戻る・進むが押されたときに呼ばれるイベント
pushState / replaceState を使っていると、
ユーザーが「戻る」「進む」を押したときに、
自分で UI を切り替えたい場面が出てきます。
そのときに使うのが popstate イベントです。
window.addEventListener("popstate", (event) => {
console.log("popstate!", event.state);
});
JavaScriptevent.state には、pushState / replaceState で渡した state オブジェクトが入っています。
これを使って、
「どの画面を表示すべきか」を決めるのが SPA の基本パターンです。
簡単な SPA 風ルーティングの例
HTML をざっくり想像します。
<nav>
<a href="/" data-page="home">Home</a>
<a href="/about" data-page="about">About</a>
</nav>
<div id="view"></div>
JavaScript はこんな感じ。
const view = document.querySelector("#view");
function render(page) {
if (page === "home") {
view.textContent = "これはホームです";
} else if (page === "about") {
view.textContent = "これはアバウトです";
}
}
function navigate(page, url) {
history.pushState({ page }, "", url);
render(page);
}
// 初期表示
render("home");
// ナビゲーションのクリックを横取り
document.querySelector("nav").addEventListener("click", (e) => {
if (e.target.matches("a[data-page]")) {
e.preventDefault();
const page = e.target.dataset.page;
const url = e.target.getAttribute("href");
navigate(page, url);
}
});
// 戻る・進むに対応
window.addEventListener("popstate", (event) => {
const state = event.state;
if (state && state.page) {
render(state.page);
} else {
render("home");
}
});
JavaScriptここでやっていることは、
リンククリック時にページ遷移を止める
代わりに pushState で URL を変える
自分で render を呼んで画面を書き換える
戻る・進むが押されたら popstate で state.page を見て render
という流れです。
これが「SPA のルーティングの超ざっくり版」です。
history API の本領がここにあります。
history API を使うときの注意点
別ドメインには勝手に飛べない(同一オリジン制限)
pushState / replaceState の url は、
「同じオリジン(スキーム・ホスト・ポートが同じ)」である必要があります。
例えば、今 https://example.com にいるときに、
history.pushState({}, "", "https://google.com");
JavaScriptのようなことはできません。
別ドメインに行きたいときは、
素直に location.href = "https://google.com" などで遷移します。
state に入れるデータは「シリアライズ可能なもの」にする
state にはオブジェクトを入れられますが、
あまり巨大なデータや関数などは入れないほうがよいです。
基本的には、
JSON にできるような素直なオブジェクト
(数値、文字列、配列、ネストしたオブジェクトなど)
にしておくと安全です。
初心者として history API で本当に掴んでほしいこと
history は「ブラウザの戻る・進むをコードから扱うための API」
back / forward / go で履歴を移動できる
pushState / replaceState で「リロードせずに URL を変えられる」
state に「その履歴に紐づくメモ」を入れておける
popstate イベントで「戻る・進むが押されたとき」に UI を切り替えられる
まずはブラウザのコンソールで、
console.log(history.length);
history.pushState({ n: 1 }, "", "/test1");
history.pushState({ n: 2 }, "", "/test2");
console.log(history.length);
JavaScriptなどを試してみてください。
そのうえで、
「戻るボタンを押したときに画面の内容を変える小さなデモ」
を自分で書いてみると、
history API が「ただのおまけ」ではなく、
「時間と画面遷移をコントロールするための強力な道具」 だと実感できるはずです。
