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
|
@@ -50,38 +50,15 @@ function namedLayoutItems(ext) {
|
|
|
50
50
|
]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function blogLayoutItems(ext) {
|
|
54
|
-
return [
|
|
55
|
-
{
|
|
56
|
-
name: "pages/",
|
|
57
|
-
children: [
|
|
58
|
-
{
|
|
59
|
-
name: "_layouts/",
|
|
60
|
-
children: [
|
|
61
|
-
{ name: `post${ext}`, description: "sidebar, date, author" },
|
|
62
|
-
],
|
|
63
|
-
},
|
|
64
|
-
{ name: `layout${ext}`, description: "nav + footer" },
|
|
65
|
-
{
|
|
66
|
-
name: "blog/",
|
|
67
|
-
children: [
|
|
68
|
-
{ name: `layout${ext}`, description: "blog sidebar" },
|
|
69
|
-
{ name: "hello.md", description: "layout: post → chain: [root, _layouts/post]" },
|
|
70
|
-
{ name: `archive${ext}`, description: "(no layout) → chain: [root, blog/layout]" },
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
|
|
78
53
|
</script>
|
|
79
54
|
|
|
80
55
|
# Layouts & Shared Data
|
|
81
56
|
|
|
57
|
+
Use layouts for navigation, headers, and other UI shared by several pages. Layouts nest with your directories and keep their component state as you navigate.
|
|
58
|
+
|
|
82
59
|
## Layouts
|
|
83
60
|
|
|
84
|
-
Place a layout file in
|
|
61
|
+
Place a layout file in a `pages/` directory to wrap its pages:
|
|
85
62
|
|
|
86
63
|
<FileTree :items="layoutBasicItems" adapter-tabs default-expanded />
|
|
87
64
|
|
|
@@ -169,8 +146,6 @@ When a page renders, the layout wraps it. The page component is injected as the
|
|
|
169
146
|
|
|
170
147
|
<img src="./layout-nesting.svg" alt="Layout nesting diagram: pages/layout wraps pages/users/layout wraps pages/users/[id] page component" style="max-width: 520px; width: 100%;" />
|
|
171
148
|
|
|
172
|
-
Layouts nest automatically and persist across navigations within their subtree, so component state is preserved.
|
|
173
|
-
|
|
174
149
|
## Named Layouts
|
|
175
150
|
|
|
176
151
|
Named layouts let individual pages opt into a different layout without changing the URL structure. Define them in `_layouts/` directories within `pages/`:
|
|
@@ -237,68 +212,9 @@ layout: post
|
|
|
237
212
|
| `"!landing"` | Replace the **entire** chain. Only the named layout wraps the page. |
|
|
238
213
|
| `false` | No layout wrapping at all. Page renders standalone. |
|
|
239
214
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
### Resolution order
|
|
243
|
-
|
|
244
|
-
When a page specifies `layout: "post"`, the scanner walks up the directory tree to find `_layouts/post`:
|
|
245
|
-
|
|
246
|
-
```
|
|
247
|
-
pages/guide/intro.md (layout: post)
|
|
248
|
-
|
|
249
|
-
1. pages/guide/_layouts/post.vue → not found
|
|
250
|
-
2. pages/_layouts/post.vue → found ✓
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
Closest ancestor wins, same as default layout chain. If no matching named layout is found in any ancestor, the build fails with a clear error.
|
|
254
|
-
|
|
255
|
-
### Examples
|
|
256
|
-
|
|
257
|
-
**Blog with shared nav but post-specific layout:**
|
|
258
|
-
|
|
259
|
-
<FileTree :items="blogLayoutItems" adapter-tabs default-expanded />
|
|
260
|
-
|
|
261
|
-
`layout: post` on `blog/hello.md` replaces the innermost default layout (`blog/layout`) with `_layouts/post`. The root layout still wraps.
|
|
262
|
-
|
|
263
|
-
**Fullscreen page with no layout:**
|
|
264
|
-
|
|
265
|
-
::: code-group
|
|
266
|
-
|
|
267
|
-
```tsx [React]
|
|
268
|
-
export const layout = false;
|
|
269
|
-
|
|
270
|
-
export default function Landing() {
|
|
271
|
-
return (
|
|
272
|
-
<div className="hero fullscreen">
|
|
273
|
-
<h1>Welcome</h1>
|
|
274
|
-
</div>
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
```vue [Vue]
|
|
280
|
-
<script>
|
|
281
|
-
export const layout = false;
|
|
282
|
-
</script>
|
|
283
|
-
|
|
284
|
-
<template>
|
|
285
|
-
<div class="hero fullscreen"><h1>Welcome</h1></div>
|
|
286
|
-
</template>
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
:::
|
|
290
|
-
|
|
291
|
-
**Exclusive layout (skip all ancestors):**
|
|
292
|
-
|
|
293
|
-
```md
|
|
294
|
-
---
|
|
295
|
-
layout: '!landing'
|
|
296
|
-
---
|
|
215
|
+
A named layout replaces the deepest default layout: in `[root, docs/layout]`, it replaces `docs/layout`; in `[root]`, it replaces the root.
|
|
297
216
|
|
|
298
|
-
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
Only `_layouts/landing` wraps this page, and the root layout is skipped entirely.
|
|
217
|
+
Void uses the closest matching `_layouts/` file in the page's directory or an ancestor. A missing named layout fails the build.
|
|
302
218
|
|
|
303
219
|
## Shared Data
|
|
304
220
|
|
|
@@ -322,42 +238,4 @@ export default defineMiddleware(async (c, next) => {
|
|
|
322
238
|
});
|
|
323
239
|
```
|
|
324
240
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
::: code-group
|
|
328
|
-
|
|
329
|
-
```tsx [React]
|
|
330
|
-
import { useShared } from '@void/react';
|
|
331
|
-
|
|
332
|
-
export default function Page() {
|
|
333
|
-
const { auth } = useShared(); // { auth: { user: AuthUser | null } }
|
|
334
|
-
return <p>Hello, {auth?.user?.name}</p>;
|
|
335
|
-
}
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
```vue [Vue]
|
|
339
|
-
<script setup lang="ts">
|
|
340
|
-
import { useShared } from '@void/vue';
|
|
341
|
-
const { auth } = useShared(); // { auth: { user: AuthUser | null } }
|
|
342
|
-
</script>
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
```svelte [Svelte]
|
|
346
|
-
<script>
|
|
347
|
-
import { useShared } from "@void/svelte";
|
|
348
|
-
const { auth } = useShared(); // { auth: { user: AuthUser | null } }
|
|
349
|
-
</script>
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
```tsx [Solid]
|
|
353
|
-
import { useShared } from '@void/solid';
|
|
354
|
-
|
|
355
|
-
export default function Page() {
|
|
356
|
-
const shared = useShared(); // { auth: { user: AuthUser | null } }
|
|
357
|
-
return <p>Hello, {shared.auth?.user?.name}</p>;
|
|
358
|
-
}
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
:::
|
|
362
|
-
|
|
363
|
-
Shared data is separate from page props. Props come from the loader, while `useShared()` returns global data from middleware. See [Type Safety](../type-safety.md#context-variables) for more on augmenting `CloudContextVariables`.
|
|
241
|
+
Call `useShared()` from your framework adapter, as in the layout examples above. Its return type is inferred from `CloudContextVariables`. Shared data comes from middleware; page props come from the loader. See [Context variables](../type-safety.md#context-variables).
|
|
@@ -24,17 +24,7 @@ export const loader = defineHandler(async (c) => {
|
|
|
24
24
|
});
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
`InferProps`
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
export interface Props {
|
|
31
|
-
users: Array<{ id: number; name: string; email: string }>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const loader = defineHandler<Props>(async (c) => {
|
|
35
|
-
return { users: await db.select().from(users) };
|
|
36
|
-
});
|
|
37
|
-
```
|
|
27
|
+
`InferProps` infers the loader’s return type, so page props stay in sync with the data it returns.
|
|
38
28
|
|
|
39
29
|
## Using the Data in Page Components
|
|
40
30
|
|
|
@@ -109,7 +99,7 @@ export default function UsersPage(props: Props) {
|
|
|
109
99
|
|
|
110
100
|
## Deferred Props
|
|
111
101
|
|
|
112
|
-
|
|
102
|
+
Use `defer()` for slow data. The page renders immediately and receives the result when it is ready:
|
|
113
103
|
|
|
114
104
|
```ts
|
|
115
105
|
// pages/dashboard.server.ts
|
|
@@ -235,16 +225,10 @@ export default function Dashboard(props: Props) {
|
|
|
235
225
|
|
|
236
226
|
:::
|
|
237
227
|
|
|
238
|
-
### How Streaming Works
|
|
239
|
-
|
|
240
|
-
On the first request, React renders the nearest Suspense fallback for deferred props; the other adapters render their loading state. As data becomes available, the server sends it in inline scripts on the same response.
|
|
241
|
-
|
|
242
|
-
A route with `ssr = false` still receives those scripts, even though its component mounts in the browser. During client-side navigation, deferred data arrives as newline-delimited JSON on the navigation response.
|
|
243
|
-
|
|
244
228
|
### Deferred Props After Mutations
|
|
245
229
|
|
|
246
230
|
::: info
|
|
247
|
-
|
|
231
|
+
After an action, deferred props keep their last resolved values until the next page load or client-side navigation. Other loader props refresh immediately.
|
|
248
232
|
:::
|
|
249
233
|
|
|
250
234
|
### Grouped Deferred Props
|
|
@@ -33,9 +33,7 @@ function mdFileItems(ext) {
|
|
|
33
33
|
|
|
34
34
|
# Markdown
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
The `@void/md` package is opt-in as it contains markdown processing and syntax highlighting dependencies that are not necessarily needed in every app.
|
|
36
|
+
Add `.md` files to `pages/` for Markdown routes. Pages inherit layouts and render as HTML, with JavaScript only for [islands](./islands), client scripts, and code-copy buttons.
|
|
39
37
|
|
|
40
38
|
## Setup
|
|
41
39
|
|
|
@@ -115,8 +113,6 @@ export default defineConfig({
|
|
|
115
113
|
|
|
116
114
|
:::
|
|
117
115
|
|
|
118
|
-
That's it. Any `.md` file in `pages/` is now a routable page.
|
|
119
|
-
|
|
120
116
|
## Page Anatomy
|
|
121
117
|
|
|
122
118
|
A markdown page has three optional parts: a script block, frontmatter, and the body.
|
|
@@ -146,7 +142,7 @@ Welcome to Void. Here's an interactive demo:
|
|
|
146
142
|
|
|
147
143
|
## Client Scripts
|
|
148
144
|
|
|
149
|
-
|
|
145
|
+
Use the `<script>` block for island imports and JavaScript that runs when the page loads:
|
|
150
146
|
|
|
151
147
|
```md
|
|
152
148
|
<script>
|
|
@@ -163,14 +159,7 @@ document.querySelector('.date').textContent = format(new Date(), 'PPP')
|
|
|
163
159
|
Published: <span class="date"></span>
|
|
164
160
|
```
|
|
165
161
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
- `Counter` is an island, so it is SSR'd and hydrated on the client
|
|
169
|
-
- `date-fns` and the `querySelector` call are client code, so they are bundled and run on page load
|
|
170
|
-
|
|
171
|
-
Each page's client script is code-split into its own chunk via dynamic import, so only the current page's script is loaded. Pages without client code ship zero extra JS.
|
|
172
|
-
|
|
173
|
-
Client scripts work in both dev (served on-demand, HMR support) and production builds.
|
|
162
|
+
Only the current page's client script loads. Pages without client code need no additional script.
|
|
174
163
|
|
|
175
164
|
## File Structure
|
|
176
165
|
|
|
@@ -329,7 +318,7 @@ Users who want full control can skip the import and write their own CSS.
|
|
|
329
318
|
|
|
330
319
|
## Markdown Features
|
|
331
320
|
|
|
332
|
-
|
|
321
|
+
Markdown features render as static HTML. Code-copy buttons add a small client script.
|
|
333
322
|
|
|
334
323
|
### Containers
|
|
335
324
|
|
|
@@ -378,7 +367,7 @@ Custom titles work too: `::: tip Pro Tip`.
|
|
|
378
367
|
|
|
379
368
|
### Syntax Highlighting
|
|
380
369
|
|
|
381
|
-
Code blocks
|
|
370
|
+
Code blocks use [Shiki](https://shiki.style) with `github-light` and `github-dark` themes by default.
|
|
382
371
|
|
|
383
372
|
### Line Highlighting
|
|
384
373
|
|
|
@@ -408,9 +397,7 @@ export function hello() {
|
|
|
408
397
|
}
|
|
409
398
|
```
|
|
410
399
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
Code blocks include a copy button. That is the only feature here that needs client-side JS, and it only adds a roughly 200 byte inline script for the clipboard API. The script is injected only when code blocks are present.
|
|
400
|
+
Code blocks include a copy button.
|
|
414
401
|
|
|
415
402
|
### Line Numbers
|
|
416
403
|
|
|
@@ -459,21 +446,9 @@ Add classes, IDs, or attributes to any element:
|
|
|
459
446
|
Paragraph with attributes. {.note}
|
|
460
447
|
```
|
|
461
448
|
|
|
462
|
-
###
|
|
463
|
-
|
|
464
|
-
All headings get permalink anchors automatically, enabling direct linking to any section.
|
|
465
|
-
|
|
466
|
-
### Table of Contents
|
|
449
|
+
### Navigation and Media
|
|
467
450
|
|
|
468
|
-
Use
|
|
469
|
-
|
|
470
|
-
### Images
|
|
471
|
-
|
|
472
|
-
Image paths are normalized automatically. Images are lazy-loaded by default.
|
|
473
|
-
|
|
474
|
-
### Links
|
|
475
|
-
|
|
476
|
-
External links automatically get `target="_blank" rel="noreferrer"`. Internal `.md` references resolve to their route paths.
|
|
451
|
+
Headings include permalink anchors. Use `[[toc]]` for a table of contents. Images are lazy-loaded, and `.md` links resolve to page routes.
|
|
477
452
|
|
|
478
453
|
## Plugin Options
|
|
479
454
|
|
|
@@ -491,147 +466,14 @@ voidMarkdown({
|
|
|
491
466
|
| `shiki.themes` | `{ light: string; dark: string}` | `{ light: "github-light", dark: "github-dark" }` | Shiki color themes |
|
|
492
467
|
| `shiki.langs` | `string[]` | Common web languages | Additional languages to load |
|
|
493
468
|
|
|
494
|
-
##
|
|
495
|
-
|
|
496
|
-
Here's a full example of a docs layout using `useFrontmatter()` and `@void/md/pages` to build a sidebar:
|
|
497
|
-
|
|
498
|
-
::: code-group
|
|
499
|
-
|
|
500
|
-
```tsx [React]
|
|
501
|
-
// pages/docs/layout.island.tsx
|
|
502
|
-
import '@void/md/theme-content.css';
|
|
503
|
-
import { useFrontmatter } from '@void/md';
|
|
504
|
-
import pages from '@void/md/pages';
|
|
505
|
-
import { useRouter } from '@void/react';
|
|
506
|
-
|
|
507
|
-
const docPages = pages.filter((p) => p.path.startsWith('/docs/'));
|
|
469
|
+
## Building a Sidebar
|
|
508
470
|
|
|
509
|
-
|
|
510
|
-
const fm = useFrontmatter();
|
|
511
|
-
const { path } = useRouter();
|
|
512
|
-
|
|
513
|
-
return (
|
|
514
|
-
<div className="docs-layout">
|
|
515
|
-
<aside>
|
|
516
|
-
<nav>
|
|
517
|
-
{docPages.map((page) => (
|
|
518
|
-
<a key={page.path} href={page.path} className={page.path === path ? 'active' : ''}>
|
|
519
|
-
{page.title}
|
|
520
|
-
</a>
|
|
521
|
-
))}
|
|
522
|
-
</nav>
|
|
523
|
-
</aside>
|
|
524
|
-
<main className="void-md">
|
|
525
|
-
<h1>{fm.title}</h1>
|
|
526
|
-
{children}
|
|
527
|
-
</main>
|
|
528
|
-
</div>
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
```
|
|
471
|
+
Use `@void/md/pages` to select the pages for your sidebar:
|
|
532
472
|
|
|
533
|
-
```
|
|
534
|
-
<!-- pages/docs/layout.island.vue -->
|
|
535
|
-
<script setup>
|
|
536
|
-
import { useFrontmatter } from '@void/md';
|
|
537
|
-
import pages from '@void/md/pages';
|
|
538
|
-
import { useRouter } from '@void/vue';
|
|
539
|
-
|
|
540
|
-
const fm = useFrontmatter();
|
|
541
|
-
const { path } = useRouter();
|
|
542
|
-
const docPages = pages.filter((p) => p.path.startsWith('/docs/'));
|
|
543
|
-
</script>
|
|
544
|
-
|
|
545
|
-
<style>
|
|
546
|
-
@import '@void/md/theme-content.css';
|
|
547
|
-
</style>
|
|
548
|
-
|
|
549
|
-
<template>
|
|
550
|
-
<div class="docs-layout">
|
|
551
|
-
<aside>
|
|
552
|
-
<nav>
|
|
553
|
-
<a
|
|
554
|
-
v-for="page in docPages"
|
|
555
|
-
:key="page.path"
|
|
556
|
-
:href="page.path"
|
|
557
|
-
:class="{ active: page.path === path }"
|
|
558
|
-
>
|
|
559
|
-
{{ page.title }}
|
|
560
|
-
</a>
|
|
561
|
-
</nav>
|
|
562
|
-
</aside>
|
|
563
|
-
<main class="void-md">
|
|
564
|
-
<h1>{{ fm.title }}</h1>
|
|
565
|
-
<slot />
|
|
566
|
-
</main>
|
|
567
|
-
</div>
|
|
568
|
-
</template>
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
```svelte [Svelte]
|
|
572
|
-
<!-- pages/docs/layout.island.svelte -->
|
|
573
|
-
<script>
|
|
574
|
-
import "@void/md/theme-content.css";
|
|
575
|
-
import { useFrontmatter } from "@void/md";
|
|
576
|
-
import pages from "@void/md/pages";
|
|
577
|
-
import { useRouter } from "@void/svelte";
|
|
578
|
-
|
|
579
|
-
const fm = useFrontmatter();
|
|
580
|
-
const { path } = useRouter();
|
|
581
|
-
const docPages = pages.filter((p) => p.path.startsWith("/docs/"));
|
|
582
|
-
</script>
|
|
583
|
-
|
|
584
|
-
<div class="docs-layout">
|
|
585
|
-
<aside>
|
|
586
|
-
<nav>
|
|
587
|
-
{#each docPages as page}
|
|
588
|
-
<a href={page.path} class:active={page.path === path}>
|
|
589
|
-
{page.title}
|
|
590
|
-
</a>
|
|
591
|
-
{/each}
|
|
592
|
-
</nav>
|
|
593
|
-
</aside>
|
|
594
|
-
<main class="void-md">
|
|
595
|
-
<h1>{fm.title}</h1>
|
|
596
|
-
<slot />
|
|
597
|
-
</main>
|
|
598
|
-
</div>
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
```tsx [Solid]
|
|
602
|
-
// pages/docs/layout.island.tsx
|
|
603
|
-
import '@void/md/theme-content.css';
|
|
604
|
-
import { useFrontmatter } from '@void/md';
|
|
473
|
+
```ts
|
|
605
474
|
import pages from '@void/md/pages';
|
|
606
|
-
import { useRouter } from '@void/solid';
|
|
607
|
-
import { For } from 'solid-js';
|
|
608
475
|
|
|
609
|
-
const docPages = pages.filter((
|
|
610
|
-
|
|
611
|
-
export default function DocsLayout(props) {
|
|
612
|
-
const fm = useFrontmatter();
|
|
613
|
-
const { path } = useRouter();
|
|
614
|
-
|
|
615
|
-
return (
|
|
616
|
-
<div class="docs-layout">
|
|
617
|
-
<aside>
|
|
618
|
-
<nav>
|
|
619
|
-
<For each={docPages}>
|
|
620
|
-
{(page) => (
|
|
621
|
-
<a href={page.path} classList={{ active: page.path === path() }}>
|
|
622
|
-
{page.title}
|
|
623
|
-
</a>
|
|
624
|
-
)}
|
|
625
|
-
</For>
|
|
626
|
-
</nav>
|
|
627
|
-
</aside>
|
|
628
|
-
<main class="void-md">
|
|
629
|
-
<h1>{fm.title}</h1>
|
|
630
|
-
{props.children}
|
|
631
|
-
</main>
|
|
632
|
-
</div>
|
|
633
|
-
);
|
|
634
|
-
}
|
|
476
|
+
const docPages = pages.filter((page) => page.path.startsWith('/docs/'));
|
|
635
477
|
```
|
|
636
478
|
|
|
637
|
-
|
|
479
|
+
Render a link with `page.path` and `page.title` for each entry. Use `useFrontmatter()` in the layout to display the current page's metadata, and wrap its content in `.void-md` when using the provided theme.
|
|
@@ -86,9 +86,7 @@ export default defineConfig({
|
|
|
86
86
|
|
|
87
87
|
:::
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
Each adapter plugin includes the framework's Vite plugin (`@vitejs/plugin-react`, `@vitejs/plugin-vue`, `@sveltejs/vite-plugin-svelte`, `vite-plugin-solid`) so you don't need to install or configure it separately. Pass framework plugin options via `voidReact({ react: { ... } })`, `voidVue({ vue: { ... } })`, `voidSvelte({ svelte: { ... } })`, or `voidSolid({ solid: { ... } })` if needed.
|
|
89
|
+
Each adapter includes its framework's Vite plugin. Pass framework plugin options via `voidReact({ react: { ... } })`, `voidVue({ vue: { ... } })`, `voidSvelte({ svelte: { ... } })`, or `voidSolid({ solid: { ... } })` if needed.
|
|
92
90
|
|
|
93
91
|
## Directory Structure
|
|
94
92
|
|
|
@@ -106,15 +104,7 @@ File-based routing rules are the same as [server routing](../server-routing.md):
|
|
|
106
104
|
|
|
107
105
|
## How Navigation Works
|
|
108
106
|
|
|
109
|
-
The first
|
|
110
|
-
|
|
111
|
-
| Request | Response |
|
|
112
|
-
| --------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
113
|
-
| Initial page load | Full SSR HTML. Client hydrates automatically. Routes with `ssr = false` return a client-mounted shell instead. |
|
|
114
|
-
| Subsequent navigation | JSON with component name + props. Client component swap or re-render. |
|
|
115
|
-
| Form submission | Runs action, then returns fresh props or a redirect. |
|
|
116
|
-
|
|
117
|
-
The first request receives rendered HTML. Later navigations load page data and update the UI without reloading the whole document.
|
|
107
|
+
The first request receives rendered HTML. Later navigations run the loader and update the page without reloading the document. Form submissions run an action, then refresh page props or redirect.
|
|
118
108
|
|
|
119
109
|
To opt a specific route out of server-rendered component HTML, export `ssr = false` from its companion `.server.ts` file:
|
|
120
110
|
|
|
@@ -182,7 +172,7 @@ import { Link } from "@void/solid";
|
|
|
182
172
|
|
|
183
173
|
:::
|
|
184
174
|
|
|
185
|
-
|
|
175
|
+
`Link` also supports query data, history replacement, full-page navigation, and cancellation:
|
|
186
176
|
|
|
187
177
|
```tsx
|
|
188
178
|
<Link href="/users" data={{ page: 2, tag: ['active', 'new'] }}>
|
|
@@ -209,7 +199,7 @@ The `Link` components also support query data, history replacement, document nav
|
|
|
209
199
|
</Link>
|
|
210
200
|
```
|
|
211
201
|
|
|
212
|
-
`prefetch` and `reloadDocument`
|
|
202
|
+
`prefetch` and `reloadDocument` work only with GET links. GET `data` becomes query parameters; use scalar values or arrays.
|
|
213
203
|
|
|
214
204
|
For programmatic navigation, use `useRouter()`:
|
|
215
205
|
|
|
@@ -235,13 +225,13 @@ export default function PostPage() {
|
|
|
235
225
|
|
|
236
226
|
## Scroll Restoration
|
|
237
227
|
|
|
238
|
-
|
|
228
|
+
Client-side navigation manages scroll position automatically:
|
|
239
229
|
|
|
240
230
|
- **Back/forward navigation** restores the exact scroll position you were at before navigating away.
|
|
241
|
-
- **
|
|
231
|
+
- **New navigation** scrolls to the top of the page.
|
|
242
232
|
- **Hash links** (`/docs#api`) scroll to the target element. Same-page hash links (`#section`) skip the server fetch entirely.
|
|
243
233
|
|
|
244
|
-
|
|
234
|
+
To keep the current scroll position, pass `preserveScroll: true`:
|
|
245
235
|
|
|
246
236
|
```ts
|
|
247
237
|
router.visit('/users', { preserveScroll: true });
|
|
@@ -4,7 +4,7 @@ outline: deep
|
|
|
4
4
|
|
|
5
5
|
# View Transitions
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Add animated page transitions with the browser’s [View Transition API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API). Pages cross-fade by default; use CSS to customize the animation.
|
|
8
8
|
|
|
9
9
|
## Enabling View Transitions
|
|
10
10
|
|
|
@@ -30,10 +30,7 @@ the company sign-in before Void login. Interactive Access authentication uses a
|
|
|
30
30
|
locally installed `cloudflared` and saves its short-lived credential in your
|
|
31
31
|
system keychain for that platform origin. You do not need to copy browser cookies.
|
|
32
32
|
|
|
33
|
-
For CI, Access credentials
|
|
34
|
-
owner creates the latter with `void project token create`; it is independently
|
|
35
|
-
revocable, expires within 90 days, and authorizes only that project's deploy
|
|
36
|
-
workflow. Human and operator tokens cannot be renewed by Access service proof.
|
|
33
|
+
For CI, use a [project deploy token](/guide/platform/installation/first-deployment) alongside your Access credentials. An Access service token does not authorize a Void deployment.
|
|
37
34
|
|
|
38
35
|
Store Access credentials in origin-keyed `VOID_ACCESS_CREDENTIALS`. A deploy
|
|
39
36
|
that uses prerendering or remote bindings needs entries for both the exact API
|
|
@@ -6,7 +6,26 @@ outline: deep
|
|
|
6
6
|
|
|
7
7
|
## Managing Email
|
|
8
8
|
|
|
9
|
-
These commands apply to a platform that enables email. Every project can send from
|
|
9
|
+
These commands apply to a platform that enables email. Every project can send from `<slug>+tag@<mail domain>` on the platform’s shared mail domain. Deploying an app with `email/` handlers sets up receiving at that address once its recipient rule is ready; the [email guide](/guide/email) describes what applications do with that.
|
|
10
|
+
|
|
11
|
+
Shared inbound mail uses one exact routing rule per receiving project and enables Cloudflare’s per-zone plus addressing. Creating a project or deploying an app that only sends mail consumes no inbound rule. Existing rules and the apex catch-all remain in place. Cloudflare normally allows [200 routing rules per domain](https://developers.cloudflare.com/email-service/platform/limits/); remove unused rules or request a higher limit if the shared domain reaches capacity. An unrelated rule for a project’s base address or a plus address blocks its setup until that conflict is removed.
|
|
12
|
+
|
|
13
|
+
If recipient creation is interrupted, inspect its retained intent:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
void platform email shared-recipients --project my-app
|
|
17
|
+
void platform email shared-recipient-resolve <recipient-id> --ended --outcome not-applied --reason "Provider audit confirms the request did not create a rule" --plan
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Wait until the reported recovery time, confirm the original execution ended,
|
|
21
|
+
and inspect the exact provider resource shown in the plan. Use `applied` when
|
|
22
|
+
the exact owned rule exists, or `not-applied` only when the provider audit
|
|
23
|
+
establishes that creation did not occur. Absence alone does not establish the
|
|
24
|
+
outcome. Run the same command with `--yes` after inspection. Recovery records
|
|
25
|
+
the decision in platform events without creating or deleting rules. Normal
|
|
26
|
+
reconciliation verifies delivery afterward; a deleting project stays closed
|
|
27
|
+
and its deletion can be retried. See [operator email commands](../../../reference/cli/platform-email.md#operator-email)
|
|
28
|
+
for the recovery requirements.
|
|
10
29
|
|
|
11
30
|
### Deciding who mail may reach
|
|
12
31
|
|
|
@@ -19,7 +38,15 @@ void platform email policy-set any
|
|
|
19
38
|
void platform email policy-set verified
|
|
20
39
|
```
|
|
21
40
|
|
|
22
|
-
|
|
41
|
+
Choose a policy in the admin UI's **Email** page or with the commands above:
|
|
42
|
+
|
|
43
|
+
- `verified`: only each project's verified recipients.
|
|
44
|
+
- `domains`: verified recipients plus any address on the listed domains.
|
|
45
|
+
- `any`: any recipient.
|
|
46
|
+
|
|
47
|
+
Unverified recipients still require Cloudflare Email Sending onboarding and [Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans). Otherwise those sends return `UNVERIFIED_DESTINATION`. Mail from a project's custom domain, and mail to the platform's own mail domain, always requires recipient verification.
|
|
48
|
+
|
|
49
|
+
Policy changes apply to new sends; admitted attempts may finish.
|
|
23
50
|
|
|
24
51
|
### Project caps
|
|
25
52
|
|
|
@@ -75,16 +102,16 @@ void platform email settings-set --domains admin
|
|
|
75
102
|
Then register a domain for a project. The zone must be in the platform's Cloudflare account; the platform's own credential does the setup, and no Cloudflare credential is stored per domain:
|
|
76
103
|
|
|
77
104
|
```sh
|
|
78
|
-
void platform email domain-add
|
|
79
|
-
void platform email domain-status
|
|
80
|
-
void platform email domain-rotate-secret
|
|
105
|
+
void platform email domain-add example.com --project hr-portal
|
|
106
|
+
void platform email domain-status example.com
|
|
107
|
+
void platform email domain-rotate-secret example.com
|
|
81
108
|
void platform email domains
|
|
82
109
|
```
|
|
83
110
|
|
|
84
|
-
|
|
111
|
+
Use the apex of the selected Cloudflare zone. Platform-managed custom inbound email uses its catch-all, which does not cover subdomains; choose an apex without another mail provider or use the platform’s shared mail address. `domain-status` reports inbound, outbound, and management readiness separately. Follow any required DNS or Cloudflare dashboard step, then use `domain-sync` to reconcile. Use `domain-rotate-secret` when you need to replace the zone ingress credential explicitly. Email Sending onboarding needs Workers Paid; after upgrading, `domain-sync` re-attempts it. For a zone in another Cloudflare account, pipe an API token for that account on standard input:
|
|
85
112
|
|
|
86
113
|
```sh
|
|
87
|
-
void platform email domain-add
|
|
114
|
+
void platform email domain-add other.example --project hr-portal --token-stdin --yes < token.txt
|
|
88
115
|
```
|
|
89
116
|
|
|
90
117
|
Project owners see administrator-registered domains in `void email domain list` and `status`; `status` names the `void platform email` command for any step they cannot take themselves, and `sync` and `remove` point them at `domain-sync` and `domain-remove`. A domain an owner registered before you switched to `admin` stays theirs to renew, sync and remove. The runtime token needs the email permissions listed in the [self-hosting guide](/guide/platform/installation/credentials#runtime-token-permissions) for this to work.
|
|
@@ -97,7 +124,7 @@ to finish the retained cleanup. If its token has expired or been revoked, provid
|
|
|
97
124
|
a replacement scoped to the same account and zone:
|
|
98
125
|
|
|
99
126
|
```sh
|
|
100
|
-
void platform email domain-remove
|
|
127
|
+
void platform email domain-remove other.example --token-stdin --yes < token.txt
|
|
101
128
|
```
|
|
102
129
|
|
|
103
130
|
This recovery is available only after project deletion has begun and no other
|