void 0.21.9 → 0.23.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.
Files changed (293) hide show
  1. package/README.md +5 -1
  2. package/dist/{account-cmd-DZZGK80W.mjs → account-cmd-C84Ee8cO.mjs} +5 -5
  3. package/dist/{scan-ClYmX3sa.mjs → application-analysis-BVsVqc11.mjs} +135 -18
  4. package/dist/application-routing-B7QEjqSR.mjs +27 -0
  5. package/dist/{auth-CZuiVsFh.mjs → auth-CCjt0hcq.mjs} +1 -1
  6. package/dist/{auth-DLNN0D3Z.mjs → auth-CSkdO2Bb.mjs} +4 -47
  7. package/dist/{auth-link-B_CeugBw.mjs → auth-link-CioEg6uY.mjs} +5 -5
  8. package/dist/{auth-router-BgEFRuvZ.mjs → auth-router-BsR981d4.mjs} +5 -5
  9. package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
  10. package/dist/{build-cmd-Dpt0jd-x.mjs → build-cmd-LzvNJORH.mjs} +19 -7
  11. package/dist/{cache-7_UeZdTk.mjs → cache-C4MvnrMH.mjs} +4 -4
  12. package/dist/{cancel-deploy-D23R1RXT.mjs → cancel-deploy-abUxpP2n.mjs} +4 -4
  13. package/dist/{cf-build-output-CGT03qCD.mjs → cf-build-output-BPqOT964.mjs} +141 -63
  14. package/dist/cf-build-output-_0HNWysu.mjs +2 -0
  15. package/dist/cli/cli.mjs +114 -460
  16. package/dist/cli/cloudflare-operation-process.mjs +1103 -0
  17. package/dist/cli/env-schema-probe.d.mts +2 -1
  18. package/dist/cli/env-schema-probe.mjs +3 -3
  19. package/dist/client-Cu7jWiF1.mjs +2 -0
  20. package/dist/{client-QTl6ko_D.mjs → client-RV8NVeB8.mjs} +165 -21
  21. package/dist/{cloudflare-auth-C4_GPZr0.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -43
  22. package/dist/{cloudflare-cmd-bSmZ1d5L.mjs → cloudflare-cmd-BcrVyTmJ.mjs} +9 -10
  23. package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
  24. package/dist/{cloudflare-connect-jAwacxxP.mjs → cloudflare-connect-B8uPZ4nx.mjs} +4 -4
  25. package/dist/{cloudflare-operations-BipGMJ5O.mjs → cloudflare-operations-AiWashgg.mjs} +1 -1
  26. package/dist/{cloudflare-operations-sMZXpk_S.mjs → cloudflare-operations-fxHb-byx.mjs} +118 -203
  27. package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
  28. package/dist/{config-CF69HgXc.d.mts → config-BMHb8RCj.d.mts} +2 -2
  29. package/dist/{config-CafTW6Cz.mjs → config-Br_JZD6u.mjs} +2 -7
  30. package/dist/config-C_XRIPx2.mjs +89 -0
  31. package/dist/{config-s7Xj7tPb.mjs → config-CyQ-wVd7.mjs} +1 -1
  32. package/dist/config-entry.d.mts +1 -1
  33. package/dist/{config-write-BSduPMY8.mjs → config-write-B1f88wJA.mjs} +1 -1
  34. package/dist/{connect-BsUSRzln.mjs → connect-Bd4kJd9U.mjs} +6 -6
  35. package/dist/{create-project-BniEV0OW.mjs → create-project-Boczwj5r.mjs} +1 -1
  36. package/dist/{create-project-DBfFSZKY.mjs → create-project-bMf6ffLZ.mjs} +9 -5
  37. package/dist/{db-hRrvZaq_.mjs → db-8uG64XLl.mjs} +26 -26
  38. package/dist/{delete-D6dZ9B6B.mjs → delete-NvbiyeJf.mjs} +4 -4
  39. package/dist/{deploy-WaAQez1O.mjs → deploy-DzAIwqNU.mjs} +944 -607
  40. package/dist/{deploy-DDz7c8LK.mjs → deploy-bjXdFCtn.mjs} +1 -1
  41. package/dist/{dist-BR1quN_w.mjs → dist-AoCzRTJE.mjs} +226 -60
  42. package/dist/{dist-C5fND3R0.mjs → dist-BuDuKZJv.mjs} +1 -1
  43. package/dist/{dist-Dn6nn2IU.mjs → dist-CTBk70IR.mjs} +42 -42
  44. package/dist/{domain-Dmhvb2oU.mjs → domain-y5Tvydvo.mjs} +5 -5
  45. package/dist/{email-DFi-s2t4.mjs → email-B3umsW75.mjs} +15 -30
  46. package/dist/{env-Csi-tMbT.mjs → env-BS6qYHDb.mjs} +6 -6
  47. package/dist/{env-public-D_6u46fX.d.mts → env-public-BX_r8HR6.d.mts} +2 -1
  48. package/dist/{env-validation-BB4GkLxn.mjs → env-validation-BPn7vk-V.mjs} +18 -71
  49. package/dist/{env-validation-BXge7uyK.mjs → env-validation-DbTg7-ar.mjs} +1 -1
  50. package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
  51. package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
  52. package/dist/{gen-Dz3X1Qab.mjs → gen-B580--vC.mjs} +5 -5
  53. package/dist/gen-BVaUUumi.mjs +2 -0
  54. package/dist/{github-cmd-BED3_9JD.mjs → github-cmd-v45BdfKX.mjs} +6 -8
  55. package/dist/{handler-BXJTXd02.d.mts → handler-CZ4nAylQ.d.mts} +2 -1
  56. package/dist/{headers-BOg_velo.mjs → headers-DWi2IXWx.mjs} +1 -1
  57. package/dist/help-DofyZuY7.mjs +2 -0
  58. package/dist/{help-DC7gdz7L.mjs → help-daGKjXGk.mjs} +268 -666
  59. package/dist/index.d.mts +1 -1
  60. package/dist/index.mjs +305 -1490
  61. package/dist/info-B97bTX9N.mjs +113 -0
  62. package/dist/{init-WO0JlPx8.mjs → init-Bvy7zrBo.mjs} +51 -20
  63. package/dist/limits-Bq5LG8Id.d.mts +27 -0
  64. package/dist/limits-Cjuk2VPm.mjs +68 -0
  65. package/dist/{link-CsHOinF7.mjs → link-CDqqCjFl.mjs} +5 -5
  66. package/dist/{list-CDb-4bZ1.mjs → list-CZj0dzKY.mjs} +5 -5
  67. package/dist/{live-CKiJilLr.d.mts → live-Chw1eIMv.d.mts} +1 -1
  68. package/dist/{local-d1-CC8sKFGu.mjs → local-d1-2CMnpuW_.mjs} +2 -2
  69. package/dist/login-DYt_An22.mjs +2 -0
  70. package/dist/{login-DvqXsfGs.mjs → login-UZKFM_u7.mjs} +5 -5
  71. package/dist/{logs-BdfiOezj.mjs → logs-CUZ6t9t3.mjs} +5 -5
  72. package/dist/migrate-8_2u55MD.mjs +2 -0
  73. package/dist/{migrate-B8KuoYsO.mjs → migrate-DHul7PRV.mjs} +5 -4
  74. package/dist/{node-BM43oz4G.mjs → node-BkyRWRx8.mjs} +2 -2
  75. package/dist/operator-args-CLgKGlwU.mjs +690 -0
  76. package/dist/{operator-cmd-03819ATr.mjs → operator-cmd-DBA6dl0m.mjs} +69 -23
  77. package/dist/output-Dm_A4Tbv.mjs +81 -0
  78. package/dist/pages/client.d.mts +34 -2
  79. package/dist/pages/client.mjs +59 -3
  80. package/dist/pages/index.d.mts +1 -1
  81. package/dist/pages/index.mjs +3 -3
  82. package/dist/pages/islands-plugin.d.mts +16 -6
  83. package/dist/pages/islands-plugin.mjs +2 -2
  84. package/dist/pages/protocol.d.mts +2 -2
  85. package/dist/pages/protocol.mjs +2 -308
  86. package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
  87. package/dist/{output-CCH48AMM.mjs → picocolors-BTps1_gs.mjs} +2 -76
  88. package/dist/plan-D1Q5rf-r.mjs +2 -0
  89. package/dist/plan-NPpwZ_kc.mjs +58 -0
  90. package/dist/platform-args-BJdRtlLq.mjs +506 -0
  91. package/dist/platform-args-D3RXyR6h.mjs +2 -0
  92. package/dist/{platform-auth-config-z92h63q5.mjs → platform-auth-config-B56E9YP1.mjs} +4 -4
  93. package/dist/{platform-auth-protection-DeE3yr2R.mjs → platform-auth-protection-BDWO_aER.mjs} +3 -3
  94. package/dist/{platform-auth-recovery-o_340Ixx.mjs → platform-auth-recovery-1gg4CSRe.mjs} +4 -4
  95. package/dist/{platform-cmd-C4ZV3Vpy.mjs → platform-cmd-Bt-1w6pY.mjs} +1 -1
  96. package/dist/{platform-cmd-DNl8WosH.mjs → platform-cmd-DMcQStSc.mjs} +26 -5
  97. package/dist/{platform-domain-CU1JtJkW.mjs → platform-domain-BNkcz0OB.mjs} +36 -9
  98. package/dist/{platform-lifecycle-Bc047IeT.mjs → platform-lifecycle-9OyBALhH.mjs} +850 -276
  99. package/dist/{platform-lifecycle-Bs2qx1E3.mjs → platform-lifecycle-BE6C_jxh.mjs} +1 -1
  100. package/dist/{platform-management-CVpGI9Y5.mjs → platform-management-CjwLVQwN.mjs} +59 -11
  101. package/dist/{platform-management-C8tt6D8h.mjs → platform-management-CnyTdcWX.mjs} +1 -1
  102. package/dist/platform-plans-config-BNGKGr4P.mjs +359 -0
  103. package/dist/{platform-recovery-dvUaptLr.mjs → platform-recovery-D6KSpuFm.mjs} +2 -2
  104. package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
  105. package/dist/{prepare-DyZ-Yok5.mjs → prepare-B5Mkic5u.mjs} +3 -3
  106. package/dist/{prepare-C3kt3Rst.mjs → prepare-DOsL0CC9.mjs} +4 -20
  107. package/dist/prepare-cgvDMtSb.mjs +2 -0
  108. package/dist/{project-cmd-B44I8J_W.mjs → project-cmd-CNzrqvBv.mjs} +30 -16
  109. package/dist/{project-team-BkbYIsXN.mjs → project-team-DQOWPfQT.mjs} +4 -4
  110. package/dist/{project-token-C8xEEQnB.mjs → project-token-CTDYU0Cc.mjs} +4 -4
  111. package/dist/project-zero-trust-BNAkW-_0.mjs +63 -0
  112. package/dist/{protocol-ZH3jP4a7.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
  113. package/dist/protocol-U7bfjHmA.mjs +331 -0
  114. package/dist/{provision-DNtrtaVD.mjs → provision-C4ORE7G7.mjs} +1 -1
  115. package/dist/{provision-BhreDAOS.mjs → provision-CJFgTZY8.mjs} +111 -215
  116. package/dist/{requests-DFyhBMaf.mjs → requests-MhxYnau8.mjs} +4 -4
  117. package/dist/resource-name-C7LVpcRm.mjs +11 -0
  118. package/dist/{rollback-DHHxXZiS.mjs → rollback-CJ6iSDoU.mjs} +5 -5
  119. package/dist/route-url-CG7U-cRN.mjs +15 -0
  120. package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
  121. package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
  122. package/dist/runtime/ai.d.mts +12 -8
  123. package/dist/runtime/ai.mjs +84 -17
  124. package/dist/runtime/better-auth-mysql.mjs +1 -1
  125. package/dist/runtime/better-auth-pg.mjs +1 -1
  126. package/dist/runtime/better-auth.mjs +1 -1
  127. package/dist/runtime/client-react.mjs +2 -2
  128. package/dist/runtime/client-solid.mjs +2 -2
  129. package/dist/runtime/client-svelte.mjs +2 -2
  130. package/dist/runtime/client-vue.mjs +2 -2
  131. package/dist/runtime/client.mjs +2 -2
  132. package/dist/runtime/durable.d.mts +3 -1
  133. package/dist/runtime/durable.mjs +4 -1
  134. package/dist/runtime/email/testing.mjs +1 -1
  135. package/dist/runtime/env-public.d.mts +1 -1
  136. package/dist/runtime/fetch-stream.mjs +1 -1
  137. package/dist/runtime/fetch.mjs +1 -1
  138. package/dist/runtime/handler.d.mts +1 -1
  139. package/dist/runtime/kv.mjs +0 -1
  140. package/dist/runtime/limits.d.mts +2 -0
  141. package/dist/runtime/limits.mjs +2 -0
  142. package/dist/runtime/live-client.d.mts +1 -1
  143. package/dist/runtime/live-server.mjs +25 -16
  144. package/dist/runtime/live.d.mts +1 -1
  145. package/dist/runtime/migration-handler.mjs +62 -42
  146. package/dist/runtime/route-url.d.mts +4 -0
  147. package/dist/runtime/route-url.mjs +2 -0
  148. package/dist/runtime/routing.d.mts +180 -0
  149. package/dist/runtime/routing.mjs +1082 -0
  150. package/dist/runtime/sandbox-container.d.mts +3 -0
  151. package/dist/runtime/sandbox-container.mjs +2 -0
  152. package/dist/runtime/sandbox.d.mts +4 -32
  153. package/dist/runtime/sandbox.mjs +151 -75
  154. package/dist/runtime/sse.mjs +1 -1
  155. package/dist/runtime/validator.d.mts +1 -1
  156. package/dist/runtime/ws-server.d.mts +4 -2
  157. package/dist/runtime/ws-server.mjs +27 -2
  158. package/dist/runtime/ws.d.mts +2 -2
  159. package/dist/runtime/ws.mjs +8 -6
  160. package/dist/sandbox-XZAqzFlG.d.mts +52 -0
  161. package/dist/sandbox-container-Bo0eiFKz.d.mts +73 -0
  162. package/dist/sandbox-container-C6ItmVuN.mjs +281 -0
  163. package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
  164. package/dist/{secret-DN9sSNiV.mjs → secret-Dli5fP0B.mjs} +6 -6
  165. package/dist/{skills-O6FUaizK.mjs → skills-D1II1Juz.mjs} +1 -1
  166. package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
  167. package/dist/{subcommand-prompt-BuGYkAkC.mjs → subcommand-prompt-CY1C4fvl.mjs} +2 -2
  168. package/dist/validate-Dq_L3s0S.mjs +2 -0
  169. package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
  170. package/dist/{wrangler-BymcxrRa.mjs → wrangler-7K-bW_DL.mjs} +14 -235
  171. package/dist/{ws-BwcqizuH.d.mts → ws-CL1w7GXU.d.mts} +13 -2
  172. package/package.json +48 -33
  173. package/sandbox.Dockerfile +4 -0
  174. package/schema.json +10 -22
  175. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
  176. package/skills/void/SKILL.md +50 -133
  177. package/skills/void/docs/guide/ai.md +94 -84
  178. package/skills/void/docs/guide/app-types.md +3 -32
  179. package/skills/void/docs/guide/auth.md +12 -116
  180. package/skills/void/docs/guide/database/d1.md +9 -54
  181. package/skills/void/docs/guide/database/mysql.md +1 -1
  182. package/skills/void/docs/guide/database/postgresql.md +5 -26
  183. package/skills/void/docs/guide/database.md +23 -75
  184. package/skills/void/docs/guide/deployment.md +27 -113
  185. package/skills/void/docs/guide/durable-state.md +43 -18
  186. package/skills/void/docs/guide/edge/headers.md +3 -47
  187. package/skills/void/docs/guide/edge/prerendering.md +5 -20
  188. package/skills/void/docs/guide/edge/redirects.md +11 -64
  189. package/skills/void/docs/guide/edge/revalidation.md +6 -19
  190. package/skills/void/docs/guide/edge/rewrites.md +56 -284
  191. package/skills/void/docs/guide/edge/static-assets.md +23 -72
  192. package/skills/void/docs/guide/email/domains.md +112 -0
  193. package/skills/void/docs/guide/email/receiving.md +139 -0
  194. package/skills/void/docs/guide/email/sending.md +231 -0
  195. package/skills/void/docs/guide/email.md +13 -619
  196. package/skills/void/docs/guide/env-migration.md +11 -11
  197. package/skills/void/docs/guide/env-vars.md +9 -29
  198. package/skills/void/docs/guide/index.md +0 -15
  199. package/skills/void/docs/guide/jobs.md +3 -18
  200. package/skills/void/docs/guide/kv.md +5 -11
  201. package/skills/void/docs/guide/live.md +5 -56
  202. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
  203. package/skills/void/docs/guide/pages-routing/head.md +10 -10
  204. package/skills/void/docs/guide/pages-routing/islands.md +6 -36
  205. package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
  206. package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
  207. package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
  208. package/skills/void/docs/guide/pages-routing/overview.md +7 -17
  209. package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
  210. package/skills/void/docs/guide/platform/administration/access.md +1 -4
  211. package/skills/void/docs/guide/platform/administration/email.md +35 -8
  212. package/skills/void/docs/guide/platform/administration/operations.md +26 -4
  213. package/skills/void/docs/guide/platform/administration/plans.md +126 -0
  214. package/skills/void/docs/guide/platform/administration/projects.md +5 -2
  215. package/skills/void/docs/guide/platform/administration/zero-trust.md +189 -0
  216. package/skills/void/docs/guide/platform/development/local.md +2 -2
  217. package/skills/void/docs/guide/platform/development/runtime.md +3 -13
  218. package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
  219. package/skills/void/docs/guide/platform/installation/credentials.md +6 -4
  220. package/skills/void/docs/guide/platform/installation/domains.md +31 -3
  221. package/skills/void/docs/guide/platform/installation/first-deployment.md +6 -0
  222. package/skills/void/docs/guide/platform/installation/maintenance.md +3 -1
  223. package/skills/void/docs/guide/platform/installation/prerequisites.md +21 -16
  224. package/skills/void/docs/guide/platform/installation/setup.md +9 -5
  225. package/skills/void/docs/guide/platform/installation/uninstall.md +17 -2
  226. package/skills/void/docs/guide/platform-administration.md +2 -0
  227. package/skills/void/docs/guide/queues.md +7 -9
  228. package/skills/void/docs/guide/quickstart.md +38 -37
  229. package/skills/void/docs/guide/remote-dev.md +4 -9
  230. package/skills/void/docs/guide/sandboxes.md +78 -41
  231. package/skills/void/docs/guide/server-routing.md +9 -72
  232. package/skills/void/docs/guide/sse.md +4 -18
  233. package/skills/void/docs/guide/ssg.md +3 -15
  234. package/skills/void/docs/guide/ssr.md +14 -62
  235. package/skills/void/docs/guide/storage.md +9 -4
  236. package/skills/void/docs/guide/type-safety.md +3 -14
  237. package/skills/void/docs/guide/typed-fetch.md +3 -7
  238. package/skills/void/docs/guide/websockets.md +68 -40
  239. package/skills/void/docs/integrations/agents.md +3 -3
  240. package/skills/void/docs/integrations/cloudflare.md +85 -316
  241. package/skills/void/docs/integrations/frameworks/analog.md +5 -64
  242. package/skills/void/docs/integrations/frameworks/astro.md +4 -73
  243. package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
  244. package/skills/void/docs/integrations/frameworks/overview.md +11 -54
  245. package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
  246. package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
  247. package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
  248. package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
  249. package/skills/void/docs/reference/api/auth.md +156 -0
  250. package/skills/void/docs/reference/api/client.md +87 -0
  251. package/skills/void/docs/reference/api/database.md +95 -0
  252. package/skills/void/docs/reference/api/durable.md +46 -0
  253. package/skills/void/docs/reference/api/env.md +50 -0
  254. package/skills/void/docs/reference/api/handlers.md +254 -0
  255. package/skills/void/docs/reference/api/pages.md +241 -0
  256. package/skills/void/docs/reference/api/plugin.md +39 -0
  257. package/skills/void/docs/reference/api/resources.md +109 -0
  258. package/skills/void/docs/reference/api/rewrites.md +76 -0
  259. package/skills/void/docs/reference/api/types.md +92 -0
  260. package/skills/void/docs/reference/api.md +56 -1218
  261. package/skills/void/docs/reference/cli/auth.md +88 -0
  262. package/skills/void/docs/reference/cli/database.md +128 -0
  263. package/skills/void/docs/reference/cli/deploy.md +85 -0
  264. package/skills/void/docs/reference/cli/domains.md +41 -0
  265. package/skills/void/docs/reference/cli/email.md +129 -0
  266. package/skills/void/docs/reference/cli/generate.md +116 -0
  267. package/skills/void/docs/reference/cli/github.md +189 -0
  268. package/skills/void/docs/reference/cli/platform-config.md +92 -0
  269. package/skills/void/docs/reference/cli/platform-email.md +81 -0
  270. package/skills/void/docs/reference/cli/platform-installation.md +127 -0
  271. package/skills/void/docs/reference/cli/platform-operations.md +90 -0
  272. package/skills/void/docs/reference/cli/platform-users.md +89 -0
  273. package/skills/void/docs/reference/cli/platform-zero-trust.md +45 -0
  274. package/skills/void/docs/reference/cli/platform.md +70 -0
  275. package/skills/void/docs/reference/cli/project.md +214 -0
  276. package/skills/void/docs/reference/cli/secrets.md +76 -0
  277. package/skills/void/docs/reference/cli/setup.md +70 -0
  278. package/skills/void/docs/reference/cli.md +33 -1621
  279. package/skills/void/docs/reference/config.md +26 -32
  280. package/skills/void/docs/reference/resource-inference.md +3 -58
  281. package/skills/void/docs/reference/structure.md +14 -41
  282. package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
  283. package/dist/cli/cf-compat.mjs +0 -968
  284. package/dist/client-4cDVv7BO.mjs +0 -2
  285. package/dist/gen-Vnv2f65C.mjs +0 -2
  286. package/dist/help-DQMfeKMz.mjs +0 -2
  287. package/dist/login-DFQk7rbW.mjs +0 -2
  288. package/dist/migrate-TsHGBnDA.mjs +0 -2
  289. package/dist/plan-BEZ8VJW0.mjs +0 -256
  290. package/dist/plan-DpuOr14e.mjs +0 -2
  291. package/dist/prepare-BZXkjdNe.mjs +0 -2
  292. package/dist/validate-EKmJWxmy.mjs +0 -2
  293. /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
@@ -34,10 +34,10 @@ export const action = defineHandler.withValidator({
34
34
  When a page needs multiple mutations, such as updating and deleting a user on the same page, export `actions` (plural) instead of `action`:
35
35
 
36
36
  ```ts
37
- // pages/users/edit.server.ts
37
+ // pages/users/[id].server.ts
38
38
  import { defineHandler } from 'void';
39
39
  import { db, eq } from 'void/db';
40
- import { users } from '@schema';
40
+ import { users, updateUserSchema } from '@schema';
41
41
 
42
42
  export const actions = {
43
43
  update: defineHandler.withValidator({
@@ -46,19 +46,18 @@ export const actions = {
46
46
  await db
47
47
  .update(users)
48
48
  .set(body)
49
- .where(eq(users.id, c.req.param('id')));
49
+ .where(eq(users.id, Number(c.req.param('id'))));
50
50
  }),
51
51
 
52
52
  delete: defineHandler(async (c) => {
53
- const { id } = await c.req.json<{ id: string }>();
54
- await db.delete(users).where(eq(users.id, id));
53
+ await db.delete(users).where(eq(users.id, Number(c.req.param('id'))));
55
54
  }),
56
55
  };
57
56
  ```
58
57
 
59
- Named actions are dispatched via a `?actionName` suffix on the URL (e.g. `/users/edit?update`). The client primitives `useForm` and `action()` handle this automatically.
58
+ Named actions are dispatched via a `?actionName` suffix on the URL (e.g. `/users/42?update`). The client primitives `useForm` and `action()` handle this automatically.
60
59
 
61
- `export const action` (singular) still works for pages that only need one mutation. Named actions are opt-in. Exporting both `action` and `actions` from the same file is an error.
60
+ Use `action` or `actions` in a file, not both.
62
61
 
63
62
  You can also define an `actions.default` key for the action that runs when no name is specified (i.e. a bare POST to the page URL):
64
63
 
@@ -73,39 +72,25 @@ export const actions = {
73
72
  };
74
73
  ```
75
74
 
76
- ## `useForm`
75
+ ## Form
77
76
 
78
- `useForm` handles form submissions, loading state, and validation errors. It is **fully typed end to end**. The URL autocompletes to pages that have an action, `form.data` matches the action validator schema, and `form.errors` keys are constrained to the body field names.
77
+ Pair `Form` with `useForm` for automatic error presentation. It preserves controlled input on failure, announces validation and action errors, and displays the message from structured quota responses. Known retry deadlines prevent premature resubmission without locking the fields. It never retries a submission automatically.
79
78
 
80
- First, define the action in your server handler:
79
+ Import `Form` from your adapter. Pass `form` and, optionally, `method="put"`, `"patch"`, or `"delete"`; the default is `"post"`. Use `renderError` for a custom action-error renderer (a snippet in Svelte).
81
80
 
82
- ```ts
83
- // pages/users/create.server.ts
84
- import { defineHandler } from 'void';
85
- import { db } from 'void/db';
86
- import { users } from '@schema';
87
- import * as v from 'valibot';
81
+ On the server, use `limit.response({ message: 'AI is temporarily unavailable. Your draft is still editable.' })` in an AI or Sandbox operation's required `limited` handler. It supplies the status and structured metadata consumed by `Form`.
88
82
 
89
- const createUserSchema = v.object({
90
- name: v.pipe(v.string(), v.minLength(1)),
91
- email: v.pipe(v.string(), v.email()),
92
- });
83
+ ## `useForm`
93
84
 
94
- export const action = defineHandler.withValidator({
95
- body: createUserSchema,
96
- })(async (c, { body }) => {
97
- await db.insert(users).values(body);
98
- return c.redirect('/users');
99
- });
100
- ```
85
+ `useForm` handles submissions, loading state, and validation errors. URLs, form values, and error fields are typed from your action.
101
86
 
102
- Then, use `useForm` in the page component to submit to this action:
87
+ Submit to the `/users` action defined above:
103
88
 
104
89
  ::: code-group
105
90
 
106
91
  ```tsx [React]
107
- // pages/users/create.tsx
108
- import { useForm } from '@void/react';
92
+ // pages/users/index.tsx
93
+ import { Form, useForm } from '@void/react';
109
94
  import { useFormStatus } from 'react-dom';
110
95
 
111
96
  function SubmitButton() {
@@ -114,11 +99,10 @@ function SubmitButton() {
114
99
  }
115
100
 
116
101
  export default function CreateUser() {
117
- // "/users/create" autocompletes; { name, email } is typed from the action's validator
118
- const form = useForm('/users/create', { name: '', email: '' });
102
+ const form = useForm('/users', { name: '', email: '' });
119
103
 
120
104
  return (
121
- <form action={form.post}>
105
+ <Form form={form}>
122
106
  <input
123
107
  name="name"
124
108
  value={form.data.name}
@@ -133,25 +117,22 @@ export default function CreateUser() {
133
117
  />
134
118
  {form.errors.email && <span>{form.errors.email}</span>}
135
119
 
136
- {form.error && <p>{form.error.message}</p>}
137
-
138
120
  <SubmitButton />
139
- </form>
121
+ </Form>
140
122
  );
141
123
  }
142
124
  ```
143
125
 
144
126
  ```vue [Vue]
145
- <!-- pages/users/create.vue -->
127
+ <!-- pages/users/index.vue -->
146
128
  <script setup lang="ts">
147
- import { useForm } from '@void/vue';
129
+ import { Form, useForm } from '@void/vue';
148
130
 
149
- // "/users/create" autocompletes; { name, email } is typed from the action's validator
150
- const form = useForm('/users/create', { name: '', email: '' });
131
+ const form = useForm('/users', { name: '', email: '' });
151
132
  </script>
152
133
 
153
134
  <template>
154
- <form @submit.prevent="form.post()">
135
+ <Form :form="form">
155
136
  <input v-model="form.data.name" />
156
137
  <span v-if="form.errors.name">{{ form.errors.name }}</span>
157
138
 
@@ -159,20 +140,19 @@ const form = useForm('/users/create', { name: '', email: '' });
159
140
  <span v-if="form.errors.email">{{ form.errors.email }}</span>
160
141
 
161
142
  <button :disabled="form.pending">Create</button>
162
- </form>
143
+ </Form>
163
144
  </template>
164
145
  ```
165
146
 
166
147
  ```svelte [Svelte]
167
- <!-- pages/users/create.svelte -->
148
+ <!-- pages/users/index.svelte -->
168
149
  <script>
169
- import { useForm } from "@void/svelte";
150
+ import { Form, useForm } from "@void/svelte";
170
151
 
171
- // "/users/create" autocompletes; { name, email } is typed from the action's validator
172
- const form = useForm("/users/create", { name: "", email: "" });
152
+ const form = useForm("/users", { name: "", email: "" });
173
153
  </script>
174
154
 
175
- <form onsubmit={(e) => { e.preventDefault(); return form.post(); }}>
155
+ <Form {form}>
176
156
  <input bind:value={form.data.name} />
177
157
  {#if form.errors.name}<span>{form.errors.name}</span>{/if}
178
158
 
@@ -180,24 +160,18 @@ const form = useForm('/users/create', { name: '', email: '' });
180
160
  {#if form.errors.email}<span>{form.errors.email}</span>{/if}
181
161
 
182
162
  <button disabled={form.pending}>Create</button>
183
- </form>
163
+ </Form>
184
164
  ```
185
165
 
186
166
  ```tsx [Solid]
187
- // pages/users/create.tsx
188
- import { useForm } from '@void/solid';
167
+ // pages/users/index.tsx
168
+ import { Form, useForm } from '@void/solid';
189
169
 
190
170
  export default function CreateUser() {
191
- // "/users/create" autocompletes; { name, email } is typed from the action's validator
192
- const form = useForm('/users/create', { name: '', email: '' });
171
+ const form = useForm('/users', { name: '', email: '' });
193
172
 
194
173
  return (
195
- <form
196
- onSubmit={(e) => {
197
- e.preventDefault();
198
- return form.post();
199
- }}
200
- >
174
+ <Form form={form}>
201
175
  <input value={form.data.name} onInput={(e) => form.setData('name', e.target.value)} />
202
176
  {form.errors.name && <span>{form.errors.name}</span>}
203
177
 
@@ -205,7 +179,7 @@ export default function CreateUser() {
205
179
  {form.errors.email && <span>{form.errors.email}</span>}
206
180
 
207
181
  <button disabled={form.pending}>Create</button>
208
- </form>
182
+ </Form>
209
183
  );
210
184
  }
211
185
  ```
@@ -218,40 +192,28 @@ The types are inferred from your action's `withValidator()` schema in the compan
218
192
 
219
193
  `useForm` returns a reactive object with:
220
194
 
221
- | Property / Method | Purpose |
222
- | -------------------------------- | --------------------------------------------------------------------------------------------- |
223
- | Property / Method | Purpose |
224
- | -------------------------------- | --------------------------------------------------------------------------------------------- |
225
- | `data` / `setData` | Current form values, typed to match the action's body schema. |
226
- | `errors` | Field-level validation errors, keys typed to body field names. |
227
- | `error` | Non-validation call-site action error, or `null`. |
228
- | `post`, `put`, `patch`, `delete` | Submit the form with that method. In React these are native form action callbacks. |
229
- | `pending` | `true` while the submission is in flight. |
230
- | `hasChanges` | `true` if form data differs from initial values. |
231
- | `wasSuccessful` | `true` after a successful submission. Stays `true` until the next submission. |
232
- | `recentlySuccessful` | `true` for 2 seconds after a successful submission. Useful for flash messages. |
233
- | `reset(...fields)` | Reset form data to initial values. Field names autocomplete. |
234
- | `clearErrors(...fields)` | Clear validation errors. Field names autocomplete. |
235
- | `clearError()` | Clear the non-validation call-site error. |
236
-
237
- In React, prefer the native Action form:
238
-
239
- ```tsx
240
- <form action={form.post}>{/* controlled inputs update form.data */}</form>
241
- ```
242
-
243
- Use `form.put`, `form.patch`, or `form.delete` as the form action for alternate HTTP methods. Use the `action()` helper when you need an awaitable imperative mutation.
244
-
245
- In Vue, Svelte, and Solid, the same helpers return `Promise<void>` so
246
- boundary-class failures can propagate through framework async error handling or
247
- explicit `catch` handlers.
195
+ | Property / Method | Purpose |
196
+ | -------------------------------- | ---------------------------------------------------------------------------------- |
197
+ | `data` / `setData` | Current form values, typed to match the action's body schema. |
198
+ | `errors` | Field-level validation errors, keys typed to body field names. |
199
+ | `error` | Action error, or `null`. |
200
+ | `post`, `put`, `patch`, `delete` | Submit the form with that method. In React these are native form action callbacks. |
201
+ | `pending` | `true` while the submission is in flight. |
202
+ | `hasChanges` | `true` if form data differs from initial values. |
203
+ | `wasSuccessful` | `true` after a successful submission. Stays `true` until the next submission. |
204
+ | `recentlySuccessful` | `true` for 2 seconds after a successful submission. Useful for flash messages. |
205
+ | `reset(...fields)` | Reset form data to initial values. Field names autocomplete. |
206
+ | `clearErrors(...fields)` | Clear validation errors. Field names autocomplete. |
207
+ | `clearError()` | Clear `error`. |
208
+
209
+ For a native React form, use `form.post`, `form.put`, `form.patch`, or `form.delete` as a native form action. For an awaitable mutation, use `action()`. In Vue, Svelte, and Solid, form submissions return `Promise<void>`; catch thrown errors or use your framework's error handling.
248
210
 
249
211
  For dynamic routes, pass `params` in the options:
250
212
 
251
213
  ```ts
252
214
  // pages/users/[id].server.ts has an action
253
215
  const form = useForm('/users/:id', { name: '' }, { params: { id: '42' } });
254
- <form action={form.put}>{/* submits to /users/42 */}</form>
216
+ <Form form={form} method="put">{/* submits to /users/42 */}</Form>
255
217
  ```
256
218
 
257
219
  ### Named Actions with `useForm`
@@ -260,24 +222,20 @@ When a page exports named actions, append `?actionName` to the URL:
260
222
 
261
223
  ```ts
262
224
  const form = useForm('/users/:id?update', { name: '' }, { params: { id } });
263
- <form action={form.put}>{/* submits to /users/42?update */}</form>
225
+ <Form form={form} method="put">{/* submits to /users/42?update */}</Form>
264
226
  ```
265
227
 
266
228
  Each named action has its own validator schema, which supplies types for its URL, body, and error keys. See [Type Safety](../type-safety#action-%E2%86%92-useform) for an example.
267
229
 
268
230
  ## `action()` Helper
269
231
 
270
- For one-shot mutations that do not need form state such as dirty tracking, reset, or field-level errors, use `action()` instead of `useForm`. It sends a request to a page action and triggers an Inertia page update, just like `useForm`, but without the reactive form object:
232
+ Use `action()` for a button or other mutation that does not need form state. It updates the page after a successful request:
271
233
 
272
234
  ```ts
273
- import { useForm, action } from '@void/react'; // or "@void/vue", "@void/svelte", "@void/solid"
274
-
275
- // Form with state + Inertia page update
276
- const form = useForm('/?create-user', { name: '', email: '' });
235
+ import { action } from '@void/react'; // or "@void/vue", "@void/svelte", "@void/solid"
277
236
 
278
- // Programmatic call + Inertia page update (no form state)
279
- const result = await action('/?delete-user', {
280
- data: { id: 42 },
237
+ const result = await action('/users/:id?delete', {
238
+ params: { id: '42' },
281
239
  method: 'DELETE',
282
240
  });
283
241
  if (!result.ok) {
@@ -285,17 +243,17 @@ if (!result.ok) {
285
243
  }
286
244
  ```
287
245
 
288
- Call `action()` from a button or another event handler when you don't need form state. It defaults to `POST`; pass `{ data, method, params }` to set the body, route parameters, or a `PUT`, `PATCH`, or `DELETE` method.
246
+ `action()` defaults to `POST`. Pass `data`, `params`, and `method` to set the body, route parameters, or HTTP method.
289
247
 
290
248
  A successful call returns `{ ok: true, pageData }`. Expected errors, such as validation failures or conflicts, return `{ ok: false, error }`.
291
249
 
292
250
  ## Validation Errors
293
251
 
294
- When an action throws a `ValidationError`, or validation fails through `withValidator`, the errors are automatically available on `form.errors`. You do not need to wire that up manually.
252
+ `withValidator()` and `ValidationError` populate `form.errors` automatically.
295
253
 
296
254
  Expected errors such as `400`, `404`, `409`, `422`, and `429` stay with the form or action call. `useForm` stores them in `form.errors` or `form.error`; `action()` returns `{ ok: false, error }`.
297
255
 
298
- Authentication errors (`401`, `403`), server errors (`500`, `502`), and unknown network or protocol failures are thrown. Handle them with your framework's error boundary or error handling.
256
+ Authentication errors (`401`, `403`), server errors (`500`, `502`), and unexpected failures are thrown. Handle them with your framework's error boundary or error handling.
299
257
 
300
258
  Actions can throw `ValidationError` for custom validation logic:
301
259
 
@@ -311,26 +269,28 @@ export const action = defineHandler(async (c) => {
311
269
  });
312
270
  ```
313
271
 
314
- Or use `withValidator()` for automatic schema-based validation. Errors are returned in the same format.
272
+ ## Authentication and origin checks
273
+
274
+ Browser submissions must come from the same origin as the page, including its scheme, hostname, and port. Void rejects cross-origin page actions with `403 Forbidden`. Server clients can call actions without browser origin headers; actions still need authentication and authorization for protected data.
315
275
 
316
276
  ## File Uploads
317
277
 
318
- `useForm` automatically detects `File`, `Blob`, and `FileList` values in form data and sends the request as `multipart/form-data` instead of JSON. No extra configuration is needed. Set a file on the form data and submit.
278
+ Set a `File`, `Blob`, or `FileList` in form data and submit. `useForm` sends it as `multipart/form-data`:
319
279
 
320
280
  ::: code-group
321
281
 
322
282
  ```tsx [React]
323
- import { useForm } from '@void/react';
283
+ import { Form, useForm } from '@void/react';
324
284
 
325
285
  export default function Upload() {
326
286
  const form = useForm('/photos', { title: '', photo: null as File | null });
327
287
 
328
288
  return (
329
- <form action={form.post}>
289
+ <Form form={form}>
330
290
  <input value={form.data.title} onChange={(e) => form.setData('title', e.target.value)} />
331
291
  <input type="file" onChange={(e) => form.setData('photo', e.target.files?.[0] ?? null)} />
332
292
  <button disabled={form.pending}>Upload</button>
333
- </form>
293
+ </Form>
334
294
  );
335
295
  }
336
296
  ```
@@ -338,7 +298,7 @@ export default function Upload() {
338
298
  ```vue [Vue]
339
299
  <script setup lang="ts">
340
300
  import { ref } from 'vue';
341
- import { useForm } from '@void/vue';
301
+ import { Form, useForm } from '@void/vue';
342
302
 
343
303
  const form = useForm('/photos', { title: '', photo: null as File | null });
344
304
  const fileInput = ref<HTMLInputElement>();
@@ -349,45 +309,40 @@ function onFileChange() {
349
309
  </script>
350
310
 
351
311
  <template>
352
- <form @submit.prevent="form.post()">
312
+ <Form :form="form">
353
313
  <input v-model="form.data.title" />
354
314
  <input type="file" ref="fileInput" @change="onFileChange" />
355
315
  <button :disabled="form.pending">Upload</button>
356
- </form>
316
+ </Form>
357
317
  </template>
358
318
  ```
359
319
 
360
320
  ```svelte [Svelte]
361
321
  <script>
362
- import { useForm } from "@void/svelte";
322
+ import { Form, useForm } from "@void/svelte";
363
323
 
364
324
  const form = useForm("/photos", { title: "", photo: null });
365
325
  </script>
366
326
 
367
- <form onsubmit={(e) => { e.preventDefault(); return form.post(); }}>
327
+ <Form {form}>
368
328
  <input bind:value={form.data.title} />
369
329
  <input type="file" onchange={(e) => { form.data.photo = e.target.files?.[0] ?? null; }} />
370
330
  <button disabled={form.pending}>Upload</button>
371
- </form>
331
+ </Form>
372
332
  ```
373
333
 
374
334
  ```tsx [Solid]
375
- import { useForm } from '@void/solid';
335
+ import { Form, useForm } from '@void/solid';
376
336
 
377
337
  export default function Upload() {
378
338
  const form = useForm('/photos', { title: '', photo: null as File | null });
379
339
 
380
340
  return (
381
- <form
382
- onSubmit={(e) => {
383
- e.preventDefault();
384
- return form.post();
385
- }}
386
- >
341
+ <Form form={form}>
387
342
  <input value={form.data.title} onInput={(e) => form.setData('title', e.target.value)} />
388
343
  <input type="file" onChange={(e) => form.setData('photo', e.target.files?.[0] ?? null)} />
389
344
  <button disabled={form.pending}>Upload</button>
390
- </form>
345
+ </Form>
391
346
  );
392
347
  }
393
348
  ```
@@ -414,10 +369,8 @@ export const action = defineHandler(async (c) => {
414
369
 
415
370
  ## Choosing a Primitive
416
371
 
417
- | Primitive | Inertia page update | Form state | Framework-specific |
418
- | ---------- | ------------------- | -------------------------- | ------------------ |
419
- | `useForm` | Yes | Yes (errors, dirty, reset) | Yes |
420
- | `action()` | Yes | No | Yes |
421
- | `fetch()` | No (raw response) | No | No |
422
-
423
- Use `useForm` when you have a form with inputs. Use `action()` for programmatic mutations (delete buttons, toggles), optionally passing `{ method }` for non-POST actions. Use `fetch()` when you need the raw response and don't want Inertia page updates.
372
+ | Primitive | Page update | Form state | Framework-specific |
373
+ | ---------------- | ----------- | -------------------------- | ------------------ |
374
+ | `useForm` | Yes | Yes (errors, dirty, reset) | Yes |
375
+ | `action()` | Yes | No | Yes |
376
+ | Native `fetch()` | No | No | No |
@@ -4,9 +4,9 @@ outline: deep
4
4
 
5
5
  # Head Management
6
6
 
7
- Pages mode manages `<head>` tags (title, meta, links, scripts, HTML/body attributes) across three layers with clear precedence: **page > middleware > config**.
7
+ Set page titles and metadata with `head()`, middleware, or site-wide defaults. Page values take precedence over middleware and config.
8
8
 
9
- ## Page `head()` Export
9
+ ## Page titles and metadata
10
10
 
11
11
  Export a `head()` function from your `.server.ts` file. It receives the Hono context and the resolved loader props, and returns a `HeadDescriptor`:
12
12
 
@@ -37,7 +37,7 @@ export const head = defineHead<Props>((c, props) => {
37
37
 
38
38
  `head()` runs server-side only, after the loader resolves.
39
39
 
40
- ## Config Defaults
40
+ ## Site defaults
41
41
 
42
42
  Set site-wide head defaults in `void.config.ts`:
43
43
 
@@ -56,9 +56,9 @@ Set site-wide head defaults in `void.config.ts`:
56
56
 
57
57
  `titleTemplate` wraps the page title. `%s` is replaced with whatever `head()` returns as `title`. A page returning `{ title: "About" }` with the template above produces `<title>About | My Site</title>`.
58
58
 
59
- ## Middleware Defaults
59
+ ## Middleware defaults
60
60
 
61
- Middleware can inject head defaults that apply to every page. This is useful for things like a theme script that must run before first paint:
61
+ Set `headDefaults` in middleware to apply defaults to every page. For example, a theme script can run before first paint:
62
62
 
63
63
  ```ts
64
64
  // middleware/01.head.ts
@@ -77,7 +77,7 @@ export default defineMiddleware(async (c, next) => {
77
77
  });
78
78
  ```
79
79
 
80
- ## Merge Precedence
80
+ ## Precedence
81
81
 
82
82
  When multiple layers provide head data, they merge with this precedence:
83
83
 
@@ -90,7 +90,7 @@ When multiple layers provide head data, they merge with this precedence:
90
90
  | `htmlAttrs` | Shallow merge, page wins conflicts. |
91
91
  | `bodyAttrs` | Shallow merge, page wins conflicts. |
92
92
 
93
- ## HeadDescriptor Shape
93
+ ## HeadDescriptor
94
94
 
95
95
  ```ts
96
96
  interface HeadDescriptor {
@@ -108,7 +108,7 @@ interface HeadDescriptor {
108
108
  }
109
109
  ```
110
110
 
111
- ## Markdown Auto-Head
111
+ ## Markdown pages
112
112
 
113
113
  Markdown pages (`.md` files) automatically generate head tags from frontmatter. You do not need a `.server.ts` file:
114
114
 
@@ -123,8 +123,8 @@ Your content here...
123
123
 
124
124
  This produces `<title>Getting Started</title>` and `<meta name="description" content="Learn how to use Void">`, with `titleTemplate` applied if configured.
125
125
 
126
- ## Client-Side Updates
126
+ ## Client-side updates
127
127
 
128
- On SPA navigation, head tags update automatically. The framework tracks managed tags with a `data-void-head` attribute and preserves matching tags across navigations, so unchanged stylesheet and preload links are not torn down and re-added. Tags that are no longer present are removed, and new tags are inserted.
128
+ Titles, meta tags, and links update automatically on client-side navigation.
129
129
 
130
130
  `script`, `htmlAttrs`, and `bodyAttrs` are SSR-only. They are not re-applied on client-side navigation.
@@ -55,13 +55,7 @@ Islands mode builds on top of [Pages Routing](./overview). You need a working Pa
55
55
 
56
56
  ## When to Use Islands
57
57
 
58
- Islands mode is a good fit when:
59
-
60
- - **Most of your page is static content:** blog posts, marketing pages, or documentation
61
- - **Only a few components need interactivity:** a counter, a form, or a live widget
62
- - **Performance is critical:** you want near-zero JavaScript for static content
63
-
64
- If your entire page is interactive (dashboards, apps with lots of client state), stick with regular [Pages Routing](./overview).
58
+ Use islands for blogs, marketing pages, or documentation with a few interactive components. For dashboards and apps with shared client state, use regular [Pages Routing](./overview).
65
59
 
66
60
  ## Creating an Island Page
67
61
 
@@ -69,12 +63,9 @@ Name your page file with the `.island` suffix:
69
63
 
70
64
  <FileTree :items="islandItems" adapter-tabs default-expanded />
71
65
 
72
- The `.island` suffix tells Void to:
66
+ Island pages render as HTML and hydrate only the components you mark as islands. Navigation uses full page loads.
73
67
 
74
- 1. **Server-render the full page** as static HTML (no `data-page` attribute, no Void Router)
75
- 2. **Only hydrate** the components you explicitly mark as islands
76
- 3. **Skip the Inertia protocol:** navigation between island pages uses full page loads
77
- 4. **Auto-prerender:** island pages with no `loader` and no dynamic params are automatically [prerendered](/guide/edge/prerendering) at deploy time. Opt out with `export const prerender = false` in the companion `.server.ts` file.
68
+ Pages without a loader or dynamic parameters are automatically [prerendered](/guide/edge/prerendering). Opt out with `export const prerender = false` in the companion `.server.ts` file.
78
69
 
79
70
  ## Marking Components as Islands
80
71
 
@@ -353,30 +344,9 @@ export default function PostForm() {
353
344
 
354
345
  :::
355
346
 
356
- `useIslandForm` returns the same shape as `useForm`:
357
-
358
- | Property | Type | Description |
359
- | ------------------------- | ------------------------- | ------------------------------------------ |
360
- | `data` | `T` | Reactive form state |
361
- | `setData(field, value)` | Function | Update a field |
362
- | `errors` | `Record<string, string>` | Validation errors from 422 responses |
363
- | `error` | `VoidActionError \| null` | Non-validation call-site action error |
364
- | `pending` | `boolean` | Submission in progress |
365
- | `hasChanges` | `boolean` | Form has unsaved changes |
366
- | `wasSuccessful` | `boolean` | Last submission succeeded |
367
- | `recentlySuccessful` | `boolean` | Success within last 2 seconds |
368
- | `reset(...fields?)` | Function | Reset to defaults (all or specific fields) |
369
- | `clearErrors(...fields?)` | Function | Clear errors (all or specific fields) |
370
- | `clearError()` | Function | Clear the non-validation call-site error |
371
- | `post(url)` | Function | Submit via POST |
372
- | `put(url)` | Function | Submit via PUT |
373
- | `patch(url)` | Function | Submit via PATCH |
374
- | `delete(url)` | Function | Submit via DELETE |
375
-
376
- The submit helpers return `Promise<void>` so callers and framework event
377
- handlers can observe boundary-class failures. On success (200), the page reloads.
378
- On validation error (422), `errors` is populated from the response
379
- `{ errors: { field: "message" } }`. On redirect, the browser follows it.
347
+ `useIslandForm` provides the same state and methods as [`useForm`](./actions-and-forms#useform). Use `post`, `put`, `patch`, or `delete` with the action URL to submit.
348
+
349
+ Successful submissions reload the page; redirects navigate to their destination. A `422` response populates `errors` from `{ errors: { field: "message" } }`. Submit helpers return `Promise<void>`.
380
350
 
381
351
  ## Navigation
382
352