| 1 | # Cloudflare Website: vinext |
| 2 | |
| 3 | Deploys a [vinext](https://vinext.dev) App Router app to Cloudflare |
| 4 | Workers with `Cloudflare.Website.Vinext` — Vite plus the Next.js API, |
| 5 | KV-backed ISR, no `wrangler.jsonc`. This is not the OpenNext path used |
| 6 | by `Cloudflare.Website.Nextjs`. |
| 7 | |
| 8 | Alchemy loads the project's `vite.config.ts`, injects the Cloudflare |
| 9 | Vite plugin, deploys the RSC Worker plus client assets, prerenders |
| 10 | routes, and seeds `VINEXT_KV_CACHE`. Values passed via `env` are |
| 11 | available in server components and route handlers as |
| 12 | `import { env } from "cloudflare:workers"`. |
| 13 | |
| 14 | - Home is SSR and reads `GREETING`. `/static` is prerendered. `/isr` |
| 15 | is ISR. `/use-cache` is a dynamic page plus `"use cache"`. |
| 16 | - `/api/*` is an App Router catch-all. Notes go to a sibling Worker |
| 17 | over the `BACKEND` service binding; `/api/kv` uses the site `KV`. |
| 18 | - `proxy.ts` returns 403 for `/admin`. |
| 19 | - Everything under `public/` deploys as static assets. |
| 20 | |
| 21 | ```ts |
| 22 | export class Vinext extends Cloudflare.Website.Vinext<Vinext>()("Vinext", { |
| 23 | env: { |
| 24 | GREETING: "Hello from vinext on Cloudflare!", |
| 25 | BACKEND: Backend, |
| 26 | KV, |
| 27 | }, |
| 28 | }); |
| 29 | ``` |
| 30 | |
| 31 | ## Run locally |
| 32 | |
| 33 | ```sh |
| 34 | bun alchemy dev |
| 35 | ``` |
| 36 | |
| 37 | Alchemy starts Vite with hot module replacement and local Worker bindings. |
| 38 | The example includes a counter, cache-refresh server actions, and Notes CRUD. |
| 39 | |
| 40 | ## Deploy |
| 41 | |
| 42 | ```sh |
| 43 | bun alchemy deploy --profile testing |
| 44 | ``` |
| 45 | |
| 46 | ## Cache and bindings |
| 47 | |
| 48 | - Install `vinext`, `@vitejs/plugin-rsc`, and `react-server-dom-webpack` |
| 49 | in the app. `react-server-dom-webpack` is vinext's RSC flight runtime |
| 50 | (same package Next uses); the name is historical — this app does not |
| 51 | use webpack. |
| 52 | - Do not bind `VINEXT_KV_CACHE` or `CF_VERSION_METADATA`. `Website.Vinext` |
| 53 | provisions the KV namespace, enables Workers Cache, and binds version |
| 54 | metadata. The resource injects the KV data-cache adapter automatically; |
| 55 | no Alchemy plugin is needed in `vite.config.ts`. Deploy seeds prerender |
| 56 | pairs into KV. |
| 57 | - Do not register `@cloudflare/vite-plugin`. Alchemy injects |
| 58 | `vite-plugin-cloudflare:alchemy` (vinext matches the prefix) and |
| 59 | no-ops the official plugin if it is still present. |
| 60 | - Unchanged sources skip the Vite build on subsequent deploys (the |
| 61 | project tree is content-hashed, scoped by `memo.include`). |
| 62 | |
| 63 | ## Test |
| 64 | |
| 65 | ```sh |
| 66 | ALCHEMY_PROFILE=testing bun test test/dev.test.ts |
| 67 | ALCHEMY_PROFILE=testing bun test test/integ.test.ts |
| 68 | ``` |
| 69 | |
| 70 | The development suite verifies local routes, bindings, and hot module replacement. |
| 71 | The live suite verifies rendered routes, caching, static assets, the proxy, |
| 72 | D1 writes, and KV round trips. It destroys its deployment after the tests. |
| 73 | |
| 74 | ## Clean up |
| 75 | |
| 76 | ```sh |
| 77 | bun alchemy destroy --profile testing |
| 78 | ``` |
| 79 | |
| 80 | See the [vinext guide](https://alchemy.run/cloudflare/frontend/vinext/). |