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.
- package/README.md +5 -1
- package/dist/{account-cmd-DZZGK80W.mjs → account-cmd-C84Ee8cO.mjs} +5 -5
- package/dist/{scan-ClYmX3sa.mjs → application-analysis-BVsVqc11.mjs} +135 -18
- package/dist/application-routing-B7QEjqSR.mjs +27 -0
- package/dist/{auth-CZuiVsFh.mjs → auth-CCjt0hcq.mjs} +1 -1
- package/dist/{auth-DLNN0D3Z.mjs → auth-CSkdO2Bb.mjs} +4 -47
- package/dist/{auth-link-B_CeugBw.mjs → auth-link-CioEg6uY.mjs} +5 -5
- package/dist/{auth-router-BgEFRuvZ.mjs → auth-router-BsR981d4.mjs} +5 -5
- package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
- package/dist/{build-cmd-Dpt0jd-x.mjs → build-cmd-LzvNJORH.mjs} +19 -7
- package/dist/{cache-7_UeZdTk.mjs → cache-C4MvnrMH.mjs} +4 -4
- package/dist/{cancel-deploy-D23R1RXT.mjs → cancel-deploy-abUxpP2n.mjs} +4 -4
- package/dist/{cf-build-output-CGT03qCD.mjs → cf-build-output-BPqOT964.mjs} +141 -63
- package/dist/cf-build-output-_0HNWysu.mjs +2 -0
- package/dist/cli/cli.mjs +114 -460
- package/dist/cli/cloudflare-operation-process.mjs +1103 -0
- package/dist/cli/env-schema-probe.d.mts +2 -1
- package/dist/cli/env-schema-probe.mjs +3 -3
- package/dist/client-Cu7jWiF1.mjs +2 -0
- package/dist/{client-QTl6ko_D.mjs → client-RV8NVeB8.mjs} +165 -21
- package/dist/{cloudflare-auth-C4_GPZr0.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -43
- package/dist/{cloudflare-cmd-bSmZ1d5L.mjs → cloudflare-cmd-BcrVyTmJ.mjs} +9 -10
- package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
- package/dist/{cloudflare-connect-jAwacxxP.mjs → cloudflare-connect-B8uPZ4nx.mjs} +4 -4
- package/dist/{cloudflare-operations-BipGMJ5O.mjs → cloudflare-operations-AiWashgg.mjs} +1 -1
- package/dist/{cloudflare-operations-sMZXpk_S.mjs → cloudflare-operations-fxHb-byx.mjs} +118 -203
- package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
- package/dist/{config-CF69HgXc.d.mts → config-BMHb8RCj.d.mts} +2 -2
- package/dist/{config-CafTW6Cz.mjs → config-Br_JZD6u.mjs} +2 -7
- package/dist/config-C_XRIPx2.mjs +89 -0
- package/dist/{config-s7Xj7tPb.mjs → config-CyQ-wVd7.mjs} +1 -1
- package/dist/config-entry.d.mts +1 -1
- package/dist/{config-write-BSduPMY8.mjs → config-write-B1f88wJA.mjs} +1 -1
- package/dist/{connect-BsUSRzln.mjs → connect-Bd4kJd9U.mjs} +6 -6
- package/dist/{create-project-BniEV0OW.mjs → create-project-Boczwj5r.mjs} +1 -1
- package/dist/{create-project-DBfFSZKY.mjs → create-project-bMf6ffLZ.mjs} +9 -5
- package/dist/{db-hRrvZaq_.mjs → db-8uG64XLl.mjs} +26 -26
- package/dist/{delete-D6dZ9B6B.mjs → delete-NvbiyeJf.mjs} +4 -4
- package/dist/{deploy-WaAQez1O.mjs → deploy-DzAIwqNU.mjs} +944 -607
- package/dist/{deploy-DDz7c8LK.mjs → deploy-bjXdFCtn.mjs} +1 -1
- package/dist/{dist-BR1quN_w.mjs → dist-AoCzRTJE.mjs} +226 -60
- package/dist/{dist-C5fND3R0.mjs → dist-BuDuKZJv.mjs} +1 -1
- package/dist/{dist-Dn6nn2IU.mjs → dist-CTBk70IR.mjs} +42 -42
- package/dist/{domain-Dmhvb2oU.mjs → domain-y5Tvydvo.mjs} +5 -5
- package/dist/{email-DFi-s2t4.mjs → email-B3umsW75.mjs} +15 -30
- package/dist/{env-Csi-tMbT.mjs → env-BS6qYHDb.mjs} +6 -6
- package/dist/{env-public-D_6u46fX.d.mts → env-public-BX_r8HR6.d.mts} +2 -1
- package/dist/{env-validation-BB4GkLxn.mjs → env-validation-BPn7vk-V.mjs} +18 -71
- package/dist/{env-validation-BXge7uyK.mjs → env-validation-DbTg7-ar.mjs} +1 -1
- package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
- package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
- package/dist/{gen-Dz3X1Qab.mjs → gen-B580--vC.mjs} +5 -5
- package/dist/gen-BVaUUumi.mjs +2 -0
- package/dist/{github-cmd-BED3_9JD.mjs → github-cmd-v45BdfKX.mjs} +6 -8
- package/dist/{handler-BXJTXd02.d.mts → handler-CZ4nAylQ.d.mts} +2 -1
- package/dist/{headers-BOg_velo.mjs → headers-DWi2IXWx.mjs} +1 -1
- package/dist/help-DofyZuY7.mjs +2 -0
- package/dist/{help-DC7gdz7L.mjs → help-daGKjXGk.mjs} +268 -666
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +305 -1490
- package/dist/info-B97bTX9N.mjs +113 -0
- package/dist/{init-WO0JlPx8.mjs → init-Bvy7zrBo.mjs} +51 -20
- package/dist/limits-Bq5LG8Id.d.mts +27 -0
- package/dist/limits-Cjuk2VPm.mjs +68 -0
- package/dist/{link-CsHOinF7.mjs → link-CDqqCjFl.mjs} +5 -5
- package/dist/{list-CDb-4bZ1.mjs → list-CZj0dzKY.mjs} +5 -5
- package/dist/{live-CKiJilLr.d.mts → live-Chw1eIMv.d.mts} +1 -1
- package/dist/{local-d1-CC8sKFGu.mjs → local-d1-2CMnpuW_.mjs} +2 -2
- package/dist/login-DYt_An22.mjs +2 -0
- package/dist/{login-DvqXsfGs.mjs → login-UZKFM_u7.mjs} +5 -5
- package/dist/{logs-BdfiOezj.mjs → logs-CUZ6t9t3.mjs} +5 -5
- package/dist/migrate-8_2u55MD.mjs +2 -0
- package/dist/{migrate-B8KuoYsO.mjs → migrate-DHul7PRV.mjs} +5 -4
- package/dist/{node-BM43oz4G.mjs → node-BkyRWRx8.mjs} +2 -2
- package/dist/operator-args-CLgKGlwU.mjs +690 -0
- package/dist/{operator-cmd-03819ATr.mjs → operator-cmd-DBA6dl0m.mjs} +69 -23
- package/dist/output-Dm_A4Tbv.mjs +81 -0
- package/dist/pages/client.d.mts +34 -2
- package/dist/pages/client.mjs +59 -3
- package/dist/pages/index.d.mts +1 -1
- package/dist/pages/index.mjs +3 -3
- package/dist/pages/islands-plugin.d.mts +16 -6
- package/dist/pages/islands-plugin.mjs +2 -2
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +2 -308
- package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
- package/dist/{output-CCH48AMM.mjs → picocolors-BTps1_gs.mjs} +2 -76
- package/dist/plan-D1Q5rf-r.mjs +2 -0
- package/dist/plan-NPpwZ_kc.mjs +58 -0
- package/dist/platform-args-BJdRtlLq.mjs +506 -0
- package/dist/platform-args-D3RXyR6h.mjs +2 -0
- package/dist/{platform-auth-config-z92h63q5.mjs → platform-auth-config-B56E9YP1.mjs} +4 -4
- package/dist/{platform-auth-protection-DeE3yr2R.mjs → platform-auth-protection-BDWO_aER.mjs} +3 -3
- package/dist/{platform-auth-recovery-o_340Ixx.mjs → platform-auth-recovery-1gg4CSRe.mjs} +4 -4
- package/dist/{platform-cmd-C4ZV3Vpy.mjs → platform-cmd-Bt-1w6pY.mjs} +1 -1
- package/dist/{platform-cmd-DNl8WosH.mjs → platform-cmd-DMcQStSc.mjs} +26 -5
- package/dist/{platform-domain-CU1JtJkW.mjs → platform-domain-BNkcz0OB.mjs} +36 -9
- package/dist/{platform-lifecycle-Bc047IeT.mjs → platform-lifecycle-9OyBALhH.mjs} +850 -276
- package/dist/{platform-lifecycle-Bs2qx1E3.mjs → platform-lifecycle-BE6C_jxh.mjs} +1 -1
- package/dist/{platform-management-CVpGI9Y5.mjs → platform-management-CjwLVQwN.mjs} +59 -11
- package/dist/{platform-management-C8tt6D8h.mjs → platform-management-CnyTdcWX.mjs} +1 -1
- package/dist/platform-plans-config-BNGKGr4P.mjs +359 -0
- package/dist/{platform-recovery-dvUaptLr.mjs → platform-recovery-D6KSpuFm.mjs} +2 -2
- package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
- package/dist/{prepare-DyZ-Yok5.mjs → prepare-B5Mkic5u.mjs} +3 -3
- package/dist/{prepare-C3kt3Rst.mjs → prepare-DOsL0CC9.mjs} +4 -20
- package/dist/prepare-cgvDMtSb.mjs +2 -0
- package/dist/{project-cmd-B44I8J_W.mjs → project-cmd-CNzrqvBv.mjs} +30 -16
- package/dist/{project-team-BkbYIsXN.mjs → project-team-DQOWPfQT.mjs} +4 -4
- package/dist/{project-token-C8xEEQnB.mjs → project-token-CTDYU0Cc.mjs} +4 -4
- package/dist/project-zero-trust-BNAkW-_0.mjs +63 -0
- package/dist/{protocol-ZH3jP4a7.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
- package/dist/protocol-U7bfjHmA.mjs +331 -0
- package/dist/{provision-DNtrtaVD.mjs → provision-C4ORE7G7.mjs} +1 -1
- package/dist/{provision-BhreDAOS.mjs → provision-CJFgTZY8.mjs} +111 -215
- package/dist/{requests-DFyhBMaf.mjs → requests-MhxYnau8.mjs} +4 -4
- package/dist/resource-name-C7LVpcRm.mjs +11 -0
- package/dist/{rollback-DHHxXZiS.mjs → rollback-CJ6iSDoU.mjs} +5 -5
- package/dist/route-url-CG7U-cRN.mjs +15 -0
- package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
- package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
- package/dist/runtime/ai.d.mts +12 -8
- package/dist/runtime/ai.mjs +84 -17
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.mjs +1 -1
- package/dist/runtime/client-react.mjs +2 -2
- package/dist/runtime/client-solid.mjs +2 -2
- package/dist/runtime/client-svelte.mjs +2 -2
- package/dist/runtime/client-vue.mjs +2 -2
- package/dist/runtime/client.mjs +2 -2
- package/dist/runtime/durable.d.mts +3 -1
- package/dist/runtime/durable.mjs +4 -1
- package/dist/runtime/email/testing.mjs +1 -1
- package/dist/runtime/env-public.d.mts +1 -1
- package/dist/runtime/fetch-stream.mjs +1 -1
- package/dist/runtime/fetch.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/kv.mjs +0 -1
- package/dist/runtime/limits.d.mts +2 -0
- package/dist/runtime/limits.mjs +2 -0
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live-server.mjs +25 -16
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/migration-handler.mjs +62 -42
- package/dist/runtime/route-url.d.mts +4 -0
- package/dist/runtime/route-url.mjs +2 -0
- package/dist/runtime/routing.d.mts +180 -0
- package/dist/runtime/routing.mjs +1082 -0
- package/dist/runtime/sandbox-container.d.mts +3 -0
- package/dist/runtime/sandbox-container.mjs +2 -0
- package/dist/runtime/sandbox.d.mts +4 -32
- package/dist/runtime/sandbox.mjs +151 -75
- package/dist/runtime/sse.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +4 -2
- package/dist/runtime/ws-server.mjs +27 -2
- package/dist/runtime/ws.d.mts +2 -2
- package/dist/runtime/ws.mjs +8 -6
- package/dist/sandbox-XZAqzFlG.d.mts +52 -0
- package/dist/sandbox-container-Bo0eiFKz.d.mts +73 -0
- package/dist/sandbox-container-C6ItmVuN.mjs +281 -0
- package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
- package/dist/{secret-DN9sSNiV.mjs → secret-Dli5fP0B.mjs} +6 -6
- package/dist/{skills-O6FUaizK.mjs → skills-D1II1Juz.mjs} +1 -1
- package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
- package/dist/{subcommand-prompt-BuGYkAkC.mjs → subcommand-prompt-CY1C4fvl.mjs} +2 -2
- package/dist/validate-Dq_L3s0S.mjs +2 -0
- package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
- package/dist/{wrangler-BymcxrRa.mjs → wrangler-7K-bW_DL.mjs} +14 -235
- package/dist/{ws-BwcqizuH.d.mts → ws-CL1w7GXU.d.mts} +13 -2
- package/package.json +48 -33
- package/sandbox.Dockerfile +4 -0
- package/schema.json +10 -22
- package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
- package/skills/void/SKILL.md +50 -133
- package/skills/void/docs/guide/ai.md +94 -84
- package/skills/void/docs/guide/app-types.md +3 -32
- package/skills/void/docs/guide/auth.md +12 -116
- package/skills/void/docs/guide/database/d1.md +9 -54
- package/skills/void/docs/guide/database/mysql.md +1 -1
- package/skills/void/docs/guide/database/postgresql.md +5 -26
- package/skills/void/docs/guide/database.md +23 -75
- package/skills/void/docs/guide/deployment.md +27 -113
- package/skills/void/docs/guide/durable-state.md +43 -18
- package/skills/void/docs/guide/edge/headers.md +3 -47
- package/skills/void/docs/guide/edge/prerendering.md +5 -20
- package/skills/void/docs/guide/edge/redirects.md +11 -64
- package/skills/void/docs/guide/edge/revalidation.md +6 -19
- package/skills/void/docs/guide/edge/rewrites.md +56 -284
- package/skills/void/docs/guide/edge/static-assets.md +23 -72
- package/skills/void/docs/guide/email/domains.md +112 -0
- package/skills/void/docs/guide/email/receiving.md +139 -0
- package/skills/void/docs/guide/email/sending.md +231 -0
- package/skills/void/docs/guide/email.md +13 -619
- package/skills/void/docs/guide/env-migration.md +11 -11
- package/skills/void/docs/guide/env-vars.md +9 -29
- package/skills/void/docs/guide/index.md +0 -15
- package/skills/void/docs/guide/jobs.md +3 -18
- package/skills/void/docs/guide/kv.md +5 -11
- package/skills/void/docs/guide/live.md +5 -56
- package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
- package/skills/void/docs/guide/pages-routing/head.md +10 -10
- package/skills/void/docs/guide/pages-routing/islands.md +6 -36
- package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
- package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
- package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
- package/skills/void/docs/guide/pages-routing/overview.md +7 -17
- package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
- package/skills/void/docs/guide/platform/administration/access.md +1 -4
- package/skills/void/docs/guide/platform/administration/email.md +35 -8
- package/skills/void/docs/guide/platform/administration/operations.md +26 -4
- package/skills/void/docs/guide/platform/administration/plans.md +126 -0
- package/skills/void/docs/guide/platform/administration/projects.md +5 -2
- package/skills/void/docs/guide/platform/administration/zero-trust.md +189 -0
- package/skills/void/docs/guide/platform/development/local.md +2 -2
- package/skills/void/docs/guide/platform/development/runtime.md +3 -13
- package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
- package/skills/void/docs/guide/platform/installation/credentials.md +6 -4
- package/skills/void/docs/guide/platform/installation/domains.md +31 -3
- package/skills/void/docs/guide/platform/installation/first-deployment.md +6 -0
- package/skills/void/docs/guide/platform/installation/maintenance.md +3 -1
- package/skills/void/docs/guide/platform/installation/prerequisites.md +21 -16
- package/skills/void/docs/guide/platform/installation/setup.md +9 -5
- package/skills/void/docs/guide/platform/installation/uninstall.md +17 -2
- package/skills/void/docs/guide/platform-administration.md +2 -0
- package/skills/void/docs/guide/queues.md +7 -9
- package/skills/void/docs/guide/quickstart.md +38 -37
- package/skills/void/docs/guide/remote-dev.md +4 -9
- package/skills/void/docs/guide/sandboxes.md +78 -41
- package/skills/void/docs/guide/server-routing.md +9 -72
- package/skills/void/docs/guide/sse.md +4 -18
- package/skills/void/docs/guide/ssg.md +3 -15
- package/skills/void/docs/guide/ssr.md +14 -62
- package/skills/void/docs/guide/storage.md +9 -4
- package/skills/void/docs/guide/type-safety.md +3 -14
- package/skills/void/docs/guide/typed-fetch.md +3 -7
- package/skills/void/docs/guide/websockets.md +68 -40
- package/skills/void/docs/integrations/agents.md +3 -3
- package/skills/void/docs/integrations/cloudflare.md +85 -316
- package/skills/void/docs/integrations/frameworks/analog.md +5 -64
- package/skills/void/docs/integrations/frameworks/astro.md +4 -73
- package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
- package/skills/void/docs/integrations/frameworks/overview.md +11 -54
- package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
- package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
- package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
- package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
- package/skills/void/docs/reference/api/auth.md +156 -0
- package/skills/void/docs/reference/api/client.md +87 -0
- package/skills/void/docs/reference/api/database.md +95 -0
- package/skills/void/docs/reference/api/durable.md +46 -0
- package/skills/void/docs/reference/api/env.md +50 -0
- package/skills/void/docs/reference/api/handlers.md +254 -0
- package/skills/void/docs/reference/api/pages.md +241 -0
- package/skills/void/docs/reference/api/plugin.md +39 -0
- package/skills/void/docs/reference/api/resources.md +109 -0
- package/skills/void/docs/reference/api/rewrites.md +76 -0
- package/skills/void/docs/reference/api/types.md +92 -0
- package/skills/void/docs/reference/api.md +56 -1218
- package/skills/void/docs/reference/cli/auth.md +88 -0
- package/skills/void/docs/reference/cli/database.md +128 -0
- package/skills/void/docs/reference/cli/deploy.md +85 -0
- package/skills/void/docs/reference/cli/domains.md +41 -0
- package/skills/void/docs/reference/cli/email.md +129 -0
- package/skills/void/docs/reference/cli/generate.md +116 -0
- package/skills/void/docs/reference/cli/github.md +189 -0
- package/skills/void/docs/reference/cli/platform-config.md +92 -0
- package/skills/void/docs/reference/cli/platform-email.md +81 -0
- package/skills/void/docs/reference/cli/platform-installation.md +127 -0
- package/skills/void/docs/reference/cli/platform-operations.md +90 -0
- package/skills/void/docs/reference/cli/platform-users.md +89 -0
- package/skills/void/docs/reference/cli/platform-zero-trust.md +45 -0
- package/skills/void/docs/reference/cli/platform.md +70 -0
- package/skills/void/docs/reference/cli/project.md +214 -0
- package/skills/void/docs/reference/cli/secrets.md +76 -0
- package/skills/void/docs/reference/cli/setup.md +70 -0
- package/skills/void/docs/reference/cli.md +33 -1621
- package/skills/void/docs/reference/config.md +26 -32
- package/skills/void/docs/reference/resource-inference.md +3 -58
- package/skills/void/docs/reference/structure.md +14 -41
- package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
- package/dist/cli/cf-compat.mjs +0 -968
- package/dist/client-4cDVv7BO.mjs +0 -2
- package/dist/gen-Vnv2f65C.mjs +0 -2
- package/dist/help-DQMfeKMz.mjs +0 -2
- package/dist/login-DFQk7rbW.mjs +0 -2
- package/dist/migrate-TsHGBnDA.mjs +0 -2
- package/dist/plan-BEZ8VJW0.mjs +0 -256
- package/dist/plan-DpuOr14e.mjs +0 -2
- package/dist/prepare-BZXkjdNe.mjs +0 -2
- package/dist/validate-EKmJWxmy.mjs +0 -2
- /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/
|
|
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
|
-
|
|
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/
|
|
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
|
-
|
|
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
|
-
##
|
|
75
|
+
## Form
|
|
77
76
|
|
|
78
|
-
`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
90
|
-
name: v.pipe(v.string(), v.minLength(1)),
|
|
91
|
-
email: v.pipe(v.string(), v.email()),
|
|
92
|
-
});
|
|
83
|
+
## `useForm`
|
|
93
84
|
|
|
94
|
-
|
|
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
|
-
|
|
87
|
+
Submit to the `/users` action defined above:
|
|
103
88
|
|
|
104
89
|
::: code-group
|
|
105
90
|
|
|
106
91
|
```tsx [React]
|
|
107
|
-
// pages/users/
|
|
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
|
-
|
|
118
|
-
const form = useForm('/users/create', { name: '', email: '' });
|
|
102
|
+
const form = useForm('/users', { name: '', email: '' });
|
|
119
103
|
|
|
120
104
|
return (
|
|
121
|
-
<form
|
|
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
|
-
</
|
|
121
|
+
</Form>
|
|
140
122
|
);
|
|
141
123
|
}
|
|
142
124
|
```
|
|
143
125
|
|
|
144
126
|
```vue [Vue]
|
|
145
|
-
<!-- pages/users/
|
|
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
|
-
|
|
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
|
|
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
|
-
</
|
|
143
|
+
</Form>
|
|
163
144
|
</template>
|
|
164
145
|
```
|
|
165
146
|
|
|
166
147
|
```svelte [Svelte]
|
|
167
|
-
<!-- pages/users/
|
|
148
|
+
<!-- pages/users/index.svelte -->
|
|
168
149
|
<script>
|
|
169
|
-
import { useForm } from "@void/svelte";
|
|
150
|
+
import { Form, useForm } from "@void/svelte";
|
|
170
151
|
|
|
171
|
-
|
|
172
|
-
const form = useForm("/users/create", { name: "", email: "" });
|
|
152
|
+
const form = useForm("/users", { name: "", email: "" });
|
|
173
153
|
</script>
|
|
174
154
|
|
|
175
|
-
<
|
|
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
|
-
</
|
|
163
|
+
</Form>
|
|
184
164
|
```
|
|
185
165
|
|
|
186
166
|
```tsx [Solid]
|
|
187
|
-
// pages/users/
|
|
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
|
-
|
|
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
|
-
</
|
|
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
|
-
|
|
|
224
|
-
|
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
|
|
235
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
279
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
</
|
|
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
|
|
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
|
-
</
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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
|
-
</
|
|
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
|
|
418
|
-
|
|
|
419
|
-
| `useForm`
|
|
420
|
-
| `action()`
|
|
421
|
-
| `fetch()`
|
|
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
|
-
|
|
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
|
|
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
|
-
##
|
|
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
|
|
59
|
+
## Middleware defaults
|
|
60
60
|
|
|
61
|
-
|
|
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
|
-
##
|
|
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
|
|
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
|
|
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-
|
|
126
|
+
## Client-side updates
|
|
127
127
|
|
|
128
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
+
Island pages render as HTML and hydrate only the components you mark as islands. Navigation uses full page loads.
|
|
73
67
|
|
|
74
|
-
|
|
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`
|
|
357
|
-
|
|
358
|
-
|
|
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
|
|