void 0.1.6 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_PROMPT.md +15 -0
- package/README.md +62 -123
- package/dist/auth-BdsJ0Aff.d.mts +43 -0
- package/dist/auth-cmd-Dx8oPKZC.mjs +43 -0
- package/dist/auth-migrations-BAtAck2g.mjs +117 -0
- package/dist/better-auth-shared-C9_GHSkR.d.mts +71 -0
- package/dist/better-auth-shared-CdYmQGry.mjs +163 -0
- package/dist/cache-W82I8ihI.mjs +47 -0
- package/dist/cancel-deploy-BOBTqqh0.mjs +59 -0
- package/dist/cf-access-Dee5cXxL.mjs +22 -0
- package/dist/chunk-DJd-R1mw.mjs +34 -0
- package/dist/cli/cli.d.mts +1 -0
- package/dist/cli/cli.mjs +1807 -0
- package/dist/client-snXOjrp1.mjs +565 -0
- package/dist/collect-CjeZgz5D.mjs +55 -0
- package/dist/config-BIa9HwVX.mjs +573 -0
- package/dist/config-BzM9Dy7T.mjs +37 -0
- package/dist/config-CvHtTM0q.mjs +30 -0
- package/dist/create-project-BIA15W7z.mjs +90 -0
- package/dist/db-DsRoMcfN.mjs +895 -0
- package/dist/defer-DcxEsVH1.mjs +49 -0
- package/dist/delete-DAP6yDc7.mjs +64 -0
- package/dist/deploy-BPKblFx6.mjs +2424 -0
- package/dist/discover-B7FkXBLB.mjs +40 -0
- package/dist/dist-DUyXJLkq.mjs +2667 -0
- package/dist/dist-Dayj3gCK.mjs +1287 -0
- package/dist/domain-BGofcQ6I.mjs +79 -0
- package/dist/dotenv-DwO4ti0Z.mjs +173 -0
- package/dist/drizzle-NnudE_UN.mjs +232 -0
- package/dist/env-CyG3tvU0.mjs +301 -0
- package/dist/env-helpers-Dr9Y7RnE.d.mts +52 -0
- package/dist/env-raw-BDL4TvdN.mjs +32 -0
- package/dist/env-types-DknSA4SO.mjs +64 -0
- package/dist/env-validation-DJKjR_8q.mjs +163 -0
- package/dist/fetch-error-BQ8sZ5Nd.mjs +266 -0
- package/dist/fetch-error-CVZ5CGA-.d.mts +20 -0
- package/dist/gen-U0Ktr4Zd.mjs +761 -0
- package/dist/handler-B0ds0OHJ.d.mts +269 -0
- package/dist/head-P-egrtFE.d.mts +45 -0
- package/dist/headers-DCXc7mDs.mjs +279 -0
- package/dist/index.d.mts +32 -0
- package/dist/index.mjs +4695 -0
- package/dist/init-C7wS5iGP.mjs +2625 -0
- package/dist/link-p2R6NbgN.mjs +49 -0
- package/dist/list-Bfel-QLc.mjs +113 -0
- package/dist/log-DXdqnmhF.mjs +26 -0
- package/dist/login-CkcXUiIu.mjs +72 -0
- package/dist/logs-DmkrRvx6.mjs +98 -0
- package/dist/magic-string.es-D6g9UnIy.mjs +1011 -0
- package/dist/mcp-CaQzfeUi.mjs +373 -0
- package/dist/node-DDfXj10V.mjs +54 -0
- package/dist/output-BwlcIYSR.mjs +139 -0
- package/dist/pages/client.d.mts +198 -0
- package/dist/pages/client.mjs +980 -0
- package/dist/pages/head-client.d.mts +15 -0
- package/dist/pages/head-client.mjs +90 -0
- package/dist/pages/head.d.mts +2 -0
- package/dist/pages/head.mjs +112 -0
- package/dist/pages/index.d.mts +38 -0
- package/dist/pages/index.mjs +76 -0
- package/dist/pages/islands-plugin.d.mts +50 -0
- package/dist/pages/islands-plugin.mjs +195 -0
- package/dist/pages/prefetch.d.mts +31 -0
- package/dist/pages/prefetch.mjs +90 -0
- package/dist/pages/protocol.d.mts +3 -0
- package/dist/pages/protocol.mjs +193 -0
- package/dist/pages/serialize.d.mts +10 -0
- package/dist/pages/serialize.mjs +14 -0
- package/dist/pathe.M-eThtNZ-D-kmWkCS.mjs +150 -0
- package/dist/plugin-inference-oZ6Ybu2_.mjs +2447 -0
- package/dist/prepare-BAtWufvm.mjs +99 -0
- package/dist/preset-D4I73kT4.mjs +221 -0
- package/dist/project-TqORyHn8.mjs +72 -0
- package/dist/project-cmd-B7lQp3F3.mjs +67 -0
- package/dist/project-slug-CKam8lF9.mjs +11 -0
- package/dist/project-tsconfig-DfkESbDL.mjs +63 -0
- package/dist/protocol-BWzXs2A2.d.mts +34 -0
- package/dist/providers-B3aMxWzP.mjs +67 -0
- package/dist/resolve-project-Br5BR03U.mjs +29 -0
- package/dist/rollback-gyC59l7U.mjs +92 -0
- package/dist/route-types-DReF1gUY.mjs +255 -0
- package/dist/routes-stub.d.mts +55 -0
- package/dist/routes-stub.mjs +1 -0
- package/dist/runner-6Ep3fNQu.mjs +123 -0
- package/dist/runner-pg-D0wWHYnr.mjs +57 -0
- package/dist/runtime/ai.d.mts +127 -0
- package/dist/runtime/ai.mjs +348 -0
- package/dist/runtime/auth-client-react.d.mts +8 -0
- package/dist/runtime/auth-client-react.mjs +6 -0
- package/dist/runtime/auth-client-solid.d.mts +8 -0
- package/dist/runtime/auth-client-solid.mjs +6 -0
- package/dist/runtime/auth-client-svelte.d.mts +8 -0
- package/dist/runtime/auth-client-svelte.mjs +6 -0
- package/dist/runtime/auth-client-vue.d.mts +8 -0
- package/dist/runtime/auth-client-vue.mjs +6 -0
- package/dist/runtime/auth-client.d.mts +8 -0
- package/dist/runtime/auth-client.mjs +6 -0
- package/dist/runtime/auth.d.mts +2 -0
- package/dist/runtime/auth.mjs +22 -0
- package/dist/runtime/better-auth-pg.d.mts +11 -0
- package/dist/runtime/better-auth-pg.mjs +51 -0
- package/dist/runtime/better-auth.d.mts +11 -0
- package/dist/runtime/better-auth.mjs +33 -0
- package/dist/runtime/client.d.mts +6 -0
- package/dist/runtime/client.mjs +5 -0
- package/dist/runtime/db-pg.d.mts +2 -0
- package/dist/runtime/db-pg.mjs +1 -0
- package/dist/runtime/db.d.mts +17 -0
- package/dist/runtime/db.mjs +30 -0
- package/dist/runtime/drizzle-arktype.d.mts +1 -0
- package/dist/runtime/drizzle-arktype.mjs +2 -0
- package/dist/runtime/drizzle-valibot.d.mts +1 -0
- package/dist/runtime/drizzle-valibot.mjs +2 -0
- package/dist/runtime/drizzle-zod.d.mts +1 -0
- package/dist/runtime/drizzle-zod.mjs +2 -0
- package/dist/runtime/env-helpers.d.mts +2 -0
- package/dist/runtime/env-helpers.mjs +173 -0
- package/dist/runtime/env-public-client.d.mts +22 -0
- package/dist/runtime/env-public-client.mjs +54 -0
- package/dist/runtime/env-public.d.mts +143 -0
- package/dist/runtime/env-public.mjs +366 -0
- package/dist/runtime/env.d.mts +13 -0
- package/dist/runtime/env.mjs +51 -0
- package/dist/runtime/fetch-stream.d.mts +51 -0
- package/dist/runtime/fetch-stream.mjs +81 -0
- package/dist/runtime/fetch.d.mts +59 -0
- package/dist/runtime/fetch.mjs +18 -0
- package/dist/runtime/handler.d.mts +3 -0
- package/dist/runtime/handler.mjs +85 -0
- package/dist/runtime/isr.d.mts +26 -0
- package/dist/runtime/isr.mjs +43 -0
- package/dist/runtime/kv.d.mts +48 -0
- package/dist/runtime/kv.mjs +106 -0
- package/dist/runtime/log.d.mts +24 -0
- package/dist/runtime/log.mjs +31 -0
- package/dist/runtime/migration-handler-pg.d.mts +6 -0
- package/dist/runtime/migration-handler-pg.mjs +85 -0
- package/dist/runtime/migration-handler.d.mts +19 -0
- package/dist/runtime/migration-handler.mjs +92 -0
- package/dist/runtime/queues.d.mts +7 -0
- package/dist/runtime/queues.mjs +8 -0
- package/dist/runtime/remote/binding-handler.d.mts +15 -0
- package/dist/runtime/remote/binding-handler.mjs +208 -0
- package/dist/runtime/remote/index.d.mts +8 -0
- package/dist/runtime/remote/index.mjs +461 -0
- package/dist/runtime/response.d.mts +14 -0
- package/dist/runtime/response.mjs +30 -0
- package/dist/runtime/sandbox.d.mts +17 -0
- package/dist/runtime/sandbox.mjs +19 -0
- package/dist/runtime/schema-d1.d.mts +1 -0
- package/dist/runtime/schema-d1.mjs +2 -0
- package/dist/runtime/schema-pg.d.mts +1 -0
- package/dist/runtime/schema-pg.mjs +2 -0
- package/dist/runtime/seed.d.mts +30 -0
- package/dist/runtime/seed.mjs +6 -0
- package/dist/runtime/storage.d.mts +7 -0
- package/dist/runtime/storage.mjs +14 -0
- package/dist/runtime/validator.d.mts +2 -0
- package/dist/runtime/validator.mjs +72 -0
- package/dist/runtime/ws-server.d.mts +26 -0
- package/dist/runtime/ws-server.mjs +296 -0
- package/dist/runtime/ws.d.mts +123 -0
- package/dist/runtime/ws.mjs +103 -0
- package/dist/scan-Ba4hFwlH.mjs +324 -0
- package/dist/scan-C6HMEIdW.mjs +318 -0
- package/dist/secret-CeRSukgM.mjs +109 -0
- package/dist/skills-ipldjlKE.mjs +62 -0
- package/dist/standard-schema-9CRjx-uR.d.mts +42 -0
- package/dist/subcommand-prompt-BKjuNAPb.mjs +349 -0
- package/dist/sveltekit.d.mts +20 -0
- package/dist/sveltekit.mjs +61 -0
- package/dist/types-mHOEwpW4.d.mts +57 -0
- package/dist/validate-CaMavMxu.mjs +146 -0
- package/dist/yarn-pnp-BFqMV_bl.mjs +196 -0
- package/getting-started-prompt.txt +26 -0
- package/package.json +322 -30
- package/schema.json +364 -0
- package/skills/migrate-vite-cloudflare-to-void/SKILL.md +175 -0
- package/skills/void/SKILL.md +75 -0
- package/skills/void/command/void.md +7 -0
- package/skills/void/docs/guide/ai.md +235 -0
- package/skills/void/docs/guide/app-types.md +103 -0
- package/skills/void/docs/guide/auth.md +257 -0
- package/skills/void/docs/guide/database/d1.md +106 -0
- package/skills/void/docs/guide/database/postgresql.md +106 -0
- package/skills/void/docs/guide/database.md +418 -0
- package/skills/void/docs/guide/deployment.md +98 -0
- package/skills/void/docs/guide/edge/headers.md +79 -0
- package/skills/void/docs/guide/edge/prerendering.md +83 -0
- package/skills/void/docs/guide/edge/redirects.md +116 -0
- package/skills/void/docs/guide/edge/revalidation.md +131 -0
- package/skills/void/docs/guide/edge/rewrites.md +354 -0
- package/skills/void/docs/guide/edge/static-assets.md +72 -0
- package/skills/void/docs/guide/env-vars.md +298 -0
- package/skills/void/docs/guide/index.md +80 -0
- package/skills/void/docs/guide/jobs.md +91 -0
- package/skills/void/docs/guide/kv.md +107 -0
- package/skills/void/docs/guide/pages-routing/actions-and-forms.md +419 -0
- package/skills/void/docs/guide/pages-routing/head.md +130 -0
- package/skills/void/docs/guide/pages-routing/islands.md +405 -0
- package/skills/void/docs/guide/pages-routing/layouts.md +362 -0
- package/skills/void/docs/guide/pages-routing/loaders.md +267 -0
- package/skills/void/docs/guide/pages-routing/markdown.md +625 -0
- package/skills/void/docs/guide/pages-routing/overview.md +236 -0
- package/skills/void/docs/guide/pages-routing/view-transitions.md +140 -0
- package/skills/void/docs/guide/queues.md +140 -0
- package/skills/void/docs/guide/quickstart.md +233 -0
- package/skills/void/docs/guide/remote-dev.md +67 -0
- package/skills/void/docs/guide/sandboxes.md +82 -0
- package/skills/void/docs/guide/server-routing.md +246 -0
- package/skills/void/docs/guide/ssg.md +74 -0
- package/skills/void/docs/guide/ssr.md +105 -0
- package/skills/void/docs/guide/storage.md +67 -0
- package/skills/void/docs/guide/type-safety.md +179 -0
- package/skills/void/docs/guide/typed-fetch.md +113 -0
- package/skills/void/docs/guide/websockets.md +190 -0
- package/skills/void/docs/index.md +48 -0
- package/skills/void/docs/integrations/agents.md +84 -0
- package/skills/void/docs/integrations/cloudflare.md +284 -0
- package/skills/void/docs/integrations/frameworks/analog.md +182 -0
- package/skills/void/docs/integrations/frameworks/astro.md +197 -0
- package/skills/void/docs/integrations/frameworks/nuxt.md +164 -0
- package/skills/void/docs/integrations/frameworks/overview.md +136 -0
- package/skills/void/docs/integrations/frameworks/react-router.md +137 -0
- package/skills/void/docs/integrations/frameworks/sveltekit.md +191 -0
- package/skills/void/docs/integrations/frameworks/tanstack-start.md +140 -0
- package/skills/void/docs/integrations/hono.md +97 -0
- package/skills/void/docs/integrations/nodejs-bun-deno.md +210 -0
- package/skills/void/docs/node_modules/@iconify/vue/README.md +408 -0
- package/skills/void/docs/node_modules/@iconify/vue/offline/readme.md +5 -0
- package/skills/void/docs/node_modules/@voidzero-dev/vitepress-theme/README.md +103 -0
- package/skills/void/docs/node_modules/oxc-minify/README.md +78 -0
- package/skills/void/docs/node_modules/reka-ui/README.md +80 -0
- package/skills/void/docs/node_modules/vitepress/README.md +28 -0
- package/skills/void/docs/node_modules/vitepress/template/api-examples.md +49 -0
- package/skills/void/docs/node_modules/vitepress/template/index.md +28 -0
- package/skills/void/docs/node_modules/vitepress/template/markdown-examples.md +85 -0
- package/skills/void/docs/node_modules/vitepress-plugin-group-icons/README.md +101 -0
- package/skills/void/docs/node_modules/void/AGENTS.md +204 -0
- package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +15 -0
- package/skills/void/docs/node_modules/void/README.md +89 -0
- package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/CHANGELOG.md +591 -0
- package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/README.md +375 -0
- package/skills/void/docs/node_modules/void/node_modules/@cloudflare/sandbox/README.md +174 -0
- package/skills/void/docs/node_modules/void/node_modules/@cloudflare/vite-plugin/README.md +37 -0
- package/skills/void/docs/node_modules/void/node_modules/@cloudflare/workers-types/README.md +135 -0
- package/skills/void/docs/node_modules/void/node_modules/@electric-sql/pglite/README.md +189 -0
- package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/CHANGELOG.md +143 -0
- package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/README.md +1272 -0
- package/skills/void/docs/node_modules/void/node_modules/@napi-rs/keyring/README.md +19 -0
- package/skills/void/docs/node_modules/void/node_modules/@types/better-sqlite3/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@types/node/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@types/pg/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/README.md +22 -0
- package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/vendor/vscode-jsonrpc/README.md +69 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/README.md +152 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/engine-javascript/README.md +9 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/transformers/README.md +9 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@types/node/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/CHANGELOG.md +24 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/README.md +565 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-exit/README.md +124 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-anchor/README.md +600 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-attrs/README.md +386 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-container/README.md +95 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-emoji/README.md +101 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/pathe/README.md +73 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/shiki/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tinyglobby/README.md +25 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tsdown/README.md +55 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite/LICENSE.md +2230 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite/README.md +20 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vue/README.md +58 -0
- package/skills/void/docs/node_modules/void/node_modules/arktype/README.md +165 -0
- package/skills/void/docs/node_modules/void/node_modules/better-auth/LICENSE.md +20 -0
- package/skills/void/docs/node_modules/void/node_modules/better-auth/README.md +32 -0
- package/skills/void/docs/node_modules/void/node_modules/better-sqlite3/README.md +99 -0
- package/skills/void/docs/node_modules/void/node_modules/blake3-jit/README.md +108 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-arktype/README.md +51 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-kit/README.md +79 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-orm/README.md +44 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-valibot/README.md +51 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-zod/README.md +65 -0
- package/skills/void/docs/node_modules/void/node_modules/es-module-lexer/README.md +390 -0
- package/skills/void/docs/node_modules/void/node_modules/estree-walker/README.md +48 -0
- package/skills/void/docs/node_modules/void/node_modules/hono/README.md +85 -0
- package/skills/void/docs/node_modules/void/node_modules/ignore/README.md +452 -0
- package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/CHANGELOG.md +76 -0
- package/{LICENSE → skills/void/docs/node_modules/void/node_modules/jsonc-parser/LICENSE.md} +21 -21
- package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/README.md +364 -0
- package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/SECURITY.md +41 -0
- package/skills/void/docs/node_modules/void/node_modules/magic-string/README.md +325 -0
- package/skills/void/docs/node_modules/void/node_modules/ofetch/README.md +398 -0
- package/skills/void/docs/node_modules/void/node_modules/pathe/README.md +73 -0
- package/skills/void/docs/node_modules/void/node_modules/pg/README.md +95 -0
- package/skills/void/docs/node_modules/void/node_modules/pglite-server/LICENSE.md +21 -0
- package/skills/void/docs/node_modules/void/node_modules/pglite-server/README.md +135 -0
- package/skills/void/docs/node_modules/void/node_modules/picocolors/README.md +21 -0
- package/skills/void/docs/node_modules/void/node_modules/tinyglobby/README.md +25 -0
- package/skills/void/docs/node_modules/void/node_modules/tsdown/README.md +55 -0
- package/skills/void/docs/node_modules/void/node_modules/valibot/LICENSE.md +9 -0
- package/skills/void/docs/node_modules/void/node_modules/valibot/README.md +94 -0
- package/skills/void/docs/node_modules/void/node_modules/vite/LICENSE.md +2230 -0
- package/skills/void/docs/node_modules/void/node_modules/vite/README.md +20 -0
- package/skills/void/docs/node_modules/void/node_modules/wrangler/README.md +63 -0
- package/skills/void/docs/node_modules/void/node_modules/zod/README.md +191 -0
- package/skills/void/docs/node_modules/void/skills/migrate-vite-cloudflare-to-void/SKILL.md +175 -0
- package/skills/void/docs/node_modules/void/skills/void/SKILL.md +75 -0
- package/skills/void/docs/node_modules/void/skills/void/command/void.md +7 -0
- package/skills/void/docs/reference/api.md +917 -0
- package/skills/void/docs/reference/cli.md +561 -0
- package/skills/void/docs/reference/config.md +408 -0
- package/skills/void/docs/reference/resource-inference.md +149 -0
- package/skills/void/docs/reference/structure.md +176 -0
- package/.npmignore +0 -29
- package/.travis.yml +0 -9
- package/favicon.ico +0 -0
- package/index.js +0 -14
- package/lib/Job.js +0 -150
- package/lib/Void.js +0 -99
- package/lib/scan.js +0 -19
- package/test/credentials.js +0 -20
- package/test/job.js +0 -64
- package/test/static/dir1/test6.html +0 -0
- package/test/static/dir2/test7.html +0 -0
- package/test/static/dir2/test8.html +0 -0
- package/test/static/dir2/test9.html +0 -0
- package/test/static/test1.html +0 -0
- package/test/static/test2.html +0 -0
- package/test/static/test3.html +0 -0
- package/test/void.js +0 -31
- /package/{test/static/dir1/test4.html → skills/void/docs/integrations/auth-providers.md} +0 -0
- /package/{test/static/dir1/test5.html → skills/void/docs/integrations/payment-processors.md} +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Deployment
|
|
6
|
+
|
|
7
|
+
Void apps run on Cloudflare's infrastructure but you don't need to use your own Cloudflare account. Our long term goal is to provide a simpler app-centric deployment experience similar to that of Vercel and Netlify. But right now, Void only supports deploying via the CLI or GitHub actions.
|
|
8
|
+
|
|
9
|
+
## CLI
|
|
10
|
+
|
|
11
|
+
### First deploy
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
void init # can handle auth + project setup during onboarding
|
|
15
|
+
void deploy # auto-detects app type, builds, deploys
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
If you skipped Void project setup during `void init`, you can still run `void auth login` manually. On first deploy, the CLI will prompt you to create or select a project if none is linked yet. The project link is saved to `.void/project.json` for subsequent deploys.
|
|
19
|
+
|
|
20
|
+
### Migrations
|
|
21
|
+
|
|
22
|
+
If your app uses Drizzle, `void deploy` runs migrations as part of the deploy flow:
|
|
23
|
+
|
|
24
|
+
1. Build the app
|
|
25
|
+
2. Read SQL migrations from `db/migrations/`
|
|
26
|
+
3. Fail if the schema has drifted ahead of the committed migrations
|
|
27
|
+
4. Apply pending migrations to the target database
|
|
28
|
+
5. Make the new deploy live
|
|
29
|
+
|
|
30
|
+
Deploy always uses checked-in migration files. If drift is detected, run `void db generate`, review the generated migration, commit it yourself, then rerun deploy. For the full database workflow and backend-specific details, see the [Database guide](./database.md).
|
|
31
|
+
|
|
32
|
+
### Flags
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
void deploy [--project <name>] [--dir <path>] [--spa]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
| Flag | Purpose |
|
|
39
|
+
| ------------------ | ------------------------------------------------- |
|
|
40
|
+
| `--project <name>` | Target a specific project by slug |
|
|
41
|
+
| `--dir <path>` | Deploy a pre-built static directory (skips build) |
|
|
42
|
+
| `--spa` | Use SPA mode instead of SSG for static deploys |
|
|
43
|
+
|
|
44
|
+
### Project resolution
|
|
45
|
+
|
|
46
|
+
The CLI resolves which project to deploy to in this order:
|
|
47
|
+
|
|
48
|
+
1. `--project <name>` flag
|
|
49
|
+
2. `VOID_PROJECT` environment variable
|
|
50
|
+
3. Linked project in `.void/project.json`
|
|
51
|
+
|
|
52
|
+
If none match, the CLI prompts interactively.
|
|
53
|
+
|
|
54
|
+
### CI preparation
|
|
55
|
+
|
|
56
|
+
If your CI pipeline runs typechecking or other static analysis before deploy, run `void prepare` after install to generate the `.void/` artifacts without booting Vite.
|
|
57
|
+
|
|
58
|
+
### Environment variables
|
|
59
|
+
|
|
60
|
+
| Variable | Purpose |
|
|
61
|
+
| -------------- | -------------------------------- |
|
|
62
|
+
| `VOID_TOKEN` | Auth token (for CI, skips OAuth) |
|
|
63
|
+
| `VOID_PROJECT` | Project slug override |
|
|
64
|
+
|
|
65
|
+
## GitHub Actions
|
|
66
|
+
|
|
67
|
+
You can deploy from a GitHub repo with a simple GitHub Actions workflow. Running `void init --github` will generate this as `.github/workflows/deploy.yml` in your project:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
name: Deploy
|
|
71
|
+
on:
|
|
72
|
+
push:
|
|
73
|
+
branches: [main]
|
|
74
|
+
|
|
75
|
+
jobs:
|
|
76
|
+
deploy:
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v4
|
|
80
|
+
- uses: pnpm/action-setup@v4
|
|
81
|
+
- uses: actions/setup-node@v4
|
|
82
|
+
with:
|
|
83
|
+
node-version: 22
|
|
84
|
+
cache: pnpm
|
|
85
|
+
- run: pnpm install
|
|
86
|
+
- run: pnpm void deploy
|
|
87
|
+
env:
|
|
88
|
+
VOID_TOKEN: ${{ secrets.VOID_TOKEN }}
|
|
89
|
+
VOID_PROJECT: my-app
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
To get a deploy token, run `void auth token` to copy it to your clipboard, then add it as a GitHub Actions secret.
|
|
93
|
+
|
|
94
|
+
## Other Targets
|
|
95
|
+
|
|
96
|
+
If you prefer to deploy directly to your own Cloudflare account instead of using Void's managed platform, see the [Cloudflare integration guide](../integrations/cloudflare.md).
|
|
97
|
+
|
|
98
|
+
To deploy to Node.js, Bun, or Deno instead of Cloudflare, set [`target`](../reference/config.md) in `void.json`. This builds a standalone server you can run anywhere, including Docker, Railway, and Fly.io. These targets do not have access to Void platform features such as D1, KV, R2, built-in auth, Workers AI, or cron scheduling. See the [Node.js, Bun, and Deno guide](../integrations/nodejs-bun-deno.md).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Custom Headers
|
|
6
|
+
|
|
7
|
+
Define custom response headers in [`void.json`](../../reference/config) using the `routing.headers` field. Keys are URL patterns, values are arrays of `"Name: value"` strings.
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"routing": {
|
|
12
|
+
"headers": {
|
|
13
|
+
"/assets/*": ["Cache-Control: public, max-age=31536000, immutable"],
|
|
14
|
+
"/*": ["X-Frame-Options: DENY", "X-Content-Type-Options: nosniff"],
|
|
15
|
+
"/*.html": ["Cache-Control: no-cache"]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Rules
|
|
22
|
+
|
|
23
|
+
- **Pattern keys** start with `/`. `*` matches any characters including `/`.
|
|
24
|
+
- **Header values** use `Name: value` format. The value may contain colons.
|
|
25
|
+
- All matching rules are merged. When multiple rules set the same header name, the **last match wins**.
|
|
26
|
+
- User-defined `Cache-Control` overrides the built-in default. The default still applies when no rule matches.
|
|
27
|
+
|
|
28
|
+
## Example: security headers
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"routing": {
|
|
33
|
+
"headers": {
|
|
34
|
+
"/*": [
|
|
35
|
+
"X-Frame-Options: DENY",
|
|
36
|
+
"X-Content-Type-Options: nosniff",
|
|
37
|
+
"Referrer-Policy: strict-origin-when-cross-origin"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Example: override caching
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"routing": {
|
|
49
|
+
"headers": {
|
|
50
|
+
"/*.html": ["Cache-Control: public, max-age=300"],
|
|
51
|
+
"/config.json": ["Cache-Control: no-store"]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Scope
|
|
58
|
+
|
|
59
|
+
Header rules apply to **all responses** served through the dispatch worker, including static assets, SSR pages, and API routes. They do not apply to:
|
|
60
|
+
|
|
61
|
+
- Hashed asset cache hits (these use immutable caching set by the dispatch worker itself)
|
|
62
|
+
- ISR cache responses (these have their own cache-control headers)
|
|
63
|
+
|
|
64
|
+
## Framework `_headers` files
|
|
65
|
+
|
|
66
|
+
Meta-frameworks like SvelteKit, Nuxt, and Astro generate a `_headers` file with cache rules for their hashed asset directories. Void automatically parses this file during deploy and merges the rules into the deploy manifest.
|
|
67
|
+
|
|
68
|
+
- Framework-generated rules are applied **before** `void.json` rules. Since the last match wins, `routing.headers` in `void.json` takes precedence and can override framework defaults.
|
|
69
|
+
- The `_headers` file is not uploaded as a static asset. Its contents are parsed and included in the manifest only.
|
|
70
|
+
|
|
71
|
+
No configuration is needed. If the framework generates a `_headers` file, it is picked up automatically.
|
|
72
|
+
|
|
73
|
+
## How headers work
|
|
74
|
+
|
|
75
|
+
1. `void deploy` reads header rules from the framework `_headers` file (if present) and `routing.headers` in `void.json`, then includes them in the deploy manifest.
|
|
76
|
+
2. The platform stores the rules in the KV routing entry for your project.
|
|
77
|
+
3. The dispatch worker applies matching rules to static responses before edge caching.
|
|
78
|
+
|
|
79
|
+
Because rules are evaluated at the edge, there is no extra latency cost. Headers are applied inline before the response is returned and cached.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Edge Prerendering
|
|
6
|
+
|
|
7
|
+
You can instruct Void to prerender a page so it is served from cache immediately after a new deploy. Prerendering happens on the platform at deploy time. The platform invokes the uploaded worker and writes the result to the edge cache.
|
|
8
|
+
|
|
9
|
+
- [Markdown pages](../pages-routing/markdown.md) are auto-prerendered.
|
|
10
|
+
- [Island pages](../pages-routing/islands) with no companion loader and no dynamic params are also auto-prerendered.
|
|
11
|
+
|
|
12
|
+
## Static pages (no params)
|
|
13
|
+
|
|
14
|
+
Export `prerender = true` from the companion `.server.ts` file:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// pages/about.server.ts
|
|
18
|
+
export const prerender = true;
|
|
19
|
+
|
|
20
|
+
export const loader = defineHandler(async (c) => {
|
|
21
|
+
// ...
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Pages with no dynamic params are automatically prerendered at their URL pattern (e.g. `/about`).
|
|
26
|
+
|
|
27
|
+
## Dynamic pages (with params)
|
|
28
|
+
|
|
29
|
+
For pages with URL params, also export `getPrerenderPaths()` to specify which param combinations to prerender:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// pages/blog/[slug].server.ts
|
|
33
|
+
export const prerender = true;
|
|
34
|
+
|
|
35
|
+
export async function getPrerenderPaths() {
|
|
36
|
+
// Return param objects matching the URL pattern
|
|
37
|
+
return [{ slug: 'hello-world' }, { slug: 'getting-started' }];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const loader = defineHandler(async (c) => {
|
|
41
|
+
// ...
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Custom SSR
|
|
46
|
+
|
|
47
|
+
In custom SSR mode (`src/main.ssr.ts`), export `getPrerenderPaths()` at the top level. Since there's no file-based routing, return full path strings:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
// src/main.ssr.ts
|
|
51
|
+
export const prerender = true;
|
|
52
|
+
|
|
53
|
+
export async function getPrerenderPaths() {
|
|
54
|
+
return ['/', '/about', '/blog/hello-world'];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default defineRender(async (c, assetTags) => {
|
|
58
|
+
// ...
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Relationship to revalidation
|
|
63
|
+
|
|
64
|
+
Pages with long revalidate TTLs (e.g. 1 year) are effectively static, but the first visitor after a deploy hits a cold cache. This is where prerendering helps - it ensures your users never get slow requests.
|
|
65
|
+
|
|
66
|
+
Enabling prerendering for a page automatically sets `revalidate` to 1 year, so you don't need to export it yourself. Since the ISR cache is cleared on every deploy, the TTL only needs to be long enough to last between deploys.
|
|
67
|
+
|
|
68
|
+
You can also explicitly set to it a different value to override the default:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
// pages/about.server.ts
|
|
72
|
+
export const prerender = true;
|
|
73
|
+
export const revalidate = 3600;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Just be aware that if no new deploy happens before the revalidate expires, the first user request after expiration will miss the cache and incur a full render.
|
|
77
|
+
|
|
78
|
+
## Behavior details
|
|
79
|
+
|
|
80
|
+
- Prerender happens once per deployment, before traffic is routed to the new version. Prerendered pages are cached at the edge.
|
|
81
|
+
- Each deploy clears the ISR cache. The deployment shows `"prerendering"` during this phase.
|
|
82
|
+
- Only paths with a positive revalidate TTL are prerendered (TTL `0` is skipped).
|
|
83
|
+
- Prerender failures are logged but never block the deploy. The page will render on the first request as usual.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Redirects
|
|
6
|
+
|
|
7
|
+
Define URL redirects in [`void.json`](../../reference/config) using the `routing.redirects` field. Keys are source URL patterns, values are destination strings or objects with an explicit status.
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"routing": {
|
|
12
|
+
"redirects": {
|
|
13
|
+
"/old": "/new",
|
|
14
|
+
"/blog/*": { "to": "/posts/:splat", "status": 301 }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Rules
|
|
21
|
+
|
|
22
|
+
- **Source patterns** start with `/`. `*` matches any characters including `/`.
|
|
23
|
+
- **Destinations** can be strings (default `302`) or objects with `to` and optional `status`. Supported statuses: `301`, `302`, `303`, `307`, `308`.
|
|
24
|
+
- `:splat` in the destination is replaced with the portion of the path matched by `*` in the source pattern.
|
|
25
|
+
- Destination query strings are merged into the `Location` header (the destination's parameters take precedence on per-key conflict). To drop the incoming query, write an explicit reset like `?`.
|
|
26
|
+
- When multiple rules match, the **first match wins**. Put more-specific rules above more-general ones (matches Netlify `_redirects` and Vercel `vercel.json` semantics).
|
|
27
|
+
- Redirects are evaluated **before** the request reaches the worker, so they short-circuit static asset serving, ISR, and SSR.
|
|
28
|
+
|
|
29
|
+
## Example: permanent redirect
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"routing": {
|
|
34
|
+
"redirects": {
|
|
35
|
+
"/old-page": { "to": "/new-page", "status": 301 }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Example: path prefix migration
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"routing": {
|
|
46
|
+
"redirects": {
|
|
47
|
+
"/blog/*": { "to": "/posts/:splat", "status": 301 }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A request to `/blog/hello-world` redirects to `/posts/hello-world` with a `301` status.
|
|
54
|
+
|
|
55
|
+
## Domain-level redirects
|
|
56
|
+
|
|
57
|
+
Scope a redirect to a specific Host header by prefixing the source with `https://host`. Useful for:
|
|
58
|
+
|
|
59
|
+
- **Domain consolidation** — redirect everything from an old marketing domain to a new one without per-host deploy config.
|
|
60
|
+
- **Canonical host enforcement** — `www.example.com` → `example.com`.
|
|
61
|
+
- **Per-domain rules on a multi-domain project** — when you've bound several custom domains to one project but want different behavior on each.
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"routing": {
|
|
66
|
+
"redirects": {
|
|
67
|
+
"https://www.example.com/*": "https://example.com/:splat",
|
|
68
|
+
"https://old-marketing.com/*": "https://example.com/:splat"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The `_redirects` file accepts the same syntax:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
https://www.example.com/* https://example.com/:splat 301!
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The host portion is split off the source and stored as a `host` field on the rule. Path-only sources (no `https://` prefix) apply to every domain bound to the project — that's the existing behavior. Host-prefixed sources only fire when the request's `Host` header matches.
|
|
81
|
+
|
|
82
|
+
### Validation
|
|
83
|
+
|
|
84
|
+
- The host must be a literal hostname — wildcards (`*.example.com`), ports, paths, and userinfo are rejected.
|
|
85
|
+
- Only `https://` is accepted. `http://` and protocol-relative `//` sources are rejected — TLS terminates upstream of the worker, so an `http://`-scoped rule physically cannot fire.
|
|
86
|
+
- The host must be **bound to your project** (either `<slug>.void.app` or a custom domain you've added via `void domain add`). `void deploy` rejects rules scoped to hosts that aren't on the project — staging the rule in the same change as the domain is the recommended flow.
|
|
87
|
+
- Custom domains in `pending` (DCV-in-progress) state are accepted. The rule deploys but stays inert until DCV completes; once the certificate is issued, the rule starts firing automatically without a redeploy.
|
|
88
|
+
|
|
89
|
+
### Combined with external destinations
|
|
90
|
+
|
|
91
|
+
The source `host` and the destination URL are independent. Combining them lets you express domain-consolidation redirects in a single rule:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
https://old.example.com/* https://www.example.com/:splat 301!
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Reads as "when a request hits `old.example.com` on any path, send a 301 to the same path on `www.example.com`."
|
|
98
|
+
|
|
99
|
+
## Framework `_redirects` files
|
|
100
|
+
|
|
101
|
+
Meta-frameworks may generate a `_redirects` file during build. Void parses this file at deploy time and merges the rules into the deploy manifest.
|
|
102
|
+
|
|
103
|
+
- `void.json` rules are applied **before** framework-generated `_redirects` rules. Since the first match wins, `routing.redirects` in `void.json` takes precedence.
|
|
104
|
+
- Both 3xx redirect rules and status `200` [rewrite rules](./rewrites) are supported in `_redirects` files.
|
|
105
|
+
- The `!` force suffix is only meaningful on `200` entries (see [rewrites — `_redirects` file](./rewrites#redirects-file)). On 3xx entries (`301!`, `302!`, `307!`, `308!`) it's silently stripped — a redirect always "forces" by nature, so the suffix is redundant. `void deploy` prints a single aggregated warning tallying every such entry so you can clean them up.
|
|
106
|
+
- The `_redirects` file is not uploaded as a static asset. Its contents are parsed and included in the manifest only.
|
|
107
|
+
|
|
108
|
+
Precedence when the same source appears in both sources follows the same rules as rewrites — config rules are merged before file rules within each phase, and first match wins, so `void.json` overrides `_redirects`. See [Precedence: `_redirects` vs `void.json`](./rewrites#precedence-redirects-vs-void-json) for the full explanation and a worked example.
|
|
109
|
+
|
|
110
|
+
## How redirects work
|
|
111
|
+
|
|
112
|
+
1. `void deploy` reads redirect rules from the framework `_redirects` file (if present) and `routing.redirects` in `void.json`, then includes them in the deploy manifest.
|
|
113
|
+
2. The platform stores the rules in the KV routing entry for your project.
|
|
114
|
+
3. The dispatch worker checks redirect rules before any worker invocation, so matching requests get a redirect response immediately.
|
|
115
|
+
|
|
116
|
+
Because rules are evaluated at the edge before invoking the worker, redirects add no latency to the request path.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Revalidation (ISR)
|
|
6
|
+
|
|
7
|
+
For SSR and [Pages mode](../pages-routing/overview) projects, Void supports stale-while-revalidate caching for dynamically rendered pages. Cached pages are served instantly from the edge while the worker re-renders in the background when the cache is stale. This is the equivalent of [Incremental Static Regeneration (ISR)](https://vercel.com/docs/incremental-static-regeneration) in other frameworks.
|
|
8
|
+
|
|
9
|
+
This requires [SSR](../ssr.md) or [Pages mode](../pages-routing/overview) to be configured.
|
|
10
|
+
|
|
11
|
+
## Enabling revalidation
|
|
12
|
+
|
|
13
|
+
Add a `routing.revalidate` field to `void.json` with a TTL in seconds:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"routing": {
|
|
18
|
+
"revalidate": 60
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Setting `revalidate` to `0` disables revalidation (equivalent to plain SSR).
|
|
24
|
+
|
|
25
|
+
## Per-path revalidation
|
|
26
|
+
|
|
27
|
+
You can set different TTLs for different URL patterns using an object:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"routing": {
|
|
32
|
+
"revalidate": {
|
|
33
|
+
"/": 60,
|
|
34
|
+
"/docs/*": 31536000,
|
|
35
|
+
"/user/*": 0,
|
|
36
|
+
"*": 30
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Rules are matched in order, and the first match wins. The `*` glob matches any characters including `/`.
|
|
43
|
+
|
|
44
|
+
Special values:
|
|
45
|
+
|
|
46
|
+
- `31536000` (1 year): effectively cached until the next deploy, since deploys clear the ISR cache
|
|
47
|
+
- `0`: never cached and always rendered by the worker, which is equivalent to plain SSR for that path
|
|
48
|
+
|
|
49
|
+
## Per-page revalidation (Pages mode)
|
|
50
|
+
|
|
51
|
+
In [Pages mode](../pages-routing/overview), you can export a `revalidate` value from a `.server.ts` file to override the global config for that page:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
// pages/products/index.server.ts
|
|
55
|
+
export const revalidate = 120; // cache for 2 minutes
|
|
56
|
+
|
|
57
|
+
export const loader = defineHandler(async (c) => {
|
|
58
|
+
// ...
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Per-page values take precedence over `void.json` patterns.
|
|
63
|
+
|
|
64
|
+
## Precedence
|
|
65
|
+
|
|
66
|
+
When multiple sources set a revalidate TTL, the most specific wins:
|
|
67
|
+
|
|
68
|
+
1. `x-revalidate` response header (per-response)
|
|
69
|
+
2. `.server.ts` export (per-page, Pages mode only)
|
|
70
|
+
3. `void.json` `routing.revalidate` path pattern match
|
|
71
|
+
4. `void.json` `routing.revalidate` global number or `"*"` fallback
|
|
72
|
+
|
|
73
|
+
## How revalidation works
|
|
74
|
+
|
|
75
|
+
1. **First request:** there is no cache entry yet. The worker renders the page, returns the response, and writes the result to KV in the background.
|
|
76
|
+
|
|
77
|
+
2. **Subsequent requests (fresh):** the cached response is served from the edge cache or KV. No worker call is needed.
|
|
78
|
+
|
|
79
|
+
3. **Subsequent requests (stale):** the stale cached response is served immediately, and the worker re-renders in the background. The next request gets the fresh version.
|
|
80
|
+
|
|
81
|
+
This means users never wait for a stale page to re-render. They always get an immediate response.
|
|
82
|
+
|
|
83
|
+
## Per-response TTL override
|
|
84
|
+
|
|
85
|
+
Route handlers can set the `x-revalidate` response header to override the TTL for a specific response:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
export const GET = defineHandler(async (c) => {
|
|
89
|
+
// Don't cache this particular response
|
|
90
|
+
c.header('x-revalidate', '0');
|
|
91
|
+
|
|
92
|
+
return c.html('...');
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- `x-revalidate: 0`: skip caching for this response
|
|
97
|
+
- `x-revalidate: 300`: cache for 5 minutes instead of the default
|
|
98
|
+
|
|
99
|
+
Only successful responses (2xx) are cached.
|
|
100
|
+
|
|
101
|
+
## Cache bypass
|
|
102
|
+
|
|
103
|
+
Requests with `Cookie` or `Authorization` headers bypass the ISR cache entirely and always dispatch to the worker. This ensures personalized or authenticated pages are never served from a shared cache.
|
|
104
|
+
|
|
105
|
+
## Cache keys and rewrites
|
|
106
|
+
|
|
107
|
+
If a request is rewritten at dispatch (`routing.rewrites`, `routing.fallbacks`, or `_redirects` 200/200!), the ISR cache slot is keyed on the **rewritten** pathname **plus** the original request URL's pathname. Query parameters are dropped from rewrite variant keys by default; use `routing.revalidateQueryAllowlist` to keep selected query params when they should vary cached output. So a direct request to `/en/docs/foo` and a rewrite from `/docs/foo → /en/docs/foo` no longer share a slot — each renders and caches independently. Middleware `c.rewrite()` runs after ISR lookup, so it observes rewrite metadata but does not create a separate ISR variant.
|
|
108
|
+
|
|
109
|
+
`revalidate({ paths })` operates on the rewritten pathname (the slot's primary key). Purging `/en/docs/foo` removes **all variants** (direct + every rewrite source) under that path. Purging the source path (`/docs/foo`) invalidates nothing, because no slot was ever written under it.
|
|
110
|
+
|
|
111
|
+
**Migration note:** the ISR cache key format bumped to a versioned `v2` prefix alongside this feature, with no reader-side fallback to the previous unversioned format. The first time a project deploys on the new dispatch, **every** pre-existing ISR entry becomes unreachable — not only paths that gained a rewrite rule. Cache slots warm up normally under the new key as traffic comes in; you'll see a one-time cache-miss wave proportional to your traffic × TTL, then the hit rate returns to normal. No manual purge is required, and the stranded entries expire on their own via their original TTLs and deployment age-out. Additionally, if you introduce a rewrite on an existing path (e.g. `/docs/foo` → `/en/docs/foo`), the cache slot for that path moves to the rewritten pathname, so the source path's `v2` slot will cold-start too.
|
|
112
|
+
|
|
113
|
+
## On-demand revalidation
|
|
114
|
+
|
|
115
|
+
You can purge ISR cache entries programmatically from a route handler:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { revalidate } from 'void/isr';
|
|
119
|
+
|
|
120
|
+
export const POST = defineHandler(async (c) => {
|
|
121
|
+
// ... update content in database ...
|
|
122
|
+
|
|
123
|
+
// Purge specific pages
|
|
124
|
+
await revalidate({ paths: ['/', '/blog/hello-world'] });
|
|
125
|
+
|
|
126
|
+
// Or purge all cached pages
|
|
127
|
+
await revalidate({ all: true });
|
|
128
|
+
|
|
129
|
+
return c.json({ ok: true });
|
|
130
|
+
});
|
|
131
|
+
```
|