Add support for IndexedDB#939
Conversation
| - **DO** use `put()` when you want insert-or-update semantics. Use `add()` only when you want an error if the key already exists. | ||
| - **DO** use indexes and key ranges (`IDBKeyRange`) for efficient queries instead of iterating all records with a cursor. | ||
| - **DO** use `"readonly"` transactions for reads. Multiple readonly transactions can run concurrently, but only one `"readwrite"` transaction per object store is active at a time. | ||
| - **DO NOT** store sensitive data (tokens, passwords, PII) in IndexedDB without encryption. IndexedDB is not a secure store — any script running on the origin can access it. |
There was a problem hiding this comment.
Do you think it'd be worth having a separate guide on how to use encryption to secure sensitive data in IDB?
| name: persist-structured-data | ||
| description: Store and retrieve structured application data client-side using IndexedDB, enabling offline access, fast local reads, and reduced network dependency without relying on cookies or localStorage for complex data. | ||
| web-feature-ids: | ||
| - indexeddb |
There was a problem hiding this comment.
There's also the related web feature getAllRecords(). It's "Limited availability" but is there anything more we want to say about it in this guide?
| } | ||
| ``` | ||
|
|
||
| ### Storage quota |
There was a problem hiding this comment.
This seems like good general advice to include in the main body of the guide, outside of the fallback strategy section. (It doesn't depend on browser support)
Could you move this up to its own H2 section?
| const notes = await getAllNotes(db); | ||
| ``` | ||
|
|
||
| ## Best Practices |
There was a problem hiding this comment.
Either in its own section, or one of the bullets in this section, we should also include the best practices for back/forward cache eligibility:
- Closing open IndexedDB connections during the
pagehideevent - Reopening or reconnecting to them during the
pageshowevent
https://web.dev/articles/bfcache#close-open-connections
The example code, demo.html, and expectations.md should also be updated to reflect it.
There was a problem hiding this comment.
Thanks for adding this Rick, +1, it would be more than ideal to guide developers towards this approach to avoid unexpected bfcache ineligibility scenarios.
|
|
||
| ```javascript | ||
| const DB_NAME = "app-notes"; | ||
| const DB_VERSION = 1; |
There was a problem hiding this comment.
Are there any best practices on when to change the version number that would be worth including?
| const record = { ...note, updatedAt: Date.now() }; | ||
| const request = store.add(record); | ||
|
|
||
| request.onsuccess = () => resolve(request.result); |
There was a problem hiding this comment.
Should this be oncomplete?
IIUC in some situations the success event can be fired before the transaction is aborted or actually written to disk.
| const request = store.add(record); | ||
|
|
||
| request.onsuccess = () => resolve(request.result); | ||
| tx.onerror = () => reject(tx.error); |
There was a problem hiding this comment.
Do we also need to handle tx.onabort in addition to errors?
|
Seeing as how IndexedDB is already a Widely available web feature, I also used the MWG Demo app to assess how well an unguided coding agent would adhere to these best practices.
The unguided agent reached for |
Remove redundant widely available message and reframe fallback verbiage Co-authored-by: Rick Viscomi <rviscomi@users.noreply.github.com>
Take suggestion that metadata is no longer needed Co-authored-by: Rick Viscomi <rviscomi@users.noreply.github.com>

Adds support for IndexedDB under persist-structured-data with guide, expectations, and demo.