How to check session storage in chrome

Open the page in Chrome, press F12, and run JSON.stringify(sessionStorage, null, 2) in the Console. Chrome prints the keys held for this tab and this origin. Open a second tab on the same URL and the same expression returns a different store, while local storage returns the same one.

Why check this

Run this whenever a feature keeps state that is supposed to belong to one tab: a checkout wizard, an upload in progress, a CSRF token, a draft that should not follow the user into a second window. The name misleads. What separates sessionStorage from localStorage is the tab, not the login session and not the browser session.

The failure this prevents has two shapes. A wizard that keeps its step in session storage passes every single-tab test and resets to step one when support asks the customer to open the order in a new tab. The opposite shape is worse: a token put there because the tab was believed to be private travels into every tab the page opens itself, which step 7 measures.

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 at the end of the run.

    node storage-demo.mjs
    
    serving http://localhost:8731/ and http://localhost:8732/
  2. Step 2.

    Open http://localhost:8731/, press F12, and read the tab's session store in the Console.

    JSON.stringify(sessionStorage, null, 2)
    
    {
    "csrfToken": "a1b2c3",
    "wizardStep": "3"
    }

    DevTools lists the same pairs under Application, Storage, Session storage, http://localhost:8731, on a row separate from Local storage.

  3. Step 3.

    Put one marker in each store, so the next steps can tell them apart.

    sessionStorage.setItem('tab1Only', 'yes');
    localStorage.setItem('lastSeen', '2026-09-11T10:00:00Z');
    JSON.stringify({ sessionStorage: { ...sessionStorage }, localStorage: { ...localStorage } }, null, 2)
    
    {
    "sessionStorage": {
      "csrfToken": "a1b2c3",
      "tab1Only": "yes",
      "wizardStep": "3"
    },
    "localStorage": {
      "lastSeen": "2026-09-11T10:00:00Z",
      "theme": "dark",
      "cart": "{\"items\":2,\"total\":\"41.00\"}"
    }
    }
  4. Step 4.

    Reload the tab and read the session store again.

    location.reload();
    
    JSON.stringify({
      'sessionStorage.tab1Only': sessionStorage.getItem('tab1Only'),
      'sessionStorage.wizardStep': sessionStorage.getItem('wizardStep'),
    }, null, 2)
    
    {
    "sessionStorage.tab1Only": "yes",
    "sessionStorage.wizardStep": "3"
    }

    A reload keeps the store. The tab is the same tab, so a refresh is not the boundary.

  5. Step 5.

    Open a second tab yourself on the same URL, press F12 there, and run the same read.

    JSON.stringify({
      origin: location.origin,
      sessionStorage: { ...sessionStorage },
      'localStorage.lastSeen': localStorage.getItem('lastSeen'),
    }, null, 2)
    
    {
    "origin": "http://localhost:8731",
    "sessionStorage": {
      "csrfToken": "a1b2c3",
      "wizardStep": "3"
    },
    "localStorage.lastSeen": "2026-09-11T10:00:00Z"
    }

    Same origin, and tab1Only, written one line before lastSeen in step 3, is absent while lastSeen is here. The session store is new, the local store is shared. The two keys the demo page writes on load are present because the page ran again in this tab.

  6. Step 6.

    Listen in tab 2, then write to both stores from tab 1.

    window.seen = [];
    addEventListener('storage', (e) => {
      seen.push((e.storageArea === localStorage ? 'localStorage' : 'sessionStorage') + ' ' + e.key + ': ' + e.oldValue + ' -> ' + e.newValue);
    });
    
    localStorage.setItem('theme', 'contrast');
    sessionStorage.setItem('wizardStep', '9');
    
    JSON.stringify(window.seen, null, 2)
    
    [
    "localStorage theme: dark -> contrast"
    ]

    Two writes, one event. A cross-tab listener never hears a session store change, because the other tab's session store is not the one that changed.

  7. Step 7.

    From tab 1, let the page open a tab of its own, then read the session store in that new tab.

    window.open('http://localhost:8731/', '_blank');
    
    JSON.stringify({
      'sessionStorage.tab1Only': sessionStorage.getItem('tab1Only'),
      'sessionStorage.wizardStep': sessionStorage.getItem('wizardStep'),
      sessionStorage: { ...sessionStorage },
    }, null, 2)
    
    {
    "sessionStorage.tab1Only": "yes",
    "sessionStorage.wizardStep": "3",
    "sessionStorage": {
      "csrfToken": "a1b2c3",
      "tab1Only": "yes",
      "wizardStep": "3"
    }
    }

    tab1Only is here, and nothing on the page writes that key. A tab the page opens starts from a copy of the opener's session store. A tab you open from the address bar, as in step 5, does not.

  8. Step 8.

    Close tab 1, open a new tab on the same URL, and read both stores.

    JSON.stringify({
      'sessionStorage.tab1Only': sessionStorage.getItem('tab1Only'),
      'localStorage.lastSeen': localStorage.getItem('lastSeen'),
    }, null, 2)
    
    {
    "sessionStorage.tab1Only": null,
    "localStorage.lastSeen": "2026-09-11T10:00:00Z"
    }

    Closing the tab ended the session store. The local store is untouched.

How to read the result

| What you see | What it means | What to do | | --- | --- | --- | | The key is in tab 1 and missing in tab 2 | Normal session storage scope | Nothing. Confirm the feature is meant to be per tab. | | The key is in both tabs | It is in local storage, not session storage | Read both stores by name before concluding anything. | | A key survives a reload but not a new tab | The store is behaving as specified | Test the flow the user runs, including a second tab. | | A key appears in a tab opened by the page | A window.open or target="_blank" copied the opener's store | Treat session storage as readable by any tab the page opens. | | No storage event in the other tab | Session storage never raises one across tabs | Use local storage or BroadcastChannel for cross-tab messages. | | An empty store on a page that saves state | Wrong origin, or state kept somewhere else | Compare the origin in the output with the address bar. |

Common mistakes

Sign: A token is put in session storage because it is believed to stay in one tab, and it turns up in another.Cause: A tab created by window.open or by a link with target=_blank starts from a copy of the opener's session store. In step 7 the marker tab1Only, which no code on the page writes, was present in the tab the page opened.
Sign: A cross-tab sync that works for one setting does nothing for another.Cause: The storage event fires only for the storage area that changed, in other documents on the same origin. A session storage write in one tab has no listener anywhere else, because no other tab shares that area. Step 6 wrote to both stores and produced one event.
Sign: A wizard resets to step one although the test passed.Cause: The test refreshed the page and the store survived, which proves nothing about a second tab. The lifetime of session storage is the tab, so the reload path and the new-tab path are two different tests.

What to check next

FAQ

How to check session storage in browser?

The Console expression is the same everywhere. Firefox lists it under Storage, Session Storage, and Safari under Storage, Session Storage in the Web Inspector. The per-tab rule comes from the HTML standard, so the behaviour in steps 5 and 8 is not specific to Chrome.

What is the difference between localstorage and sessionstorage?

Scope and lifetime. Both are per origin and both hold strings. Local storage is one store shared by every tab and survives a browser restart. Session storage is one store per tab, copied into tabs the page opens, and gone when the tab closes. Step 5 and step 8 show both halves.

Does session storage survive a refresh?

Yes. Step 4 reloaded the page and the marker was still there. It also survives a navigation inside the tab and going back. It does not survive closing the tab, and a restored tab after a browser crash is a separate case not measured here.

Can two windows share one session store?

Only when one opened the other. A window created by window.open from the page, or by a link with target="_blank", starts with a copy of the opener's store. Later writes are not synchronised between the two, because they are two stores after the copy.

Is session storage safer than a cookie for a token?

No. Any script on the page reads it, including a compromised third-party script, and an HttpOnly cookie is not readable by script at all. It also travels into tabs the page opens, as step 7 shows.

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.

basic6 minpublished updated Maks Verny