「ダークモードの設定をリロード後も覚えておきたい」「入力途中のフォームの値をブラウザに一時保存しておきたい」といった場面で役立つのが、JavaScript の localStorage と sessionStorage です。これらは Web Storage API と呼ばれる仕組みで、サーバーを使わずにブラウザ側へデータを保存できます。この記事では setItem() / getItem() などの基本操作、localStorage と sessionStorage の違い、文字列しか保存できないという制約を JSON.stringify() で乗り越える方法、保存できる容量や Cookie との違いまで、初心者向けに実際のコードとともに解説します。
目次
Web Storage API でブラウザにデータを保存する
Web Storage API は、ブラウザの中に「キーと値」のペアでデータをためておくための仕組みです。データはユーザーの端末(ブラウザ)に保存されるため、ページをリロードしてもサーバーへ問い合わせることなく、保存しておいた値をすぐに読み出せます。用意されているのは localStorage と sessionStorage の2つで、どちらもまったく同じメソッドで操作できます。違いは「データがいつまで残るか」だけです(後述します)。
どちらも window オブジェクトのプロパティとして最初から使えるので、ライブラリの読み込みなどは不要です。まずは基本となる読み書きから見ていきましょう。
setItem / getItem / removeItem で読み書きする
データの保存には setItem(キー, 値) を、取り出しには getItem(キー) を使います。キーも値も文字列です。保存したデータを消すには removeItem(キー)、すべて消すには clear() を使います。
// 値を保存する(キー: "username"、値: "taro")
localStorage.setItem("username", "taro");
// 値を取り出す
const name = localStorage.getItem("username");
console.log(name); // "taro"
// 保存されていないキーを取り出すと null が返る
console.log(localStorage.getItem("nothing")); // null
// 特定のキーを削除する
localStorage.removeItem("username");
// すべてのデータを削除する
localStorage.clear();
ここで覚えておきたいのが、存在しないキーを getItem() で読み出すと null が返るという点です。値が保存されているかどうかで処理を分けたいときは、null かどうかを判定するのが基本になります。
主なメソッドとプロパティをまとめると次のとおりです。localStorage でも sessionStorage でも、まったく同じものが使えます。
| メソッド / プロパティ | 説明 |
|---|---|
setItem(key, value) | キーと値のペアを保存する(同じキーがあれば上書き) |
getItem(key) | キーに対応する値を取り出す。なければ null |
removeItem(key) | 指定したキーのデータを削除する |
clear() | 保存されているすべてのデータを削除する |
key(index) | index 番目(0始まり)のキー名を返す |
length | 保存されているデータの個数(プロパティ) |
length と key() を組み合わせると、保存されているデータを順番に取り出せます。たとえば、いま何が保存されているかをすべて確認したいときに使えます。
localStorage.setItem("theme", "dark");
localStorage.setItem("lang", "ja");
// 保存件数
console.log(localStorage.length); // 2
// すべてのキーと値を順に取り出す
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i); // i番目のキー名
const value = localStorage.getItem(key); // その値
console.log(key, value); // "theme" "dark" / "lang" "ja"
}
localStorage と sessionStorage の違い
2つのストレージは操作方法が同じなので、迷うのは「どちらを使うか」だけです。違いは大きく2つあります。1つ目はデータがいつまで残るか(永続性)です。localStorage に保存したデータは、明示的に削除しない限りブラウザを閉じても残り続けます。一方 sessionStorage のデータは、そのタブ(セッション)を閉じると消えます。
2つ目はタブ間での共有です。localStorage は同じサイト(同一オリジン)であれば複数のタブやウィンドウで同じデータを共有します。sessionStorage はタブごとに独立していて、別のタブからは見えません。それぞれの性質を表にまとめます。
| localStorage | sessionStorage | |
|---|---|---|
| データが残る期間 | 削除するまで永続(ブラウザを閉じても残る) | タブを閉じると消える |
| タブ・ウィンドウ間の共有 | 同一オリジンで共有される | そのタブ内だけ(共有されない) |
| 主な用途 | テーマ設定・ログイン状態の保持など長く残したいもの | 入力の一時保存・一度きりのフラグなど |
たとえばダークモードの設定のように「次にサイトを訪れたときも覚えておいてほしい」値は localStorage が向いています。逆に「このタブで作業している間だけ覚えておければよい」一時的な値なら sessionStorage が適しています。
オブジェクトや配列を保存する(JSON.stringify / JSON.parse)
Web Storage には 文字列しか保存できないという大きな制約があります。オブジェクトや配列をそのまま setItem() に渡すと、勝手に文字列化されて "[object Object]" という使い物にならない値になってしまいます。
const user = { name: "taro", age: 28 };
// オブジェクトをそのまま保存すると…
localStorage.setItem("user", user);
console.log(localStorage.getItem("user")); // "[object Object]" ← 壊れる
そこで、オブジェクトや配列を保存するときは JSON.stringify() で JSON 文字列に変換してから保存します。取り出すときは逆に JSON.parse() で文字列をオブジェクトに戻します。この「保存時に stringify、取得時に parse」がセットの定番パターンです。
const user = { name: "taro", age: 28 };
// 保存:オブジェクト → JSON文字列にしてから setItem
localStorage.setItem("user", JSON.stringify(user));
// 取得:文字列を取り出して JSON.parse でオブジェクトに戻す
const saved = JSON.parse(localStorage.getItem("user"));
console.log(saved.name); // "taro"
console.log(saved.age); // 28
// 配列も同じように扱える
const todos = ["買い物", "掃除", "勉強"];
localStorage.setItem("todos", JSON.stringify(todos));
const savedTodos = JSON.parse(localStorage.getItem("todos"));
console.log(savedTodos[0]); // "買い物"
注意したいのは、保存されていないキー(getItem() が null を返す場合)をそのまま JSON.parse() に渡すと null がそのまま返る点や、保存されている文字列が壊れていると JSON.parse() がエラーになる点です。安全に扱いたいときは、値が null かどうかを先に確認しておくとよいでしょう。
const raw = localStorage.getItem("user");
// null でなければ parse、なければ初期値を使う
const user = raw ? JSON.parse(raw) : { name: "ゲスト", age: 0 };
console.log(user.name);
実践例:ダークモードの設定を記憶する
localStorage の典型的な使いどころが、テーマ(ダークモード)の設定の記憶です。ボタンで切り替えた状態を保存しておき、次にページを開いたときに前回の状態を復元します。流れは「ページ読み込み時に保存値を読んで反映」「切り替え時に保存」の2つです。
const button = document.querySelector("#theme-toggle");
// 1. ページ読み込み時:保存されたテーマを復元する
if (localStorage.getItem("theme") === "dark") {
document.body.classList.add("dark");
}
// 2. ボタンで切り替えたら、その状態を保存する
button.addEventListener("click", () => {
document.body.classList.toggle("dark");
// 現在ダークかどうかを localStorage に記録
const isDark = document.body.classList.contains("dark");
localStorage.setItem("theme", isDark ? "dark" : "light");
});
同じ考え方で、入力フォームの値を一時保存することもできます。input イベントのたびに値を保存し、読み込み時に復元すれば、誤ってリロードしても入力内容が消えません。
const input = document.querySelector("#draft");
// 読み込み時:保存された下書きを復元
input.value = localStorage.getItem("draft") || "";
// 入力のたびに保存
input.addEventListener("input", () => {
localStorage.setItem("draft", input.value);
});
保存できる容量の目安と Cookie との違い
Web Storage に保存できる容量は仕様で厳密に決まっているわけではありませんが、多くのブラウザでオリジンごとにおよそ 5MB 前後が目安とされています。テキストや設定値、小さな JSON を保存するには十分ですが、画像のような大きなデータや無制限のデータを入れる用途には向きません。容量を超えると setItem() が例外を投げるため、大量に保存する場合は注意が必要です。
似た仕組みに Cookie がありますが、性質はかなり異なります。Cookie はサーバーへのリクエストのたびに自動で送信されるのに対し、Web Storage のデータはサーバーへ送られず、あくまでブラウザ内(JavaScript)からだけ参照されます。そのため、ログイン認証のようにサーバー側で読みたい情報は Cookie、画面表示の設定のようにブラウザ内で完結する情報は Web Storage、というように使い分けるのが一般的です。容量も Cookie が 1 件あたり 4KB 程度なのに対し、Web Storage はずっと多くのデータを保存できます。
保存したはずの値が取り出せないとき
「保存したのに getItem() が null を返す」「数値を入れたはずなのに文字列になっている」といったつまずきは、Web Storage の性質を押さえると防げます。
数値や真偽値は文字列として戻ってくる
Web Storage は値をすべて文字列として保存します。そのため setItem("count", 5) のように数値を渡しても、取り出すときには文字列の "5" になります。数値として計算したいときは Number() で変換が必要です。同様に true / false も "true" / "false" という文字列で戻ってくるため、そのまま条件判定に使うと意図しない結果になります。
localStorage.setItem("count", 5);
const count = localStorage.getItem("count");
console.log(count); // "5"(文字列)
console.log(count + 1); // "51"(文字列の連結になってしまう)
console.log(Number(count) + 1); // 6(数値に変換すれば正しく計算できる)
オリジンが違うとデータは共有されない
Web Storage のデータは「オリジン」(プロトコル・ドメイン・ポートの組み合わせ)ごとに分けて保存されます。http:// と https:// の違いや、サブドメインの違いがあると別物として扱われ、保存したデータを読み出せません。ローカルのファイル(file://)で開いたときと、サーバー経由(http://localhost)で開いたときでも別扱いになるため、「保存したはずなのに見つからない」ときはアクセスしている URL を確認してみてください。
まとめ
localStorage と sessionStorage は、サーバーを使わずにブラウザへ手軽にデータを保存できる便利な仕組みです。要点を振り返ります。
- 保存は
setItem(key, value)、取得はgetItem(key)(なければnull) - 削除は
removeItem(key)/clear()、件数はlength、キー名はkey(index)で取得 localStorageは永続・タブ間で共有、sessionStorageはタブを閉じると消える- 保存できるのは文字列だけ。オブジェクトや配列は
JSON.stringify()/JSON.parse()で変換する - 数値や真偽値も文字列で戻るため、必要に応じて
Number()などで変換する - 容量の目安は約5MB。サーバーに送られる Cookie とは用途が異なる
まずは「文字列で保存する」「オブジェクトは JSON 化する」という2点を押さえれば、設定の記憶や入力の一時保存といった実用的な機能をすぐに作れます。