@dataweavers/redis-page-caching
v2.0.0
Published
Redis caching implementation for Next.js, designed to work seamlessly with the @fortedigital/nextjs-cache-handler. This package provides a robust and efficient caching solution using Redis, allowing developers to easily integrate caching into their Next.j
Downloads
535
Readme
@dataweavers/redis-page-caching
Provides a standardised Redis caching integration for Next.js applications, including page caching via the Next.js cache handler, cache tag management for targeted CDN purging, and cache management API routes for clearing and pre-populating the cache.
Internally uses @fortedigital/nextjs-cache-handler as the underlying cache handler.
Installation
npm install @dataweavers/redis-page-cachingSetup
1. Register the cache handler
In your next.config.js (or next.config.ts), set the custom cache handler:
import path from 'path';
const nextConfig = {
cacheHandler: path.join(process.cwd(), 'node_modules/@dataweavers/redis-page-caching/dist/cache-handler.mjs'),
cacheMaxMemorySize: 0, // disable default in-memory caching
};2. Set environment variables
Configure at minimum REDIS_HOST and an authentication method (see Authentication).
Configuration
Redis connection
| Variable | Required | Default | Description |
|---|---|---|---|
| REDIS_HOST | Yes | (empty) | Hostname of the Redis instance, e.g. my-redis.eastus.redis.azure.net. When absent, falls back to LRU in-memory cache. |
| REDIS_PORT | No | 10000 | Port for the Redis instance. Azure Managed Redis default is 10000. Azure Cache for Redis is typically 6380. |
| REDIS_KEY_PREFIX | No | nextjs: | Prefix applied to all Redis keys. Useful when sharing a Redis instance across multiple applications or environments. |
| REDIS_CLUSTER_MODE | No | false | Set to true when connecting to a Redis Cluster (e.g. Azure Managed Redis with clustering enabled). Uses createCluster instead of createClient. |
Authentication
| Variable | Required | Default | Description |
|---|---|---|---|
| REDIS_ACCESS_KEY | No | (empty) | Access key / password. When set, access key authentication is used. When omitted, Managed Identity is used. |
| AZURE_CLIENT_ID | No | (empty) | Client ID of a user-assigned managed identity. When set (and REDIS_ACCESS_KEY is unset), a user-assigned identity is used. When both are unset, DefaultAzureCredential is used. |
Cache management API routes
| Variable | Required | Default | Description |
|---|---|---|---|
| CACHE_MANAGEMENT_SECRET | Yes (if using API routes) | (must be set) | Secret key to authenticate requests to the clear and populate API routes. Use a strong random string. |
| CACHE_POPULATE_BATCH_SIZE | No | 25 | Number of pages processed per batch during cache population. |
| CACHE_POPULATE_BATCH_DELAY_MS | No | 5000 | Delay in milliseconds between batches during cache population. |
Logging
| Variable | Required | Default | Description |
|---|---|---|---|
| DATAWEAVERS_LOG_LEVEL | No | info | Log verbosity. One of silent, error, warn, info, debug, trace. |
Authentication
The cache handler selects an authentication mode automatically based on which environment variables are present.
Access key
Set REDIS_ACCESS_KEY to the Redis password or access key.
REDIS_HOST=my-redis.redis.cache.windows.net
REDIS_PORT=6380
REDIS_ACCESS_KEY=your-access-keyUser-assigned Managed Identity
Leave REDIS_ACCESS_KEY unset and set AZURE_CLIENT_ID to the Client ID of the user-assigned managed identity assigned to your hosting resource (e.g. App Service).
REDIS_HOST=my-redis.eastus.redis.azure.net
REDIS_PORT=10000
AZURE_CLIENT_ID=<client-id-of-user-assigned-managed-identity>Required Azure configuration:
- Assign the managed identity to the App Service — Portal → App Service → Identity → User assigned → Add.
- Add the identity as a Redis User — Portal → Azure Managed Redis → Authentication → Redis Users → Add. Set the access policy to
Data ContributororData Owner. - Disable access keys — Portal → Azure Managed Redis → Authentication → Access keys → Disable.
- Install the peer dependencies —
npm install @azure/identity @redis/entraid.
AZURE_CLIENT_IDmust be the Client ID of the managed identity — found in Portal → Managed Identities → your identity → Overview → Client ID.
Default Azure Credential (fallback)
Leave both REDIS_ACCESS_KEY and AZURE_CLIENT_ID unset. The handler will use DefaultAzureCredential from @azure/identity, which tries environment variables, system-assigned managed identity, Azure CLI, and other sources in order.
REDIS_HOST=my-redis.eastus.redis.azure.net
REDIS_PORT=10000
# Neither REDIS_ACCESS_KEY nor AZURE_CLIENT_ID setRedis Cluster Mode
When your Redis instance is running in cluster mode (e.g. Azure Managed Redis with clustering enabled), set REDIS_CLUSTER_MODE=true. Without this, the client will receive MOVED redirect errors and silently fall back to no caching.
REDIS_HOST=my-redis.eastus.redis.azure.net
REDIS_PORT=10000
REDIS_CLUSTER_MODE=true
AZURE_CLIENT_ID=<client-id>No other configuration changes are required — authentication and key prefix behaviour are identical in cluster mode.
Cache Tag Service
CacheTagService stores page-level cache tags in Redis at render time. These tags are later read by @dataweavers/arc-nextjs-wrapper to set Cache-Tag response headers for targeted CDN purging.
Adding tags at render time
Call addPageTags from your page or data-fetching code to associate tags with the current page path:
import { CacheTagService } from '@dataweavers/redis-page-caching';
const service = new CacheTagService();
await service.addPageTags('/doctors', ['tag-a', 'tag-b', 'item-guid-123']);Tags are stored as a Redis set under the key <REDIS_KEY_PREFIX>page-tags:<path>. Paths are normalised to lowercase with a leading / before being used as keys, so /Doctors and /doctors resolve to the same entry.
API
| Method | Description |
|---|---|
| addPageTags(path, tags, forceOverwrite?) | Adds tags to the Redis set for the given path. Duplicate tags are ignored. Pass forceOverwrite: true to clear existing tags before adding. Returns { success, error? } and logs Redis errors. |
| getPageTags(path) | Returns { success, tags, error? } where tags is an array or null when no entry exists. Redis errors are logged and returned as success: false. |
| deletePageTags(path) | Deletes the tag set for the given path. Returns { success, error? } and logs Redis errors. |
Cache Management API Routes (Optional - install if required)
The package exports CacheClear and CachePopulate classes that provide ready-made route handlers for both the Next.js Pages Router and App Router.
Clearing the cache
App Router
// app/api/clear-cache/route.ts
import { CacheClear } from '@dataweavers/redis-page-caching';
const { POST } = new CacheClear(process.env.CACHE_MANAGEMENT_SECRET).getAppRouteHandlers();
export { POST };Pages Router
// pages/api/clear-cache.ts
import { CacheClear } from '@dataweavers/redis-page-caching';
export default new CacheClear(process.env.CACHE_MANAGEMENT_SECRET).getPagesRouteHandler();Request:
POST /api/clear-cache
x-secret: your-secretOptionally include x-pattern to restrict which keys are cleared (default: /*):
POST /api/clear-cache
x-secret: your-secret
x-pattern: /products/*Pre-populating the cache
App Router
// app/api/populate-cache/route.ts
import { CachePopulate, StaticPath } from '@dataweavers/redis-page-caching';
// include an automation to retrieve routes or add more static routes
const paths: StaticPath[] = [
{ params: { path: '/' } },
{ params: { path: 'doctors' } },
];
const { POST } = new CachePopulate(process.env.CACHE_MANAGEMENT_SECRET, paths).getAppRouteHandlers();
export { POST };Pages Router
// pages/api/populate-cache.ts
import { CachePopulate, StaticPath } from '@dataweavers/redis-page-caching';
// include an automation to retrieve routes or add more static routes
const paths: StaticPath[] = [
{ params: { path: '/' } },
{ params: { path: 'doctors' } },
];
export default new CachePopulate(process.env.CACHE_MANAGEMENT_SECRET, paths).getPagesRouteHandlers();Request:
POST /api/populate-cache?pathCount=50
x-secret: your-secret| Parameter | Where | Description |
|---|---|---|
| x-secret | Header | Must match CACHE_MANAGEMENT_SECRET. |
| pathCount | Query string | Maximum number of pages to revalidate. Default: 10. |
Cache Initialisation
When deploying, you may want to pre-warm the Redis cache rather than letting it build organically. Two approaches are available.
Instrumentation (on startup)
Use Next.js instrumentation to populate the cache when the server starts. Set setOnlyIfNotExists: true to avoid overwriting keys that are already cached (soft populate), or omit it to overwrite all keys (hard populate).
// instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs' && process.env.NODE_ENV !== 'development') {
try {
const { registerInitialCache } = await import('@fortedigital/nextjs-cache-handler/instrumentation');
const CacheHandler = (await import('@dataweavers/redis-page-caching/cache-handler')).default;
await Promise.race([
registerInitialCache(CacheHandler, { setOnlyIfNotExists: true }),
new Promise<void>((_, reject) =>
setTimeout(() => reject(new Error('registerInitialCache timed out')), 10_000)
),
]);
} catch (err) {
console.error('[instrumentation] Cache handler registration failed:', err);
}
}
}API endpoint trigger (deployment pipeline)
Use the CachePopulate API route and call it from your deployment pipeline after the application has started:
POST /api/populate-cache?pathCount=100
x-secret: your-secretThis is the recommended approach for larger sites as it allows control over batch size and timing via CACHE_POPULATE_BATCH_SIZE and CACHE_POPULATE_BATCH_DELAY_MS.
Key Namespacing
All Redis keys are prefixed with REDIS_KEY_PREFIX (default nextjs:). This ensures:
- Page cache keys do not conflict with cache tag keys or other application Redis usage.
- Multiple applications or deployment slots (e.g. blue/green) sharing the same Redis instance can use different prefixes to remain isolated.
Page cache keys: nextjs:<route-path>
Cache tag keys: nextjs:page-tags:<path>
