localStorage adapter
A client-side store — run the whole feedback loop in the browser, no server required.
@siteping/adapter-localstorage persists feedbacks in the visitor's browser. Combined with the widget's store option, you get a fully working feedback loop with zero backend — ideal for demos, prototypes, and docs sites (this site uses it).
npm i @siteping/adapter-localstorageimport { initSiteping } from "@siteping/widget";
import { LocalStorageStore } from "@siteping/adapter-localstorage";
initSiteping({
store: new LocalStorageStore(),
projectName: "my-demo",
});Options
| Option | Type | Default | What it does |
|---|---|---|---|
key | string | "siteping_feedbacks" | The single localStorage key holding the whole feedback array |
Behavior notes
- Data stays on one machine. Each visitor sees only their own feedback — by design. It never leaves the browser.
- Corrupted data never crashes — and is never silently lost. A record missing its
annotations— or itscomments, as every record saved before threads does — reads with an empty list; an entry that can't be read — a missing field, an unknown type or status, a date that doesn't parse, comments that aren't a list — is skipped without hiding the others, and stored JSON that can't be parsed reads as an empty list. Before the next write replaces the key, whatever was skipped — those entries, or the whole blob when it isn't a JSON array — is appended to a JSON array under<key>.corrupt(e.g.siteping_feedbacks.corrupt), which the store never deletes. If that copy can't be saved, the write fails with aStorePersistenceErrorand the key is left as it was. - Quota pressure drops screenshots first. If a write exceeds the browser's storage quota (~5 MB per origin), the adapter retries once without the screenshot before giving up with a
StorePersistenceError— the comment survives even when the image can't. - Bulk actions are safe within one tab. The store applies its writes one at a time, so selecting several feedbacks and resolving or deleting them together changes every one of them. The guarantee stops at the instance: two tabs — or two
LocalStorageStores on the samekey— each rewrite the whole array, and the last write wins. - Dates survive the round-trip —
createdAtand friends come back as realDateobjects, not strings. - SSR-safe: without
localStorage, reads return an empty list and every write —clear()included — fails with aStorePersistenceError, never a raw exception. - Duplicate
clientIdsubmissions return the existing record, same as every other adapter.