Tiny hub/client helper that lets you proxy `localStorage` and `indexedDB` (via [`idb-keyval`](https://github.com/jakearchibald/idb-keyval)) calls into a cross-origin iframe. The hub runs on a storage-friendly origin, while the client injects a hidden ifra
npm install iframe-shared-storageTiny hub/client helper that lets you proxy localStorage and indexedDB (via idb-keyval) calls into a cross-origin iframe. The hub runs on a storage-friendly origin, while the client injects a hidden iframe, performs a readiness handshake, and then proxies storage calls through postmsg-rpc.
window.localStorage, but every call is executed inside the hub origin.client, hub, or both) to inspect RPC traffic when debugging.dist/browser.js for tags or import from the published package when bundling.initHub): expose localStorage and selected idb-keyval APIs to postmsg-rpc. Every method is wrapped with logging hooks and runs inside the iframe's origin.constructClient): either attach to an existing iframe or inject one that points at the hub URL. It keeps the iframe hidden, performs a handshake via postMessage, and only issues RPCs after the hub reports it is ready.The repository also contains client.html / hub.html demo pages plus Playwright harnesses that emulate restrictive headers to ensure the handshake behaves under COEP/CORP variations.
bash
npm install iframe-shared-storage
`$3
`bash
npm run build # emits dist/index.js + dist/browser.js
`
Use dist/browser.js for
Host this file on the origin that is allowed to use the storage APIs you care about.$3
`ts
import { constructClient } from "iframe-shared-storage";const storage = constructClient({
iframe: {
src: "https://storage-origin.example.com/hub.html",
messagingOptions: { enableLog: "client" },
iframeReadyTimeoutMs: 1500,
methodCallTimeoutMs: 2000,
methodCallRetries: 2,
},
});
await storage.localStorage.setItem("foo", "bar");
const value = await storage.localStorage.getItem("foo");
await storage.indexedDBKeyval?.set("heavy", JSON.stringify({ ... }));
`For non-bundled apps, the same API is available via the
IframeStorage global that dist/browser.js defines:
`html
`API
$3
Call this once inside the hub iframe. The hub must have a parent window (i.e. it cannot run as a top-level page). It registers handlers for:
- localStorage.setItem/getItem/removeItem/clear/key
- indexedDBKeyval.set/get/del$3
- Pass { iframe: { src: string } } to inject a hidden iframe that points to your hub URL. The iframe receives an auto-generated iframe-storage-hub id.
- Pass { iframe: { id: string } } to bind to an already-rendered