@pantheon-systems/nextjs-cache-handler
Custom cache handler for Next.js with support for Google Cloud Storage and file-based caching. Designed for Pantheon's Next.js hosting platform.
Features
- Dual Cache Handlers: Support for both GCS (production) and file-based (development) caching
- Next.js 16
use cache Support: Handlers for the new cacheHandlers (plural) API
- Tag-Based Invalidation: Efficient O(1) cache invalidation using tag mapping
- Edge Cache Clearing: Automatic CDN cache invalidation on Pantheon infrastructure
- Build-Aware Caching: Automatically invalidates route cache on new builds
- Static Route Preservation: Preserves SSG routes during cache clearing
Installation
npm install @pantheon-systems/nextjs-cache-handler
Quick Start
1. Create a cache handler file
import { createCacheHandler } from '@pantheon-systems/nextjs-cache-handler';
const CacheHandler = createCacheHandler({
type: 'auto',
});
export default CacheHandler;
2. Configure Next.js
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const nextConfig = {
cacheHandler: path.resolve(__dirname, "./cacheHandler.mjs"),
cacheMaxMemorySize: 0,
};
export default nextConfig;
Configuration
createCacheHandler(config?)
Creates a cache handler based on the provided configuration.
interface CacheHandlerConfig {
type?: 'auto' | 'file' | 'gcs';
}
Note: Debug logging is controlled via the CACHE_DEBUG environment variable. See the Debugging section for details.
Environment Variables
CACHE_BUCKET | GCS bucket name for storing cache | Required for GCS handler |
OUTBOUND_PROXY_ENDPOINT | Edge cache proxy endpoint (Pantheon infrastructure) | Optional (enables edge cache clearing) |
CACHE_DEBUG | Enable debug logging (true or 1) | Optional |
API Reference
createCacheHandler(config?)
Factory function that returns the appropriate cache handler class based on configuration.
import { createCacheHandler } from '@pantheon-systems/nextjs-cache-handler';
const CacheHandler = createCacheHandler();
const FileCacheHandler = createCacheHandler({ type: 'file' });
const GcsCacheHandler = createCacheHandler({ type: 'gcs' });
getSharedCacheStats()
Returns cache statistics for the current environment.
import { getSharedCacheStats } from '@pantheon-systems/nextjs-cache-handler';
const stats = await getSharedCacheStats();
console.log(stats);
clearSharedCache()
Clears all cache entries (preserving static SSG routes).
import { clearSharedCache } from '@pantheon-systems/nextjs-cache-handler';
const clearedCount = await clearSharedCache();
console.log(`Cleared ${clearedCount} cache entries`);
Direct Handler Access
For advanced use cases, you can import the handlers directly:
import { FileCacheHandler, GcsCacheHandler } from '@pantheon-systems/nextjs-cache-handler';
export default FileCacheHandler;
Next.js 16 use cache Handlers
Next.js 16 introduces the 'use cache' directive with a new cacheHandlers (plural) configuration. This package provides handlers for it.
1. Create a use-cache handler file
import { createUseCacheHandler } from '@pantheon-systems/nextjs-cache-handler/use-cache';
const UseCacheHandler = createUseCacheHandler({
type: 'auto',
});
export default UseCacheHandler;
2. Configure Next.js
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const nextConfig = {
cacheHandler: path.resolve(__dirname, "./cache-handler.mjs"),
cacheHandlers: {
default: path.resolve(__dirname, "./use-cache-handler.mjs"),
},
cacheMaxMemorySize: 0,
cacheComponents: true,
};
export default nextConfig;
createUseCacheHandler(config?)
Factory function that returns the appropriate use-cache handler. Accepts the same type option ('auto', 'file', 'gcs').
getUseCacheStats()
Returns statistics for use cache entries, similar to getSharedCacheStats().
import { getUseCacheStats } from '@pantheon-systems/nextjs-cache-handler';
const stats = await getUseCacheStats();
Direct Handler Access
import { UseCacheFileHandler, UseCacheGcsHandler } from '@pantheon-systems/nextjs-cache-handler';
Cache Types
The handler distinguishes between two cache types:
- Fetch Cache: Stores data from
fetch() calls with caching enabled
- Route Cache: Stores rendered pages and route data
Tag-Based Invalidation
The handler maintains a tag-to-keys mapping for efficient O(1) cache invalidation:
await cacheHandler.set('post-1', data, { tags: ['posts', 'blog'] });
await cacheHandler.revalidateTag('posts');
Edge Cache Clearing
When deployed on Pantheon, the cache handlers automatically clear the CDN edge cache when cache entries are invalidated. This is triggered by:
revalidateTag() calls (clears matching surrogate keys and paths)
revalidatePath() calls (clears the specific path from the CDN)
Edge cache clearing is enabled when the OUTBOUND_PROXY_ENDPOINT environment variable is set (automatically configured on Pantheon). It runs in the background and does not block cache operations.
Build Invalidation
On each new build, the handler automatically:
- Detects the new build ID
- Invalidates the route cache (Full Route Cache)
- Preserves the data cache (Fetch Cache)
This matches Next.js's expected behavior where route cache is invalidated on each deploy but data cache persists.
Debugging
Enable debug logging to see detailed cache operations by setting the CACHE_DEBUG environment variable:
CACHE_DEBUG=true npm run start
CACHE_DEBUG=1 npm run start
Log Levels
The cache handler uses four log levels:
debug | Only when CACHE_DEBUG=true | Verbose operational logs (GET, SET, HIT, MISS) |
info | Only when CACHE_DEBUG=true | Important events (initialization, cache cleared) |
warn | Always | Recoverable issues that might need attention |
error | Always | Errors that affect cache operations |
Example Output
When debug logging is enabled, you'll see output like:
[GcsCacheHandler] Initializing cache handler
[GcsCacheHandler] GET: /api/posts
[GcsCacheHandler] HIT: /api/posts (route)
[GcsCacheHandler] SET: /api/users (fetch)
[EdgeCacheClear] Cleared 3 paths in 45ms
[GcsCacheHandler] Revalidated 5 entries for tags: posts, blog
This helps diagnose cache behavior, verify cache hits/misses, and troubleshoot invalidation issues.
Publishing
Prerequisites
Publishing Steps
-
Update the version in package.json:
npm version patch
npm version minor
npm version major
-
Build and test:
npm run build
npm test
-
Publish to npm:
npm publish --access public
The --access public flag is required for scoped packages to be publicly accessible.
Verify Publication
After publishing, verify the package is available:
npm view @pantheon-systems/nextjs-cache-handler
Or install it in a test project:
npm install @pantheon-systems/nextjs-cache-handler
License
MIT