Caching system for Nuxt with IndexedDB, automatic refetching, and cross-tab synchronization
npm install nuxt-async-cacheCaching system for Nuxt with IndexedDB, automatic refetching, and cross-tab synchronization.
- SSR-enabled: works with Nuxt SSR
- IndexedDB Storage: persistent client-side caching using Dexie
- Auto-refresh: flexible data refreshing
- Cross-tab Sync: coordinated data updates across multiple tabs
- Lock Coordination: de-duplicated requests across tabs
``bashUsing pnpm (recommended)
pnpm add nuxt-async-cache
$3
Add the module to your
nuxt.config.ts:`typescript
export default defineNuxtConfig({
modules: [
'nuxt-async-cache'
],
// Optional: Configure module options
asyncCache: {
// Module configuration options (if any)
}
})
`Note: The module automatically configures Vite to handle the Dexie dependency correctly. If you encounter import issues, you can add this fallback configuration:
`typescript
export default defineNuxtConfig({
modules: ['nuxt-async-cache'],
vite: {
resolve: {
alias: {
'dexie': 'dexie/dist/dexie.mjs'
}
}
}
})
`$3
The module automatically provides the
useCachedAsyncData composable across your entire Nuxt application:`vue
`Basic Usage
`vue
Loading...
Error: {{ error.message }}
{{ data.name }}
`Reactive Keys
The
key parameter supports reactive values, allowing you to dynamically change the cache key:`vue
`You can also use refs directly:
`vue
`Advanced Usage with Dynamic Timestamps
`javascript
const { data } = useCachedAsyncData({
key: 'api-data',
handler: () => $fetch('/api/data'),
timestamps: {
// Use server-provided timestamp
requestTime: (response) => response.timestamp,
// Compute staleness based on data type
staleAfter: (response) => {
if (response.type === 'critical') return 10000 // 10 seconds
if (response.type === 'normal') return 60000 // 1 minute
return 300000 // 5 minutes for others
},
// Auto-refresh based on server hint
refetchAfter: (response) => response.nextUpdateIn || null,
// Expiry based on data importance
expiresAfter: (response) => response.ttl || 86400000
}
})
`API Reference
$3
#### Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
|
key | MaybeRefOrGetter | Required | Unique cache key (supports reactive values) |
| handler | () => Promise | Required | Data fetching function |
| timestamps | TimestampConfig | {} | Dynamic timestamp configuration |
| defaults | DefaultTimestamps | See below | Default timing values |
| immediate | boolean | true | Fetch immediately |
| server | boolean | true | Fetch on server |
| lazy | boolean | false | Don't block navigation |
| dedupe | 'defer' \| 'cancel' | undefined | Deduplication strategy |#### Default Timestamps
`javascript
{
staleAfter: 30000, // 30 seconds
refetchAfter: null, // No auto-refetch
expiresAfter: 86400000 // 24 hours
}
`#### Return Value
`javascript
{
data: Ref, // Reactive data
pending: Ref, // Loading state
error: Ref, // Error state
status: Ref, // 'idle' | 'pending' | 'success' | 'error'
refresh: () => Promise, // Manual refresh
clear: () => Promise // Clear cache entry
}
`Cache Management Utilities
The module provides client-side utilities for cache management:
`javascript
// In a Nuxt plugin or client composable
import {
cleanupExpiredCache,
clearAllCache,
setupCacheMaintenance
} from 'nuxt-async-cache/runtime/utils/cache'// Manual cleanup (client-side only)
await cleanupExpiredCache()
// Clear everything
await clearAllCache()
// Auto maintenance (runs every 5 minutes by default, client-side only)
const stopMaintenance = setupCacheMaintenance()
// Call stopMaintenance() to stop
`How It Works
$3
- Data is fetched on the server and stored in memory
- Cache entries are passed to the client via Nuxt payload$3
- Client checks IndexedDB for newer data
- Uses server data if local cache is older or missing
- Sets up auto-refresh timers based on timestamps$3
- Uses Web Locks API for coordinating refresh across tabs
- Falls back to Dexie-based locking if Web Locks unavailable
- BroadcastChannel notifies other tabs of cache updates$3
- Stale: Data is shown but background refresh is triggered
- Refetch: Automatic refresh at specified intervals
- Expired: Data is removed from cache entirelyBest Practices
1. Choose appropriate cache keys: Use descriptive, unique keys. Keys can be static strings, reactive refs, or computed values for dynamic caching
2. Set reasonable timeouts: Balance freshness vs performance
3. Handle errors gracefully: Always provide error states
4. Use dynamic timestamps: Leverage server hints when available
5. Monitor cache size: Use cleanup utilities in production
6. Leverage reactive keys: Use computed keys for dynamic data that depends on user state or route parameters
Browser Support
- IndexedDB: All modern browsers
- Web Locks API: Chrome 69+, Firefox 96+, Safari 15.4+
- BroadcastChannel: All modern browsers
Graceful fallbacks are provided for unsupported APIs.
Development
$3
`bash
Clone the repository
git clone
cd nuxt-async-cacheInstall dependencies
pnpm installPrepare the module
pnpm dev:prepareStart development server
pnpm dev
`$3
`bash
Run tests
pnpm testRun tests in watch mode
pnpm test:watchRun type checking
pnpm test:types
`$3
`bash
Build the module
pnpm prepackLint code
pnpm lint
``