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

// 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/');

Steps

  1. Step 1.

    Start the demo page. Stop it with Ctrl+C when the run is over.

    node storage-demo.mjs
    
    serving http://localhost:8731/ and http://localhost:8732/
  2. 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.

  3. 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 localStorage is true while getItem("length") is null, because length is a member of the Storage interface and not a stored key. Only getItem(key) !== null answers the question you asked.

  4. 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
    }

    Boolean of the stored false is true, because the stored value is the four-character string false. Any feature flag read without a parse is on.

  5. 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"
    }

    lastSeen survived the reload and theme did not. Nothing was lost: the demo page writes theme on every load, so the bootstrap overwrote the edit.

  6. 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

Sign: A key check with the in operator says true for a key nothing ever wrote.Cause: Storage exposes length, key, getItem, setItem, removeItem and clear as properties of the object, so the in operator and hasOwnProperty answer true for those names. In the step 3 capture, 'length' in localStorage was true while getItem('length') was null in the same store.
Sign: A value edited in the Application panel is back to the old one after a reload, and the store looks broken.Cause: The application wrote it again during page load. In step 5 the edited theme returned to dark while lastSeen, which no bootstrap touches, survived the same reload. The store kept both writes, the later one won.
Sign: The Application panel shows an empty store while the application clearly saves state.Cause: The panel groups by origin, and http://localhost:8731 and http://localhost:8732 are separate rows in that list. Step 6 reads the same file on the second port and finds none of the keys the first port wrote, because the port belongs to the origin.

What to check next

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.

basic5 minpublished updated Maks Verny