A collection of utilities and helpers for working with DatoCMS in Next.js projects.
Installation
npm install @smartive/datocms-utils
Utilities
General Utilities
classNames
Cleans and joins an array of class names (strings and numbers), filtering out undefined and boolean values.
import { classNames } from '@smartive/datocms-utils'; const className = classNames('btn', isActive && 'btn-active', 42, undefined, 'btn-primary'); // Result: "btn btn-active 42 btn-primary"
getTelLink
Converts a phone number into a tel: link by removing non-digit characters (except + for international numbers).
import { getTelLink } from '@smartive/datocms-utils'; const link = getTelLink('+1 (555) 123-4567'); // Result: "tel:+15551234567"
DatoCMS Cache Tags
Utilities for managing DatoCMS cache tags with different storage backends. Cache tags enable efficient cache invalidation by tracking which queries reference which content.
Core Utilities
import { generateQueryId, parseXCacheTagsResponseHeader } from '@smartive/datocms-utils/cache-tags'; // Generate a unique ID for a GraphQL query const queryId = generateQueryId(document, variables, headers); // Parse DatoCMS's X-Cache-Tags header const tags = parseXCacheTagsResponseHeader('tag-a tag-2 other-tag'); // Result: ['tag-a', 'tag-2', 'other-tag']
Storage Providers
The package provides multiple storage backends for cache tags: Neon (Postgres), Redis, and Noop. All implement the same CacheTagsProvider interface, with the Noop provider being especially useful for testing and development.
Neon (Postgres) Provider
Use Neon serverless Postgres to store cache tag mappings.
Setup:
- Create the cache tags table:
CREATE TABLE IF NOT EXISTS query_cache_tags ( query_id TEXT NOT NULL, cache_tag TEXT NOT NULL, PRIMARY KEY (query_id, cache_tag) );
- Install @neondatabase/serverless
npm install @neondatabase/serverless
- Create and use the store:
import { NeonCacheTagsProvider } from '@smartive/datocms-utils/cache-tags/neon'; const provider = new NeonCacheTagsProvider({ connectionUrl: process.env.DATABASE_URL!, table: 'query_cache_tags', throwOnError: false, // Optional: Disable error throwing, defaults to `true` onError(error, ctx) { // Optional: Custom error callback console.error('CacheTagsProvider error', { error, context: ctx }); }, }); // Store cache tags for a query await provider.storeQueryCacheTags(queryId, ['item:42', 'product']); // Find queries that reference specific tags const queries = await provider.queriesReferencingCacheTags(['item:42']); // Delete specific cache tags await provider.deleteCacheTags(['item:42']); // Clear all cache tags await provider.truncateCacheTags();
Redis Provider
Use Redis to store cache tag mappings with better performance for high-traffic applications.
Setup:
- Install ioredis
- Create and use the provider:
import { RedisCacheTagsProvider } from '@smartive/datocms-utils/cache-tags/redis'; const provider = new RedisCacheTagsProvider({ connectionUrl: process.env.REDIS_URL!, keyPrefix: 'prod:', // Optional: namespace for multi-environment setups throwOnError: process.env.NODE_ENV === 'development', // Optional: Disable error throwing in production - defaults to `true` }); // Same API as Neon provider await provider.storeQueryCacheTags(queryId, ['item:42', 'product']); const queries = await provider.queriesReferencingCacheTags(['item:42']); await provider.deleteCacheTags(['item:42']); await provider.truncateCacheTags();
Redis connection string examples:
# Upstash Redis REDIS_URL=rediss://default:token@endpoint.upstash.io:6379 # Redis Cloud REDIS_URL=redis://username:password@redis-host:6379 # Local development REDIS_URL=redis://localhost:6379
CacheTagsProvider Interface
Both providers implement:
storeQueryCacheTags(queryId: string, cacheTags: CacheTag[]): Store cache tags for a queryqueriesReferencingCacheTags(cacheTags: CacheTag[]): Get query IDs that reference any of the specified tagsdeleteCacheTags(cacheTags: CacheTag[]): Delete specific cache tagstruncateCacheTags(): Wipe all cache tags (use with caution)
Complete Example
import { generateQueryId, parseXCacheTagsResponseHeader } from '@smartive/datocms-utils/cache-tags'; import { RedisCacheTagsProvider } from '@smartive/datocms-utils/cache-tags/redis'; const provider = new RedisCacheTagsProvider({ connectionUrl: process.env.REDIS_URL!, keyPrefix: 'myapp:', }); // After making a DatoCMS query const queryId = generateQueryId(document, variables, request.headers); const cacheTags = parseXCacheTagsResponseHeader(response.headers['x-cache-tags']); await provider.storeQueryCacheTags(queryId, cacheTags); // When handling DatoCMS webhook for cache invalidation const affectedQueries = await provider.queriesReferencingCacheTags(webhook.entity.attributes.tags); // Revalidate affected queries... await provider.deleteCacheTags(webhook.entity.attributes.tags);
TypeScript Types
The package includes TypeScript types for DatoCMS webhooks and cache tags:
CacheTag: A branded type for cache tags, ensuring type safetyCacheTagsInvalidateWebhook: Type definition for DatoCMS cache tag invalidation webhook payloadsCacheTagsProvider: Interface for cache tag storage implementations
License
MIT © smartive AG