プライベートモードや設定で無効化されている
プライベートブラウジングやシークレットモードでは、localStorageの挙動が通常と異なります。書き込もうとすると例外になったり、書けてもタブを閉じると消えたりします。ユーザーがそのモードで開いていると、保存できないように見えるのはこのためです。
また、ブラウザの設定やプライバシー保護機能でサイトのストレージ利用が制限されている場合もあります。サードパーティ的な文脈(iframe内など)では、ストレージへのアクセスがそもそも拒否されることがあります。まずは通常モードで再現するかを確かめ、モード依存かどうかを切り分けてください。
例外を握りつぶさず捕捉する
localStorageへの書き込みは、状況によって例外を投げます。代表が容量上限を超えたときのQuotaExceededErrorです。setItemを単に呼んでいるだけだと、失敗してもコードは素通りし、保存されていないことに気づけません。
setItemをtry/catchで囲み、失敗時にエラーをコンソールへ出すか、ユーザーに通知するようにしてください。これで「保存処理に到達しているのに失敗している」のか「そもそも保存処理が呼ばれていない」のかを区別できます。利用前に簡単なテスト書き込みでlocalStorageが使えるか判定しておくのも有効です。
症状別チェック表
localStorageが使えない・保存されないは、症状を分けずに直そうとすると原因探しが長引きます。まず「自分だけで起きるのか」「全員で起きるのか」「特定ブラウザだけか」「差し替え後だけか」を切り分けます。
確認順序を固定すると、相対パス、ファイル名、キャッシュ、認証、外部読み込みのどこで止まっているかが見えます。修正後はローカル確認だけで終わらせず、実際の共有URLで再表示して、相手と同じ条件で直ったことを確認します。
- 自分だけ表示されない: キャッシュ、ログイン状態、ブラウザ拡張、端末幅を確認する
- 全員で表示されない: ファイル構成、相対パス、大文字小文字、アップロード漏れを見る
- 一部だけ崩れる: CSS/画像/JSごとに読み込みエラーを分ける
- 差し替え後だけ古い: URL、キャッシュ、更新対象ファイルの取り違えを確認する
保存できるのは文字列だけ
localStorageに保存できる値は文字列です。オブジェクトや配列をそのまま渡すと、意図せず文字列化されて [object Object] のような値になり、読み出しても元に戻りません。保存時にJSON.stringify、読み出し時にJSON.parseを通すのが基本です。
読み出し側でparseを忘れる、あるいは保存されていないキーをparseしようとしてnullで失敗する、というミスもよくあります。getItemの結果がnullかどうかを確認してからparseする、というガードを入れておくと安定します。
保存されない原因を切り分ける手順
原因が読めないときは、外側の条件から順に確認すると早いです。次の手順を試してください。
- 通常モード(プライベートでない)で再現するか確認する
- 開発者ツールのApplication/StorageタブでlocalStorageの中身を直接見る
- setItemをtry/catchで囲み、例外が出ていないかコンソールで確認する
- 保存値がJSON.stringifyされ、読み出しでJSON.parseされているか見直す
- 容量上限に達していないか、不要なキーを削除して試す
- 別のブラウザや別端末でも同じ症状が出るか確かめる
共有環境でデータ保持を確認する
localStorageはオリジン(ドメイン)ごとに分離して保存されます。ローカルのfile://で開いて動いても、実際に配信されるドメイン上では挙動が変わることがあります。実環境に近い形で確認しておくと安心です。
ギガサイト便にHTMLやZIPをドロップすると 〇〇.giga-site.com というサブドメインで配信され、HTTPS環境でlocalStorageの保存・読み出しを試せます。プライベートモードや別端末で開いてもらえば、データが保持されるかをレビュー相手と一緒に確認できます。確認・レビュー用途の一時共有に向いています。
よくある質問
localStorageに保存したのにリロードすると消えています。
プライベートブラウジングで開いている可能性があります。このモードではタブを閉じると消える、または書き込み自体が失敗することがあります。まず通常モードで再現するか確認し、保存処理をtry/catchで囲んで例外が出ていないかを見てください。
オブジェクトを保存したのに読み出すと壊れています。
localStorageは文字列しか保存できません。オブジェクトはJSON.stringifyで文字列化して保存し、読み出し時にJSON.parseで戻してください。parseを忘れると元のデータ構造に戻りません。
QuotaExceededErrorが出ます。
保存容量の上限を超えています。不要なキーを削除する、保存するデータ量を減らす、といった対処が必要です。setItemをtry/catchで囲んでおけば、上限到達をユーザーに知らせて代替動作に切り替えられます。
ローカルでは動くのに配信環境で保存できません。
localStorageはオリジン単位で分離されるため、file://と実際のドメインでは別扱いになります。実環境に近い形で確認するのが確実です。ギガサイト便で配信URLを発行すれば、HTTPS環境や別端末で保存挙動を試せます。
原因が分からないときはどこから確認すべきですか?
まず自分だけの問題か全員の問題かを分けます。次にシークレットウィンドウ、別ブラウザ、スマホで確認し、ファイル構成・相対パス・キャッシュ・認証設定を順に見ます。