How to check localstorage in chrome
Open the page in Chrome, press F12, and run JSON.stringify(localStorage, null, 2) in the Console. Chrome prints every key and value held for the current origin. The Application panel, under Local storage, lists the same pairs and lets you edit one in place. A different port is a different store.
Why check this
This check belongs in the regression pass for anything that keeps client state: a logout, a consent banner, a feature flag, a draft that survives a refresh. The failure it prevents is specific. A logout route that clears the session cookie but leaves user and flags in local storage hands the next person on that machine the previous account's name in the header, and the application then sends a stale flag set to the API on the first request.
Run it on staging after any release that renames a stored key. A renamed key does not delete the old one, so two generations of state sit in the same store and the code reads whichever it looks for first. Run it again when a bug report says the problem clears after a hard refresh, which usually means the value on disk and the value in memory disagree.
Prerequisites
- Chrome with DevTools. The figures below are one capture on one machine, Chrome 152.0.7977.76 on Windows 11, on 2026-09-11. Character counts and behaviour are stable across builds, key order is not.
- Node 22, to serve the demo page. Save this as
storage-demo.mjs. It answers on two ports, which makes one file into two origins.
// storage-demo.mjs: one page, served on two ports, so the same file is two origins.
import { createServer } from 'node:http';
const page = `<!doctype html><meta charset="utf-8"><title>storage demo</title>
<h1>storage demo</h1>
<script>
localStorage.setItem('theme', 'dark');
localStorage.setItem('cart', JSON.stringify({ items: 2, total: '41.00' }));
sessionStorage.setItem('wizardStep', '3');
sessionStorage.setItem('csrfToken', 'a1b2c3');
</script>`;
for (const port of [8731, 8732]) {
createServer((req, res) => {
res.setHeader('content-type', 'text/html; charset=utf-8');
res.end(page);
}).listen(port);
}
console.log('serving http://localhost:8731/ and http://localhost:8732/');
- The MDN reference for Window.localStorage for the interface, and the Storage interface for the member names that matter in step 3.
Steps
- Step 1.
Start the demo page. Stop it with Ctrl+C when the run is over.
node storage-demo.mjsserving http://localhost:8731/ and http://localhost:8732/ - Step 2.
Open
http://localhost:8731/in Chrome, press F12, select the Console tab and read the whole store in one expression.JSON.stringify(localStorage, null, 2){ "theme": "dark", "cart": "{\"items\":2,\"total\":\"41.00\"}" }DevTools lists the same pairs under Application, Storage, Local storage,
http://localhost:8731. - Step 3.
Ask whether a key exists, in the three ways people write it.
localStorage.setItem('emptyNote', ''); JSON.stringify({ 'getItem("cart")': localStorage.getItem('cart'), 'getItem("nope")': localStorage.getItem('nope'), '"nope" in localStorage': 'nope' in localStorage, 'getItem("emptyNote")': localStorage.getItem('emptyNote'), 'Boolean(getItem("emptyNote"))': Boolean(localStorage.getItem('emptyNote')), 'getItem("emptyNote") !== null': localStorage.getItem('emptyNote') !== null, '"length" in localStorage': 'length' in localStorage, 'getItem("length")': localStorage.getItem('length'), 'localStorage.length': localStorage.length, }, null, 2){ "getItem(\"cart\")": "{\"items\":2,\"total\":\"41.00\"}", "getItem(\"nope\")": null, "\"nope\" in localStorage": false, "getItem(\"emptyNote\")": "", "Boolean(getItem(\"emptyNote\"))": false, "getItem(\"emptyNote\") !== null": true, "\"length\" in localStorage": true, "getItem(\"length\")": null, "localStorage.length": 3 }Two lines in that block disagree.
"length" in localStorageistruewhilegetItem("length")isnull, becauselengthis a member of the Storage interface and not a stored key. OnlygetItem(key) !== nullanswers the question you asked. - Step 4.
Confirm what the store does to a value that is not a string.
localStorage.setItem('user', { id: 7 }); localStorage.setItem('flag', false); JSON.stringify({ 'getItem("user")': localStorage.getItem('user'), 'getItem("flag")': localStorage.getItem('flag'), 'typeof getItem("flag")': typeof localStorage.getItem('flag'), 'Boolean(getItem("flag"))': Boolean(localStorage.getItem('flag')), 'JSON.parse(getItem("flag"))': JSON.parse(localStorage.getItem('flag')), }, null, 2){ "getItem(\"user\")": "[object Object]", "getItem(\"flag\")": "false", "typeof getItem(\"flag\")": "string", "Boolean(getItem(\"flag\"))": true, "JSON.parse(getItem(\"flag\"))": false }Booleanof the storedfalseistrue, because the stored value is the four-character stringfalse. Any feature flag read without a parse is on. - Step 5.
Write two keys, reload the page, and read them back.
localStorage.setItem('theme', 'light'); localStorage.setItem('lastSeen', '2026-09-11T10:00:00Z'); location.reload();JSON.stringify({ 'localStorage.theme': localStorage.getItem('theme'), 'localStorage.lastSeen': localStorage.getItem('lastSeen'), }, null, 2){ "localStorage.theme": "dark", "localStorage.lastSeen": "2026-09-11T10:00:00Z" }lastSeensurvived the reload andthemedid not. Nothing was lost: the demo page writesthemeon every load, so the bootstrap overwrote the edit. - Step 6.
Open
http://localhost:8732/, the same file on another port, and read the same keys.JSON.stringify({ origin: location.origin, 'localStorage.theme': localStorage.getItem('theme'), 'localStorage.lastSeen': localStorage.getItem('lastSeen'), 'localStorage.length': localStorage.length, }, null, 2){ "origin": "http://localhost:8732", "localStorage.theme": "dark", "localStorage.lastSeen": null, "localStorage.length": 2 }Same host, same page, empty of everything the other port wrote. The port is part of the origin, and the origin is the store.
How to read the result
| What you see | What it means | What to do |
| --- | --- | --- |
| {} from step 2 | Nothing is stored for this origin | Read the address bar. Scheme, host and port pick the store, and a dev server on another port has its own. |
| A key with the value you expect | The write landed on this origin | Nothing. Record the key name for the logout test. |
| getItem returns null | No such key, or you asked for an interface member | Test with getItem(key) !== null, never with in. |
| [object Object] | An object went into setItem without JSON.stringify | Fix the writer. The original object is gone, not recoverable from the store. |
| A key returns after a reload with the old value | The page bootstrap rewrites it on load | Look at the load script, not at the browser. |
| QuotaExceededError in the Console | The origin is at its storage ceiling | Measure it: How to check localstorage size. |
Common mistakes
What to check next
- How to check session storage in chrome: the same API with a different lifetime, and the one a login wizard usually wants.
- How to check localstorage size: how much of the origin quota the keys you just listed consume.
- How to check if cookies are secure and HttpOnly: a token in local storage is readable by any script on the page, a cookie need not be.
- How to check console errors on a website: where a failed write reports itself when nothing catches it.
FAQ
How to check local storage in browser?
The Console expression works in every Chromium browser and in Firefox. Firefox puts the same list under Storage, Local Storage; Safari puts it under Storage, Local Storage in the Web Inspector. The API and the per-origin rule are identical, only the panel names differ.
How to view or edit localstorage?
View with JSON.stringify(localStorage, null, 2). Edit from the Console with localStorage.setItem(key, value), or in the Application panel, which lists the same pairs for the origin. Reload afterwards to see whether the page keeps the edit or writes over it, as step 5 does.
How to check if a localstorage key exists?
Use localStorage.getItem(key) !== null. A stored empty string is a real key and returns "", which is falsy, so a truthiness test reports it missing. The in operator answers true for interface members such as length, as the step 3 output shows.
Does localStorage survive closing the browser?
Yes. Chrome was closed and started again on the same profile during this capture, and lastSeen was still there, while the marker written to the session store was gone. Clearing site data, an Incognito window closing, or a quota eviction removes it.
Can one tab read what another tab wrote?
Yes, when both tabs are on the same origin. Local storage is one store per origin, shared by every tab, and a write in one tab raises a storage event in the others. That is the difference the session storage procedure measures.
Verified
Verified by Maks VernyChrome 152.0.7977.76node 22.23.2
Each output block is what the command above it printed on that date, on the host named in the step. Figures read from a live site move between runs. Compare the shape of the answer rather than the digits, and see the methodology for how a page is re-verified.
Related on this site
basic5 minpublished updated Maks Verny