vinext ships two Cloudflare cache adapters you declare in vite.config.ts:
cdnAdapter()serves page-level ISR through the Cloudflare Workers Cache (ctx.cache). The origin renders fresh and the edge absorbs HIT/STALE traffic, revalidating in the background;revalidateTag()/revalidatePath()fan out toctx.cache.purge({ tags }).kvDataAdapter()backs the inner"use cache"/ fetch data cache with a Workers KV namespace instead of in-memory.
Both are wired up in vite.config.ts:
import { cdnAdapter } from "@vinext/cloudflare/cache/cdn-adapter";
import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";
vinext({
cache: {
cdn: cdnAdapter(),
data: kvDataAdapter(), // binding defaults to VINEXT_KV_CACHE
},
});The Workers Cache only exposes ctx.cache when cache.enabled: true is set
in wrangler.jsonc, and the KV adapter needs a matching VINEXT_KV_CACHE
namespace binding — both are configured there.
- ISR-cached App Router page at
/cached/[slug](revalidate = 60). - Cached App Route handler at
/api/now(revalidate = 30). - Force-dynamic comparison page at
/dynamic. - Revalidation API at
/api/revalidate-tagand/api/revalidate-paththat drives the UI's "Invalidate this page" controls. - A client-side probe that issues a no-store fetch against a route and
prints the headers Cloudflare's edge attaches —
cf-cache-status(the outer Workers Cache verdict),Age, plus theCache-Control/Cache-Tagheaders vinext emits to drive it.
-
vite.config.tsdeclares the adapters viavinext({ cache })(see above). The descriptors are plain serializable values — they don't touch the Workers runtime at build/dev time; the adapters instantiate lazily on the first request. -
wrangler.jsoncenables the platform cache and binds the KV namespace:Create the namespace with
npx wrangler kv namespace create VINEXT_KV_CACHEand drop the returned id in. -
The Worker entry uses vinext's router-selected handler directly from
wrangler.jsonc:{ "main": "vinext/server/fetch-handler" }The handler registers the configured adapters on the first request — passing the Worker's
envsokvDataAdapter()can resolve its KV binding — then threads the request'sExecutionContextthrough ALS socdnAdapter()can reachctx.cacheat revalidation time. No manual registration. -
ISR responses carry
CDN-Cache-Control: public, max-age=N, stale-while-revalidate=M(for the edge) plus a browser-facingCache-Control: public, max-age=0, must-revalidate, and aCache-Tagheader listing both the bare path (/cached/intro) and Next.js's internal_N_T_<path>form. The Workers Cache reads these to cache and tag-purge. -
revalidateTag/revalidatePathin your route handlers fan out to both the KV data cache andctx.cache.purge(...)on the platform layer.
pnpm install
pnpm devThen open http://localhost:5173 and click into any of the demo routes.
Note: dev runs on
@cloudflare/vite-plugin(miniflare), so theVINEXT_KV_CACHEnamespace is emulated locally andkvDataAdapter()works. The edge CDN layer (cf-cache-status, background revalidation) only runs on Cloudflare's edge — locally theCDN-Cache-Control/Cache-TagheaderscdnAdapter()emits are what drive it once deployed.
pnpm build
npx wrangler deploy
{ "cache": { "enabled": true }, "kv_namespaces": [ { "binding": "VINEXT_KV_CACHE", "id": "<your-kv-namespace-id>" } ] }