Last updated
Browsing IndexedDB Databases
The IndexedDB Manager provides a visual interface for inspecting client-side databases. Here is how IndexedDB is structured and what the manager shows:
/* IndexedDB structure */
Browser
└── Database: "myapp-db" (version 3)
├── Object Store: "users"
│ ├── Key path: "id"
│ ├── Auto-increment: true
│ ├── Indexes: ["email", "username"]
│ └── Records: 1,247
├── Object Store: "posts"
│ ├── Key path: "id"
│ ├── Auto-increment: true
│ ├── Indexes: ["userId", "createdAt"]
│ └── Records: 8,432
└── Object Store: "cache"
├── Key path: "url"
├── Auto-increment: false
└── Records: 156
/* Opening a database in JavaScript */
const request = indexedDB.open('myapp-db', 3);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Create object store
const userStore = db.createObjectStore('users', {
keyPath: 'id',
autoIncrement: true
});
// Create indexes
userStore.createIndex('email', 'email', { unique: true });
userStore.createIndex('username', 'username', { unique: true });
};
Viewing and Querying Records
The manager lets you browse and query records without writing JavaScript:
/* Sample records in "users" object store */
Key: 1
{
"id": 1,
"username": "alice",
"email": "alice@example.com",
"role": "admin",
"createdAt": "2024-01-15T10:30:00Z",
"preferences": {
"theme": "dark",
"notifications": true,
"language": "en"
}
}
Key: 2
{
"id": 2,
"username": "bob",
"email": "bob@example.com",
"role": "user",
"createdAt": "2024-01-16T14:22:00Z",
"preferences": {
"theme": "light",
"notifications": false,
"language": "fr"
}
}
/* Querying by index */
Query: email index = "alice@example.com"
Result: Record with key 1
/* Key range query */
Query: id between 1 and 100
Results: 100 records
/* JavaScript equivalent */
const tx = db.transaction('users', 'readonly');
const store = tx.objectStore('users');
const index = store.index('email');
const request = index.get('alice@example.com');
Adding and Editing Records
The manager supports adding, editing, and deleting records for development and debugging:
/* Adding a new record */
Object store: users
New record:
{
"username": "carol",
"email": "carol@example.com",
"role": "editor",
"createdAt": "2024-01-17T09:00:00Z",
"preferences": {
"theme": "dark",
"notifications": true,
"language": "en"
}
}
Result: Record added with auto-generated key: 3
/* Editing an existing record */
Key: 2
Change: preferences.theme = "dark"
Result: Record updated
/* Deleting a record */
Key: 3
Result: Record deleted
/* JavaScript equivalents */
// Add record
const tx = db.transaction('users', 'readwrite');
const store = tx.objectStore('users');
store.add({ username: 'carol', email: 'carol@example.com' });
// Update record
store.put({ id: 2, username: 'bob', preferences: { theme: 'dark' } });
// Delete record
store.delete(3);
Debugging Offline PWA Data
IndexedDB is commonly used in Progressive Web Apps for offline storage. The manager helps debug offline data issues:
/* PWA cache inspection */
Database: "pwa-cache-v2"
Object Store: "api-responses"
Records:
Key: "https://api.example.com/users/me"
{
"url": "https://api.example.com/users/me",
"data": { "id": 1, "name": "Alice", "role": "admin" },
"cachedAt": "2024-01-17T08:30:00Z",
"expiresAt": "2024-01-17T09:30:00Z",
"status": 200
}
Key: "https://api.example.com/posts?page=1"
{
"url": "https://api.example.com/posts?page=1",
"data": { "posts": [...], "total": 142 },
"cachedAt": "2024-01-17T08:31:00Z",
"expiresAt": "2024-01-17T08:46:00Z", ← expired!
"status": 200
}
/* Debugging: why is the app showing stale data? */
/* Manager reveals: cached response expired 45 minutes ago */
/* But app is still serving it — bug in cache expiry check */
/* Fix: delete expired record to force fresh fetch */
Delete key: "https://api.example.com/posts?page=1"
/* App will now fetch fresh data on next request */
Exporting and Importing IndexedDB Data
Export data for analysis or to share test fixtures between developers:
/* Export all records from "users" store as JSON */
[
{
"id": 1,
"username": "alice",
"email": "alice@example.com",
"role": "admin"
},
{
"id": 2,
"username": "bob",
"email": "bob@example.com",
"role": "user"
}
]
/* Import test fixtures */
/* Share users-test-data.json with team */
/* Each developer imports to get consistent test state */
/* JavaScript: export all records */
async function exportStore(db, storeName) {
return new Promise((resolve) => {
const tx = db.transaction(storeName, 'readonly');
const store = tx.objectStore(storeName);
const request = store.getAll();
request.onsuccess = () => resolve(request.result);
});
}
const data = await exportStore(db, 'users');
const json = JSON.stringify(data, null, 2);
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
// trigger download...
/* JavaScript: import records */
async function importStore(db, storeName, records) {
const tx = db.transaction(storeName, 'readwrite');
const store = tx.objectStore(storeName);
store.clear();
records.forEach(record => store.add(record));
return tx.complete;
}