[{"data":1,"prerenderedAt":2948},["ShallowReactive",2],{"navigation_docs":3,"-modules-features-forms-definition":587,"-modules-features-forms-definition-surround":2943},[4,50,155,441,504],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":49},"Get Started","i-lucide-rocket","\u002Fget-started","1.get-started",[10,15,20,25,30,35,40,45],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fget-started\u002Fintroduction","1.get-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fget-started\u002Finstallation","1.get-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Project structure","\u002Fget-started\u002Fproject-structure","1.get-started\u002F3.project-structure","i-lucide-folder-tree",{"title":26,"path":27,"stem":28,"icon":29},"Configuration","\u002Fget-started\u002Fconfiguration","1.get-started\u002F4.configuration","i-lucide-settings",{"title":31,"path":32,"stem":33,"icon":34},"Authentication","\u002Fget-started\u002Fauthentication","1.get-started\u002F5.authentication","i-lucide-lock",{"title":36,"path":37,"stem":38,"icon":39},"Adding modules","\u002Fget-started\u002Fadding-modules","1.get-started\u002F6.adding-modules","i-lucide-puzzle",{"title":41,"path":42,"stem":43,"icon":44},"Database","\u002Fget-started\u002Fdatabase","1.get-started\u002F7.database","i-lucide-database",{"title":46,"path":47,"stem":48,"icon":6},"Deployment","\u002Fget-started\u002Fdeployment","1.get-started\u002F8.deployment",false,{"title":51,"icon":52,"path":53,"stem":54,"children":55,"page":49},"Guide","i-lucide-book-open","\u002Fguide","2.guide",[56,90,115,125],{"title":57,"icon":49,"path":58,"stem":59,"children":60,"page":49},"Concepts","\u002Fguide\u002Fconcepts","2.guide\u002F1.concepts",[61,66,71,76,80,85],{"title":62,"path":63,"stem":64,"icon":65},"Architecture","\u002Fguide\u002Fconcepts\u002Farchitecture","2.guide\u002F1.concepts\u002F1.architecture","i-lucide-blocks",{"title":67,"path":68,"stem":69,"icon":70},"Access control","\u002Fguide\u002Fconcepts\u002Fauth-and-scopes","2.guide\u002F1.concepts\u002F2.auth-and-scopes","i-lucide-shield-check",{"title":72,"path":73,"stem":74,"icon":75},"Extension points","\u002Fguide\u002Fconcepts\u002Fextension-points","2.guide\u002F1.concepts\u002F3.extension-points","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":44},"Database extensions","\u002Fguide\u002Fconcepts\u002Fdatabase-extensions","2.guide\u002F1.concepts\u002F4.database-extensions",{"title":81,"path":82,"stem":83,"icon":84},"Identity","\u002Fguide\u002Fconcepts\u002Fidentity","2.guide\u002F1.concepts\u002F5.identity","i-lucide-fingerprint",{"title":86,"path":87,"stem":88,"icon":89},"Glossary","\u002Fguide\u002Fconcepts\u002Fglossary","2.guide\u002F1.concepts\u002F6.glossary","i-lucide-book-a",{"title":91,"icon":49,"path":92,"stem":93,"children":94,"page":49},"UX patterns","\u002Fguide\u002Fux-patterns","2.guide\u002F2.ux-patterns",[95,100,105,110],{"title":96,"path":97,"stem":98,"icon":99},"Layouts and navigation","\u002Fguide\u002Fux-patterns\u002Flayouts-and-navigation","2.guide\u002F2.ux-patterns\u002F1.layouts-and-navigation","i-lucide-layout-template",{"title":101,"path":102,"stem":103,"icon":104},"Pages","\u002Fguide\u002Fux-patterns\u002Fpages","2.guide\u002F2.ux-patterns\u002F2.pages","i-lucide-table",{"title":106,"path":107,"stem":108,"icon":109},"Forms and actions","\u002Fguide\u002Fux-patterns\u002Fforms-and-actions","2.guide\u002F2.ux-patterns\u002F3.forms-and-actions","i-lucide-square-pen",{"title":111,"path":112,"stem":113,"icon":114},"Text and formatting","\u002Fguide\u002Fux-patterns\u002Ftext-and-formatting","2.guide\u002F2.ux-patterns\u002F4.text-and-formatting","i-lucide-type",{"title":116,"icon":49,"path":117,"stem":118,"children":119,"page":49},"Best practices","\u002Fguide\u002Fbest-practices","2.guide\u002F3.best-practices",[120],{"title":121,"path":122,"stem":123,"icon":124},"HTTP routes","\u002Fguide\u002Fbest-practices\u002Fhttp-routes","2.guide\u002F3.best-practices\u002F1.http-routes","i-lucide-route",{"title":126,"icon":49,"path":127,"stem":128,"children":129,"page":49},"Going further","\u002Fguide\u002Fgoing-further","2.guide\u002F4.going-further",[130,135,140,145,150],{"title":131,"path":132,"stem":133,"icon":134},"Use your own OAuth server","\u002Fguide\u002Fgoing-further\u002Fown-oauth-server","2.guide\u002F4.going-further\u002F1.own-oauth-server","i-lucide-key-round",{"title":136,"path":137,"stem":138,"icon":139},"Create an OAuth application","\u002Fguide\u002Fgoing-further\u002Foauth-application","2.guide\u002F4.going-further\u002F2.oauth-application","i-lucide-app-window",{"title":141,"path":142,"stem":143,"icon":144},"Signing keys","\u002Fguide\u002Fgoing-further\u002Fsigning-keys","2.guide\u002F4.going-further\u002F3.signing-keys","i-lucide-key-square",{"title":146,"path":147,"stem":148,"icon":149},"Stripe setup","\u002Fguide\u002Fgoing-further\u002Fstripe-setup","2.guide\u002F4.going-further\u002F4.stripe-setup","i-lucide-credit-card",{"title":151,"path":152,"stem":153,"icon":154},"Migrate to the permission model","\u002Fguide\u002Fgoing-further\u002Fmigrate-access-control","2.guide\u002F4.going-further\u002F5.migrate-access-control","i-lucide-arrow-right-left",{"title":156,"icon":157,"path":158,"stem":159,"children":160},"Modules","i-lucide-boxes","\u002Fmodules","3.modules",[161,163,244,273,320,375],{"title":156,"path":158,"stem":162},"3.modules\u002Findex",{"title":81,"icon":49,"path":164,"stem":165,"children":166,"page":49},"\u002Fmodules\u002Fidentity","3.modules\u002F1.identity",[167,190,194,198,220,224,240],{"title":168,"path":169,"stem":170,"children":171},"Auth","\u002Fmodules\u002Fidentity\u002Fauth","3.modules\u002F1.identity\u002F1.auth\u002Findex",[172,174,178,182,186],{"title":173,"path":169,"stem":170},"Overview",{"title":175,"path":176,"stem":177},"Server API","\u002Fmodules\u002Fidentity\u002Fauth\u002Fserver","3.modules\u002F1.identity\u002F1.auth\u002F2.server",{"title":179,"path":180,"stem":181},"Reference","\u002Fmodules\u002Fidentity\u002Fauth\u002Freference","3.modules\u002F1.identity\u002F1.auth\u002F3.reference",{"title":183,"path":184,"stem":185},"Client mode","\u002Fmodules\u002Fidentity\u002Fauth\u002Fclient-mode","3.modules\u002F1.identity\u002F1.auth\u002F4.client-mode",{"title":187,"path":188,"stem":189},"OAuth providers","\u002Fmodules\u002Fidentity\u002Fauth\u002Foauth-providers","3.modules\u002F1.identity\u002F1.auth\u002F5.oauth-providers",{"title":191,"path":192,"stem":193},"Users","\u002Fmodules\u002Fidentity\u002Fusers","3.modules\u002F1.identity\u002F2.users",{"title":195,"path":196,"stem":197},"Account","\u002Fmodules\u002Fidentity\u002Faccount","3.modules\u002F1.identity\u002F3.account",{"title":199,"path":200,"stem":201,"children":202},"Authorization","\u002Fmodules\u002Fidentity\u002Fauthorization","3.modules\u002F1.identity\u002F4.authorization\u002Findex",[203,204,208,212,216],{"title":173,"path":200,"stem":201},{"title":205,"path":206,"stem":207},"Roles and requirements","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Froles-and-requirements","3.modules\u002F1.identity\u002F4.authorization\u002F2.roles-and-requirements",{"title":209,"path":210,"stem":211},"Policies","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Fpolicies","3.modules\u002F1.identity\u002F4.authorization\u002F3.policies",{"title":213,"path":214,"stem":215},"Client","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Fclient","3.modules\u002F1.identity\u002F4.authorization\u002F4.client",{"title":217,"path":218,"stem":219},"Admin","\u002Fmodules\u002Fidentity\u002Fauthorization\u002Fadmin","3.modules\u002F1.identity\u002F4.authorization\u002F5.admin",{"title":221,"path":222,"stem":223},"Preferences","\u002Fmodules\u002Fidentity\u002Fpreferences","3.modules\u002F1.identity\u002F5.preferences",{"title":225,"path":226,"stem":227,"children":228},"OAuth Server","\u002Fmodules\u002Fidentity\u002Foauth-server","3.modules\u002F1.identity\u002F6.oauth-server\u002Findex",[229,230,233,237],{"title":173,"path":226,"stem":227},{"title":175,"path":231,"stem":232},"\u002Fmodules\u002Fidentity\u002Foauth-server\u002Fserver","3.modules\u002F1.identity\u002F6.oauth-server\u002F2.server",{"title":234,"path":235,"stem":236},"Hooks","\u002Fmodules\u002Fidentity\u002Foauth-server\u002Fhooks","3.modules\u002F1.identity\u002F6.oauth-server\u002F3.hooks",{"title":179,"path":238,"stem":239},"\u002Fmodules\u002Fidentity\u002Foauth-server\u002Froutes-and-clients","3.modules\u002F1.identity\u002F6.oauth-server\u002F4.routes-and-clients",{"title":241,"path":242,"stem":243},"OAuth Resource","\u002Fmodules\u002Fidentity\u002Foauth-resource","3.modules\u002F1.identity\u002F8.oauth-resource",{"title":245,"icon":49,"path":246,"stem":247,"children":248,"page":49},"Commerce","\u002Fmodules\u002Fcommerce","3.modules\u002F2.commerce",[249,253,257],{"title":250,"path":251,"stem":252},"Stripe","\u002Fmodules\u002Fcommerce\u002Fstripe","3.modules\u002F2.commerce\u002F1.stripe",{"title":254,"path":255,"stem":256},"Payments","\u002Fmodules\u002Fcommerce\u002Fpayments","3.modules\u002F2.commerce\u002F2.payments",{"title":258,"path":259,"stem":260,"children":261},"Subscriptions","\u002Fmodules\u002Fcommerce\u002Fsubscriptions","3.modules\u002F2.commerce\u002F3.subscriptions\u002Findex",[262,263,266,270],{"title":173,"path":259,"stem":260},{"title":175,"path":264,"stem":265},"\u002Fmodules\u002Fcommerce\u002Fsubscriptions\u002Fserver","3.modules\u002F2.commerce\u002F3.subscriptions\u002F2.server",{"title":267,"path":268,"stem":269},"App","\u002Fmodules\u002Fcommerce\u002Fsubscriptions\u002Fapp","3.modules\u002F2.commerce\u002F3.subscriptions\u002F3.app",{"title":179,"path":271,"stem":272},"\u002Fmodules\u002Fcommerce\u002Fsubscriptions\u002Freference","3.modules\u002F2.commerce\u002F3.subscriptions\u002F4.reference",{"title":274,"icon":49,"path":275,"stem":276,"children":277,"page":49},"Features","\u002Fmodules\u002Ffeatures","3.modules\u002F3.features",[278,293,312,316],{"title":279,"path":280,"stem":281,"children":282},"Events","\u002Fmodules\u002Ffeatures\u002Fevents","3.modules\u002F3.features\u002F1.events\u002Findex",[283,284,287,290],{"title":173,"path":280,"stem":281},{"title":175,"path":285,"stem":286},"\u002Fmodules\u002Ffeatures\u002Fevents\u002Fserver","3.modules\u002F3.features\u002F1.events\u002F2.server",{"title":267,"path":288,"stem":289},"\u002Fmodules\u002Ffeatures\u002Fevents\u002Fapp","3.modules\u002F3.features\u002F1.events\u002F3.app",{"title":179,"path":291,"stem":292},"\u002Fmodules\u002Ffeatures\u002Fevents\u002Freference","3.modules\u002F3.features\u002F1.events\u002F4.reference",{"title":294,"path":295,"stem":296,"children":297},"Forms","\u002Fmodules\u002Ffeatures\u002Fforms","3.modules\u002F3.features\u002F2.forms\u002Findex",[298,299,303,306,309],{"title":173,"path":295,"stem":296},{"title":300,"path":301,"stem":302},"Definition","\u002Fmodules\u002Ffeatures\u002Fforms\u002Fdefinition","3.modules\u002F3.features\u002F2.forms\u002F2.definition",{"title":175,"path":304,"stem":305},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Fserver","3.modules\u002F3.features\u002F2.forms\u002F3.server",{"title":267,"path":307,"stem":308},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Fapp","3.modules\u002F3.features\u002F2.forms\u002F4.app",{"title":179,"path":310,"stem":311},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Freference","3.modules\u002F3.features\u002F2.forms\u002F5.reference",{"title":313,"path":314,"stem":315},"Cookie Consent","\u002Fmodules\u002Ffeatures\u002Fcookie-consent","3.modules\u002F3.features\u002F3.cookie-consent",{"title":317,"path":318,"stem":319},"MCP","\u002Fmodules\u002Ffeatures\u002Fmcp","3.modules\u002F3.features\u002F4.mcp",{"title":321,"icon":49,"path":322,"stem":323,"children":324,"page":49},"Interface","\u002Fmodules\u002Finterface","3.modules\u002F4.interface",[325,350,353,357,361],{"title":326,"path":327,"stem":328,"children":329},"UI","\u002Fmodules\u002Finterface\u002Fui","3.modules\u002F4.interface\u002F1.ui\u002Findex",[330,331,335,339,343,347],{"title":173,"path":327,"stem":328},{"title":332,"path":333,"stem":334},"Page components","\u002Fmodules\u002Finterface\u002Fui\u002Fpage-components","3.modules\u002F4.interface\u002F1.ui\u002F2.page-components",{"title":336,"path":337,"stem":338},"App shell","\u002Fmodules\u002Finterface\u002Fui\u002Fapp-shell","3.modules\u002F4.interface\u002F1.ui\u002F3.app-shell",{"title":340,"path":341,"stem":342},"Form inputs","\u002Fmodules\u002Finterface\u002Fui\u002Fform-inputs","3.modules\u002F4.interface\u002F1.ui\u002F4.form-inputs",{"title":344,"path":345,"stem":346},"Composables and helpers","\u002Fmodules\u002Finterface\u002Fui\u002Fcomposables","3.modules\u002F4.interface\u002F1.ui\u002F5.composables",{"title":179,"path":348,"stem":349},"\u002Fmodules\u002Finterface\u002Fui\u002Freference","3.modules\u002F4.interface\u002F1.ui\u002F6.reference",{"title":217,"path":351,"stem":352},"\u002Fmodules\u002Finterface\u002Fadmin","3.modules\u002F4.interface\u002F2.admin",{"title":354,"path":355,"stem":356},"Menu","\u002Fmodules\u002Finterface\u002Fmenu","3.modules\u002F4.interface\u002F3.menu",{"title":358,"path":359,"stem":360},"Widget","\u002Fmodules\u002Finterface\u002Fwidget","3.modules\u002F4.interface\u002F4.widget",{"title":362,"path":363,"stem":364,"children":365},"Mobile","\u002Fmodules\u002Finterface\u002Fmobile","3.modules\u002F4.interface\u002F5.mobile\u002Findex",[366,367,371],{"title":173,"path":363,"stem":364},{"title":368,"path":369,"stem":370},"CLI and devices","\u002Fmodules\u002Finterface\u002Fmobile\u002Fcli-and-devices","3.modules\u002F4.interface\u002F5.mobile\u002F2.cli-and-devices",{"title":372,"path":373,"stem":374},"Splash screen","\u002Fmodules\u002Finterface\u002Fmobile\u002Fsplash-screen","3.modules\u002F4.interface\u002F5.mobile\u002F3.splash-screen",{"title":376,"icon":49,"path":377,"stem":378,"children":379,"page":49},"Platform","\u002Fmodules\u002Fplatform","3.modules\u002F5.platform",[380,402,406,423],{"title":381,"path":382,"stem":383,"children":384},"Module Kit","\u002Fmodules\u002Fplatform\u002Fmodule-kit","3.modules\u002F5.platform\u002F1.module-kit\u002Findex",[385,386,390,394,398],{"title":173,"path":382,"stem":383},{"title":387,"path":388,"stem":389},"Server toolkit","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fserver-toolkit","3.modules\u002F5.platform\u002F1.module-kit\u002F2.server-toolkit",{"title":391,"path":392,"stem":393},"Registries and menus","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fregistries-and-menus","3.modules\u002F5.platform\u002F1.module-kit\u002F3.registries-and-menus",{"title":395,"path":396,"stem":397},"Translations","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fi18n","3.modules\u002F5.platform\u002F1.module-kit\u002F4.i18n",{"title":399,"path":400,"stem":401},"Database helpers","\u002Fmodules\u002Fplatform\u002Fmodule-kit\u002Fdatabase","3.modules\u002F5.platform\u002F1.module-kit\u002F5.database",{"title":403,"path":404,"stem":405},"Notify","\u002Fmodules\u002Fplatform\u002Fnotify","3.modules\u002F5.platform\u002F2.notify",{"title":407,"path":408,"stem":409,"children":410},"Email Templates","\u002Fmodules\u002Fplatform\u002Femail-templates","3.modules\u002F5.platform\u002F3.email-templates\u002Findex",[411,412,416,419],{"title":173,"path":408,"stem":409},{"title":413,"path":414,"stem":415},"Email components","\u002Fmodules\u002Fplatform\u002Femail-templates\u002Fcomponents","3.modules\u002F5.platform\u002F3.email-templates\u002F2.components",{"title":175,"path":417,"stem":418},"\u002Fmodules\u002Fplatform\u002Femail-templates\u002Fserver","3.modules\u002F5.platform\u002F3.email-templates\u002F3.server",{"title":420,"path":421,"stem":422},"Module emails","\u002Fmodules\u002Fplatform\u002Femail-templates\u002Fmodule-emails","3.modules\u002F5.platform\u002F3.email-templates\u002F4.module-emails",{"title":424,"path":425,"stem":426,"children":427},"Base Layer","\u002Fmodules\u002Fplatform\u002Fbase-layer","3.modules\u002F5.platform\u002F4.base-layer\u002Findex",[428,429,433,437],{"title":173,"path":425,"stem":426},{"title":430,"path":431,"stem":432},"Content collections","\u002Fmodules\u002Fplatform\u002Fbase-layer\u002Fcontent-collections","3.modules\u002F5.platform\u002F4.base-layer\u002F2.content-collections",{"title":434,"path":435,"stem":436},"Layouts and routing","\u002Fmodules\u002Fplatform\u002Fbase-layer\u002Flayouts-and-routing","3.modules\u002F5.platform\u002F4.base-layer\u002F3.layouts-and-routing",{"title":438,"path":439,"stem":440},"Composables and utils","\u002Fmodules\u002Fplatform\u002Fbase-layer\u002Fcomposables-and-utils","3.modules\u002F5.platform\u002F4.base-layer\u002F4.composables-and-utils",{"title":442,"icon":443,"path":444,"stem":445,"children":446,"page":49},"Examples","i-lucide-code-xml","\u002Fexamples","4.examples",[447,466,476],{"title":448,"icon":49,"path":449,"stem":450,"children":451,"page":49},"Starters","\u002Fexamples\u002Fstarters","4.examples\u002F1.starters",[452,456,461],{"title":453,"path":454,"stem":455,"icon":6},"Workspace starter","\u002Fexamples\u002Fstarters\u002Fworkspace","4.examples\u002F1.starters\u002F1.workspace",{"title":457,"path":458,"stem":459,"icon":460},"Mobile starter","\u002Fexamples\u002Fstarters\u002Fmobile","4.examples\u002F1.starters\u002F2.mobile","i-lucide-smartphone",{"title":462,"path":463,"stem":464,"icon":465},"Standalone mobile starter","\u002Fexamples\u002Fstarters\u002Fmobile-standalone","4.examples\u002F1.starters\u002F3.mobile-standalone","i-lucide-tablet-smartphone",{"title":467,"icon":49,"path":468,"stem":469,"children":470,"page":49},"Apps","\u002Fexamples\u002Fapps","4.examples\u002F2.apps",[471],{"title":472,"path":473,"stem":474,"icon":475},"Frigear website app","\u002Fexamples\u002Fapps\u002Ffrigear-nu-website","4.examples\u002F2.apps\u002F1.frigear-nu-website","i-lucide-layout-dashboard",{"title":477,"icon":49,"path":478,"stem":479,"children":480,"page":49},"Tasks","\u002Fexamples\u002Ftasks","4.examples\u002F3.tasks",[481,485,489,494,499],{"title":482,"path":483,"stem":484,"icon":70},"Protect a route","\u002Fexamples\u002Ftasks\u002Fprotect-a-route","4.examples\u002F3.tasks\u002F1.protect-a-route",{"title":486,"path":487,"stem":488,"icon":475},"Add an admin page","\u002Fexamples\u002Ftasks\u002Fadd-an-admin-page","4.examples\u002F3.tasks\u002F2.add-an-admin-page",{"title":490,"path":491,"stem":492,"icon":493},"Sell event tickets","\u002Fexamples\u002Ftasks\u002Fsell-event-tickets","4.examples\u002F3.tasks\u002F3.sell-event-tickets","i-lucide-ticket",{"title":495,"path":496,"stem":497,"icon":498},"Build a form","\u002Fexamples\u002Ftasks\u002Fbuild-a-form","4.examples\u002F3.tasks\u002F4.build-a-form","i-lucide-clipboard-list",{"title":500,"path":501,"stem":502,"icon":503},"Send an email","\u002Fexamples\u002Ftasks\u002Fsend-an-email","4.examples\u002F3.tasks\u002F5.send-an-email","i-lucide-mail",{"title":505,"icon":506,"path":507,"stem":508,"children":509,"page":49},"Contribute","i-lucide-git-pull-request","\u002Fcontribute","5.contribute",[510,513,518,544,549,552,556,571],{"title":173,"path":511,"stem":512,"icon":506},"\u002Fcontribute\u002Foverview","5.contribute\u002F1.overview",{"title":514,"path":515,"stem":516,"icon":517},"Local development","\u002Fcontribute\u002Flocal-development","5.contribute\u002F2.local-development","i-lucide-terminal",{"title":519,"icon":49,"path":520,"stem":521,"children":522,"page":49},"Writing a module","\u002Fcontribute\u002Fwriting-a-module","5.contribute\u002F3.writing-a-module",[523,527,532,536,541],{"title":524,"path":525,"stem":526,"icon":39},"Scaffold a module","\u002Fcontribute\u002Fwriting-a-module\u002Fscaffold","5.contribute\u002F3.writing-a-module\u002F1.scaffold",{"title":528,"path":529,"stem":530,"icon":531},"Setup checklist","\u002Fcontribute\u002Fwriting-a-module\u002Fsetup-checklist","5.contribute\u002F3.writing-a-module\u002F2.setup-checklist","i-lucide-list-checks",{"title":533,"path":534,"stem":535,"icon":44},"Database tables","\u002Fcontribute\u002Fwriting-a-module\u002Fdatabase-tables","5.contribute\u002F3.writing-a-module\u002F3.database-tables",{"title":537,"path":538,"stem":539,"icon":540},"Testing","\u002Fcontribute\u002Fwriting-a-module\u002Ftesting","5.contribute\u002F3.writing-a-module\u002F4.testing","i-lucide-flask-conical",{"title":67,"path":542,"stem":543,"icon":70},"\u002Fcontribute\u002Fwriting-a-module\u002Faccess-control","5.contribute\u002F3.writing-a-module\u002F5.access-control",{"title":545,"path":546,"stem":547,"icon":548},"Publishing","\u002Fcontribute\u002Fpublishing","5.contribute\u002F4.publishing","i-lucide-package-check",{"title":448,"path":550,"stem":551,"icon":6},"\u002Fcontribute\u002Fstarters","5.contribute\u002F5.starters",{"title":553,"path":554,"stem":555,"icon":52},"Documentation","\u002Fcontribute\u002Fdocumentation","5.contribute\u002F6.documentation",{"title":557,"icon":49,"path":558,"stem":559,"children":560,"page":49},"Tooling","\u002Fcontribute\u002Ftooling","5.contribute\u002F7.tooling",[561,566],{"title":562,"path":563,"stem":564,"icon":565},"CLI","\u002Fcontribute\u002Ftooling\u002Fcli","5.contribute\u002F7.tooling\u002F1.cli","i-lucide-square-terminal",{"title":567,"path":568,"stem":569,"icon":570},"ESLint config","\u002Fcontribute\u002Ftooling\u002Feslint-config","5.contribute\u002F7.tooling\u002F2.eslint-config","i-lucide-spell-check",{"title":572,"icon":49,"path":573,"stem":574,"children":575},"Decisions","\u002Fcontribute\u002Fdecisions","5.contribute\u002F8.decisions\u002Findex",[576,578,583],{"title":572,"path":573,"stem":574,"icon":577},"i-lucide-scale",{"title":579,"path":580,"stem":581,"icon":582},"Session lifetimes per OAuth client","\u002Fcontribute\u002Fdecisions\u002Foauth-token-lifetimes","5.contribute\u002F8.decisions\u002F1.oauth-token-lifetimes","i-lucide-timer",{"title":584,"path":585,"stem":586,"icon":70},"One permission model","\u002Fcontribute\u002Fdecisions\u002Fpermission-model","5.contribute\u002F8.decisions\u002F2.permission-model",{"id":588,"title":589,"body":590,"description":2936,"extension":2937,"links":2938,"meta":2939,"navigation":2940,"path":301,"seo":2941,"stem":302,"__hash__":2942},"docs\u002F3.modules\u002F3.features\u002F2.forms\u002F2.definition.md","Forms definition",{"type":591,"value":592,"toc":2926},"minimark",[593,601,606,609,621,1592,1606,1616,1620,1623,1749,1753,1763,1942,1995,1999,2013,2250,2270,2274,2287,2398,2504,2559,2562,2567,2743,2788,2792,2840,2850,2854,2878,2896,2900,2922],[594,595,596,597,600],"p",{},"This page describes the definition: what a form asks, who may answer it and where the answers go. It is for app\ndevelopers who write forms in code or want to know what the builder can do. Set up the\nmodule first: ",[598,599,173],"a",{"href":295},".",[602,603,605],"h2",{"id":604},"the-definition","The definition",[594,607,608],{},"The client and the server compile the same definition into one validation schema, so both agree on what is required.\nEach submission stores a copy of the definition it was answered against, so old submissions still render after the\nform changes.",[594,610,611,612,616,617,620],{},"Write a definition in code with ",[613,614,615],"code",{},"defineForm()"," from ",[613,618,619],{},"@frigear-nu\u002Fforms\u002Futils",". These are its types, abridged:",[622,623,628],"pre",{"className":624,"code":625,"language":626,"meta":627,"style":627},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","type FormDefinition = {\n  mode: 'single' | 'stepped' \u002F\u002F 'single' has exactly one step and no stepper\n  storage: 'db' | 'none' \u002F\u002F default 'db'\n  steps: FormStep[]\n  submit?: {\n    label?: Translated\n    successMessage?: Translated\n    redirect?: string \u002F\u002F same-origin path\n    allowResubmit?: { keep: string[] } \u002F\u002F offers \"send another\"; these field keys stay filled in\n  }\n  delivery?: {\n    email?: {\n      to: string[] \u002F\u002F literal addresses; ${...} placeholders are rejected\n      subject?: Translated \u002F\u002F may use {{variables}}\n      body?: Translated \u002F\u002F plain text with {{variables}}, up to 10,000 characters per language\n      routes?: { field: string, to: Record\u003Cstring, string[]> } \u002F\u002F recipients by one field's answer, falling back to `to`\n      replyToField?: string \u002F\u002F key of an email field\n    }\n  }\n  access?: FormAccess \u002F\u002F default { availability: 'web', auth: 'none' }\n}\n\ntype FormStep = { id: string, title?: Translated, description?: Translated, showIf?: Condition, fields: FormField[] }\n\ntype FormField = {\n  key: string \u002F\u002F unique across the form; the key of the answer\n  type: 'text' | 'email' | 'tel' | 'number' | 'textarea' | 'select' | 'radio' | 'checkbox' | 'date' | 'file' | 'markdown' | 'captcha'\n  label?: Translated\n  description?: Translated\n  placeholder?: Translated\n  content?: Translated \u002F\u002F markdown fields\n  required?: boolean\n  options?: { value: string, label: Translated }[] \u002F\u002F select \u002F radio\n  multiple?: boolean \u002F\u002F file fields\n  autocomplete?: string \u002F\u002F defaults: 'email' for email, 'tel' for tel ('tel-national' next to a country selector)\n  validation?: { min?, max?, minLength?, maxLength?, pattern?, maxFiles?, maxSize?, accept?: string[], message?: Translated }\n  phone?: PhoneConfig \u002F\u002F tel fields\n  captcha?: CaptchaConfig \u002F\u002F captcha fields\n  showIf?: Condition\n}\n\ntype Condition = { field: string, op: 'eq' | 'neq' | 'in' | 'empty' | 'notEmpty' | 'truthy', value?: unknown }\n\ntype FormAccess = {\n  availability: 'web' | 'api' \u002F\u002F 'api' = no public page\n  auth: 'none' | 'user' | 'token' | 'password'\n  schedule?: Schedule \u002F\u002F default always open; see Open period\n}\n","ts","",[613,629,630,650,684,711,726,737,748,758,772,799,805,815,825,840,854,867,917,930,936,941,955,961,968,1028,1033,1044,1057,1172,1182,1192,1202,1215,1226,1259,1273,1286,1353,1367,1381,1392,1397,1402,1489,1494,1505,1532,1573,1587],{"__ignoreMap":627},[631,632,635,639,643,647],"span",{"class":633,"line":634},"line",1,[631,636,638],{"class":637},"spNyl","type",[631,640,642],{"class":641},"sBMFI"," FormDefinition",[631,644,646],{"class":645},"sMK4o"," =",[631,648,649],{"class":645}," {\n",[631,651,653,657,660,663,667,670,673,675,678,680],{"class":633,"line":652},2,[631,654,656],{"class":655},"swJcz","  mode",[631,658,659],{"class":645},":",[631,661,662],{"class":645}," '",[631,664,666],{"class":665},"sfazB","single",[631,668,669],{"class":645},"'",[631,671,672],{"class":645}," |",[631,674,662],{"class":645},[631,676,677],{"class":665},"stepped",[631,679,669],{"class":645},[631,681,683],{"class":682},"sHwdD"," \u002F\u002F 'single' has exactly one step and no stepper\n",[631,685,687,690,692,694,697,699,701,703,706,708],{"class":633,"line":686},3,[631,688,689],{"class":655},"  storage",[631,691,659],{"class":645},[631,693,662],{"class":645},[631,695,696],{"class":665},"db",[631,698,669],{"class":645},[631,700,672],{"class":645},[631,702,662],{"class":645},[631,704,705],{"class":665},"none",[631,707,669],{"class":645},[631,709,710],{"class":682}," \u002F\u002F default 'db'\n",[631,712,714,717,719,722],{"class":633,"line":713},4,[631,715,716],{"class":655},"  steps",[631,718,659],{"class":645},[631,720,721],{"class":641}," FormStep",[631,723,725],{"class":724},"sTEyZ","[]\n",[631,727,729,732,735],{"class":633,"line":728},5,[631,730,731],{"class":655},"  submit",[631,733,734],{"class":645},"?:",[631,736,649],{"class":645},[631,738,740,743,745],{"class":633,"line":739},6,[631,741,742],{"class":655},"    label",[631,744,734],{"class":645},[631,746,747],{"class":641}," Translated\n",[631,749,751,754,756],{"class":633,"line":750},7,[631,752,753],{"class":655},"    successMessage",[631,755,734],{"class":645},[631,757,747],{"class":641},[631,759,761,764,766,769],{"class":633,"line":760},8,[631,762,763],{"class":655},"    redirect",[631,765,734],{"class":645},[631,767,768],{"class":641}," string",[631,770,771],{"class":682}," \u002F\u002F same-origin path\n",[631,773,775,778,780,783,786,788,790,793,796],{"class":633,"line":774},9,[631,776,777],{"class":655},"    allowResubmit",[631,779,734],{"class":645},[631,781,782],{"class":645}," {",[631,784,785],{"class":655}," keep",[631,787,659],{"class":645},[631,789,768],{"class":641},[631,791,792],{"class":724},"[] ",[631,794,795],{"class":645},"}",[631,797,798],{"class":682}," \u002F\u002F offers \"send another\"; these field keys stay filled in\n",[631,800,802],{"class":633,"line":801},10,[631,803,804],{"class":645},"  }\n",[631,806,808,811,813],{"class":633,"line":807},11,[631,809,810],{"class":655},"  delivery",[631,812,734],{"class":645},[631,814,649],{"class":645},[631,816,818,821,823],{"class":633,"line":817},12,[631,819,820],{"class":655},"    email",[631,822,734],{"class":645},[631,824,649],{"class":645},[631,826,828,831,833,835,837],{"class":633,"line":827},13,[631,829,830],{"class":655},"      to",[631,832,659],{"class":645},[631,834,768],{"class":641},[631,836,792],{"class":724},[631,838,839],{"class":682},"\u002F\u002F literal addresses; ${...} placeholders are rejected\n",[631,841,843,846,848,851],{"class":633,"line":842},14,[631,844,845],{"class":655},"      subject",[631,847,734],{"class":645},[631,849,850],{"class":641}," Translated",[631,852,853],{"class":682}," \u002F\u002F may use {{variables}}\n",[631,855,857,860,862,864],{"class":633,"line":856},15,[631,858,859],{"class":655},"      body",[631,861,734],{"class":645},[631,863,850],{"class":641},[631,865,866],{"class":682}," \u002F\u002F plain text with {{variables}}, up to 10,000 characters per language\n",[631,868,870,873,875,877,880,882,884,887,890,892,895,898,901,903,905,908,911,914],{"class":633,"line":869},16,[631,871,872],{"class":655},"      routes",[631,874,734],{"class":645},[631,876,782],{"class":645},[631,878,879],{"class":655}," field",[631,881,659],{"class":645},[631,883,768],{"class":641},[631,885,886],{"class":645},",",[631,888,889],{"class":655}," to",[631,891,659],{"class":645},[631,893,894],{"class":641}," Record",[631,896,897],{"class":645},"\u003C",[631,899,900],{"class":641},"string",[631,902,886],{"class":645},[631,904,768],{"class":641},[631,906,907],{"class":724},"[]",[631,909,910],{"class":645},">",[631,912,913],{"class":645}," }",[631,915,916],{"class":682}," \u002F\u002F recipients by one field's answer, falling back to `to`\n",[631,918,920,923,925,927],{"class":633,"line":919},17,[631,921,922],{"class":655},"      replyToField",[631,924,734],{"class":645},[631,926,768],{"class":641},[631,928,929],{"class":682}," \u002F\u002F key of an email field\n",[631,931,933],{"class":633,"line":932},18,[631,934,935],{"class":645},"    }\n",[631,937,939],{"class":633,"line":938},19,[631,940,804],{"class":645},[631,942,944,947,949,952],{"class":633,"line":943},20,[631,945,946],{"class":655},"  access",[631,948,734],{"class":645},[631,950,951],{"class":641}," FormAccess",[631,953,954],{"class":682}," \u002F\u002F default { availability: 'web', auth: 'none' }\n",[631,956,958],{"class":633,"line":957},21,[631,959,960],{"class":645},"}\n",[631,962,964],{"class":633,"line":963},22,[631,965,967],{"emptyLinePlaceholder":966},true,"\n",[631,969,971,973,975,977,979,982,984,986,988,991,993,995,997,1000,1002,1004,1006,1009,1011,1014,1016,1019,1021,1024,1026],{"class":633,"line":970},23,[631,972,638],{"class":637},[631,974,721],{"class":641},[631,976,646],{"class":645},[631,978,782],{"class":645},[631,980,981],{"class":655}," id",[631,983,659],{"class":645},[631,985,768],{"class":641},[631,987,886],{"class":645},[631,989,990],{"class":655}," title",[631,992,734],{"class":645},[631,994,850],{"class":641},[631,996,886],{"class":645},[631,998,999],{"class":655}," description",[631,1001,734],{"class":645},[631,1003,850],{"class":641},[631,1005,886],{"class":645},[631,1007,1008],{"class":655}," showIf",[631,1010,734],{"class":645},[631,1012,1013],{"class":641}," Condition",[631,1015,886],{"class":645},[631,1017,1018],{"class":655}," fields",[631,1020,659],{"class":645},[631,1022,1023],{"class":641}," FormField",[631,1025,792],{"class":724},[631,1027,960],{"class":645},[631,1029,1031],{"class":633,"line":1030},24,[631,1032,967],{"emptyLinePlaceholder":966},[631,1034,1036,1038,1040,1042],{"class":633,"line":1035},25,[631,1037,638],{"class":637},[631,1039,1023],{"class":641},[631,1041,646],{"class":645},[631,1043,649],{"class":645},[631,1045,1047,1050,1052,1054],{"class":633,"line":1046},26,[631,1048,1049],{"class":655},"  key",[631,1051,659],{"class":645},[631,1053,768],{"class":641},[631,1055,1056],{"class":682}," \u002F\u002F unique across the form; the key of the answer\n",[631,1058,1060,1063,1065,1067,1070,1072,1074,1076,1079,1081,1083,1085,1088,1090,1092,1094,1097,1099,1101,1103,1106,1108,1110,1112,1115,1117,1119,1121,1124,1126,1128,1130,1133,1135,1137,1139,1142,1144,1146,1148,1151,1153,1155,1157,1160,1162,1164,1166,1169],{"class":633,"line":1059},27,[631,1061,1062],{"class":655},"  type",[631,1064,659],{"class":645},[631,1066,662],{"class":645},[631,1068,1069],{"class":665},"text",[631,1071,669],{"class":645},[631,1073,672],{"class":645},[631,1075,662],{"class":645},[631,1077,1078],{"class":665},"email",[631,1080,669],{"class":645},[631,1082,672],{"class":645},[631,1084,662],{"class":645},[631,1086,1087],{"class":665},"tel",[631,1089,669],{"class":645},[631,1091,672],{"class":645},[631,1093,662],{"class":645},[631,1095,1096],{"class":665},"number",[631,1098,669],{"class":645},[631,1100,672],{"class":645},[631,1102,662],{"class":645},[631,1104,1105],{"class":665},"textarea",[631,1107,669],{"class":645},[631,1109,672],{"class":645},[631,1111,662],{"class":645},[631,1113,1114],{"class":665},"select",[631,1116,669],{"class":645},[631,1118,672],{"class":645},[631,1120,662],{"class":645},[631,1122,1123],{"class":665},"radio",[631,1125,669],{"class":645},[631,1127,672],{"class":645},[631,1129,662],{"class":645},[631,1131,1132],{"class":665},"checkbox",[631,1134,669],{"class":645},[631,1136,672],{"class":645},[631,1138,662],{"class":645},[631,1140,1141],{"class":665},"date",[631,1143,669],{"class":645},[631,1145,672],{"class":645},[631,1147,662],{"class":645},[631,1149,1150],{"class":665},"file",[631,1152,669],{"class":645},[631,1154,672],{"class":645},[631,1156,662],{"class":645},[631,1158,1159],{"class":665},"markdown",[631,1161,669],{"class":645},[631,1163,672],{"class":645},[631,1165,662],{"class":645},[631,1167,1168],{"class":665},"captcha",[631,1170,1171],{"class":645},"'\n",[631,1173,1175,1178,1180],{"class":633,"line":1174},28,[631,1176,1177],{"class":655},"  label",[631,1179,734],{"class":645},[631,1181,747],{"class":641},[631,1183,1185,1188,1190],{"class":633,"line":1184},29,[631,1186,1187],{"class":655},"  description",[631,1189,734],{"class":645},[631,1191,747],{"class":641},[631,1193,1195,1198,1200],{"class":633,"line":1194},30,[631,1196,1197],{"class":655},"  placeholder",[631,1199,734],{"class":645},[631,1201,747],{"class":641},[631,1203,1205,1208,1210,1212],{"class":633,"line":1204},31,[631,1206,1207],{"class":655},"  content",[631,1209,734],{"class":645},[631,1211,850],{"class":641},[631,1213,1214],{"class":682}," \u002F\u002F markdown fields\n",[631,1216,1218,1221,1223],{"class":633,"line":1217},32,[631,1219,1220],{"class":655},"  required",[631,1222,734],{"class":645},[631,1224,1225],{"class":641}," boolean\n",[631,1227,1229,1232,1234,1236,1239,1241,1243,1245,1248,1250,1252,1254,1256],{"class":633,"line":1228},33,[631,1230,1231],{"class":655},"  options",[631,1233,734],{"class":645},[631,1235,782],{"class":645},[631,1237,1238],{"class":655}," value",[631,1240,659],{"class":645},[631,1242,768],{"class":641},[631,1244,886],{"class":645},[631,1246,1247],{"class":655}," label",[631,1249,659],{"class":645},[631,1251,850],{"class":641},[631,1253,913],{"class":645},[631,1255,792],{"class":724},[631,1257,1258],{"class":682},"\u002F\u002F select \u002F radio\n",[631,1260,1262,1265,1267,1270],{"class":633,"line":1261},34,[631,1263,1264],{"class":655},"  multiple",[631,1266,734],{"class":645},[631,1268,1269],{"class":641}," boolean",[631,1271,1272],{"class":682}," \u002F\u002F file fields\n",[631,1274,1276,1279,1281,1283],{"class":633,"line":1275},35,[631,1277,1278],{"class":655},"  autocomplete",[631,1280,734],{"class":645},[631,1282,768],{"class":641},[631,1284,1285],{"class":682}," \u002F\u002F defaults: 'email' for email, 'tel' for tel ('tel-national' next to a country selector)\n",[631,1287,1289,1292,1294,1296,1299,1302,1305,1307,1310,1312,1315,1317,1320,1322,1325,1327,1330,1332,1335,1337,1339,1341,1343,1346,1348,1350],{"class":633,"line":1288},36,[631,1290,1291],{"class":655},"  validation",[631,1293,734],{"class":645},[631,1295,782],{"class":645},[631,1297,1298],{"class":655}," min",[631,1300,1301],{"class":645},"?,",[631,1303,1304],{"class":655}," max",[631,1306,1301],{"class":645},[631,1308,1309],{"class":655}," minLength",[631,1311,1301],{"class":645},[631,1313,1314],{"class":655}," maxLength",[631,1316,1301],{"class":645},[631,1318,1319],{"class":655}," pattern",[631,1321,1301],{"class":645},[631,1323,1324],{"class":655}," maxFiles",[631,1326,1301],{"class":645},[631,1328,1329],{"class":655}," maxSize",[631,1331,1301],{"class":645},[631,1333,1334],{"class":655}," accept",[631,1336,734],{"class":645},[631,1338,768],{"class":641},[631,1340,907],{"class":724},[631,1342,886],{"class":645},[631,1344,1345],{"class":655}," message",[631,1347,734],{"class":645},[631,1349,850],{"class":641},[631,1351,1352],{"class":645}," }\n",[631,1354,1356,1359,1361,1364],{"class":633,"line":1355},37,[631,1357,1358],{"class":655},"  phone",[631,1360,734],{"class":645},[631,1362,1363],{"class":641}," PhoneConfig",[631,1365,1366],{"class":682}," \u002F\u002F tel fields\n",[631,1368,1370,1373,1375,1378],{"class":633,"line":1369},38,[631,1371,1372],{"class":655},"  captcha",[631,1374,734],{"class":645},[631,1376,1377],{"class":641}," CaptchaConfig",[631,1379,1380],{"class":682}," \u002F\u002F captcha fields\n",[631,1382,1384,1387,1389],{"class":633,"line":1383},39,[631,1385,1386],{"class":655},"  showIf",[631,1388,734],{"class":645},[631,1390,1391],{"class":641}," Condition\n",[631,1393,1395],{"class":633,"line":1394},40,[631,1396,960],{"class":645},[631,1398,1400],{"class":633,"line":1399},41,[631,1401,967],{"emptyLinePlaceholder":966},[631,1403,1405,1407,1409,1411,1413,1415,1417,1419,1421,1424,1426,1428,1431,1433,1435,1437,1440,1442,1444,1446,1449,1451,1453,1455,1458,1460,1462,1464,1467,1469,1471,1473,1476,1478,1480,1482,1484,1487],{"class":633,"line":1404},42,[631,1406,638],{"class":637},[631,1408,1013],{"class":641},[631,1410,646],{"class":645},[631,1412,782],{"class":645},[631,1414,879],{"class":655},[631,1416,659],{"class":645},[631,1418,768],{"class":641},[631,1420,886],{"class":645},[631,1422,1423],{"class":655}," op",[631,1425,659],{"class":645},[631,1427,662],{"class":645},[631,1429,1430],{"class":665},"eq",[631,1432,669],{"class":645},[631,1434,672],{"class":645},[631,1436,662],{"class":645},[631,1438,1439],{"class":665},"neq",[631,1441,669],{"class":645},[631,1443,672],{"class":645},[631,1445,662],{"class":645},[631,1447,1448],{"class":665},"in",[631,1450,669],{"class":645},[631,1452,672],{"class":645},[631,1454,662],{"class":645},[631,1456,1457],{"class":665},"empty",[631,1459,669],{"class":645},[631,1461,672],{"class":645},[631,1463,662],{"class":645},[631,1465,1466],{"class":665},"notEmpty",[631,1468,669],{"class":645},[631,1470,672],{"class":645},[631,1472,662],{"class":645},[631,1474,1475],{"class":665},"truthy",[631,1477,669],{"class":645},[631,1479,886],{"class":645},[631,1481,1238],{"class":655},[631,1483,734],{"class":645},[631,1485,1486],{"class":641}," unknown",[631,1488,1352],{"class":645},[631,1490,1492],{"class":633,"line":1491},43,[631,1493,967],{"emptyLinePlaceholder":966},[631,1495,1497,1499,1501,1503],{"class":633,"line":1496},44,[631,1498,638],{"class":637},[631,1500,951],{"class":641},[631,1502,646],{"class":645},[631,1504,649],{"class":645},[631,1506,1508,1511,1513,1515,1518,1520,1522,1524,1527,1529],{"class":633,"line":1507},45,[631,1509,1510],{"class":655},"  availability",[631,1512,659],{"class":645},[631,1514,662],{"class":645},[631,1516,1517],{"class":665},"web",[631,1519,669],{"class":645},[631,1521,672],{"class":645},[631,1523,662],{"class":645},[631,1525,1526],{"class":665},"api",[631,1528,669],{"class":645},[631,1530,1531],{"class":682}," \u002F\u002F 'api' = no public page\n",[631,1533,1535,1538,1540,1542,1544,1546,1548,1550,1553,1555,1557,1559,1562,1564,1566,1568,1571],{"class":633,"line":1534},46,[631,1536,1537],{"class":655},"  auth",[631,1539,659],{"class":645},[631,1541,662],{"class":645},[631,1543,705],{"class":665},[631,1545,669],{"class":645},[631,1547,672],{"class":645},[631,1549,662],{"class":645},[631,1551,1552],{"class":665},"user",[631,1554,669],{"class":645},[631,1556,672],{"class":645},[631,1558,662],{"class":645},[631,1560,1561],{"class":665},"token",[631,1563,669],{"class":645},[631,1565,672],{"class":645},[631,1567,662],{"class":645},[631,1569,1570],{"class":665},"password",[631,1572,1171],{"class":645},[631,1574,1576,1579,1581,1584],{"class":633,"line":1575},47,[631,1577,1578],{"class":655},"  schedule",[631,1580,734],{"class":645},[631,1582,1583],{"class":641}," Schedule",[631,1585,1586],{"class":682}," \u002F\u002F default always open; see Open period\n",[631,1588,1590],{"class":633,"line":1589},48,[631,1591,960],{"class":645},[594,1593,1594,1597,1598,1601,1602,1605],{},[613,1595,1596],{},"Translated"," is a string or a ",[613,1599,1600],{},"{ da, en }"," map. It falls back to ",[613,1603,1604],{},"en",", then to the first value.",[594,1607,1608,1611,1612,1615],{},[613,1609,1610],{},"storage: 'none'"," never stores the answers. They only reach the ",[613,1613,1614],{},"forms:submitted"," hook and the email.",[602,1617,1619],{"id":1618},"rules-a-definition-must-follow","Rules a definition must follow",[594,1621,1622],{},"The module checks these rules when a definition is saved or seeded.",[1624,1625,1626,1666,1672,1678,1704,1720,1733],"ul",{},[1627,1628,1629,1633,1634,1637,1638,1641,1642,1645,1646,1648,1649,1651,1652,1654,1655,1657,1658,1648,1660,1662,1663,1665],"li",{},[1630,1631,1632],"strong",{},"Conditions."," ",[613,1635,1636],{},"showIf"," sees only the answers of input fields ",[1630,1639,1640],{},"earlier"," in the form. ",[613,1643,1644],{},"value"," is the compared value\nfor ",[613,1647,1430],{}," and ",[613,1650,1439],{},", and a list for ",[613,1653,1448],{},". ",[613,1656,1457],{},", ",[613,1659,1466],{},[613,1661,1475],{}," (an alias of ",[613,1664,1466],{},") ignore it.",[1627,1667,1668,1671],{},[1630,1669,1670],{},"Hidden fields."," A hidden field is not required, its answer is dropped, and a stale answer never keeps another\nfield shown.",[1627,1673,1674,1677],{},[1630,1675,1676],{},"Keys."," Field keys start with a letter and contain letters, digits and underscores. Keys and step ids are unique.",[1627,1679,1680,1633,1683,1648,1685,1687,1688,1690,1691,1694,1695,1697,1698,1654,1701,1703],{},[1630,1681,1682],{},"Fields.",[613,1684,1114],{},[613,1686,1123],{}," need options. ",[613,1689,1159],{}," needs ",[613,1692,1693],{},"content"," and collects no answer. ",[613,1696,1150],{}," needs\n",[613,1699,1700],{},"storage: 'db'",[613,1702,1168],{}," is always required while visible.",[1627,1705,1706,1633,1709,1712,1713,1716,1717,600],{},[1630,1707,1708],{},"Files.",[613,1710,1711],{},"maxSize"," defaults to 10 MB, and ",[613,1714,1715],{},"maxFiles"," to 10, or 1 without ",[613,1718,1719],{},"multiple",[1627,1721,1722,1633,1725,1728,1729,1732],{},[1630,1723,1724],{},"Access.",[613,1726,1727],{},"auth: 'token'"," requires ",[613,1730,1731],{},"availability: 'api'",", because nobody can type a token into a page.",[1627,1734,1735,1633,1738,1741,1742,1745,1746,1748],{},[1630,1736,1737],{},"Email.",[613,1739,1740],{},"routes.field"," must be an earlier input field, and ",[613,1743,1744],{},"replyToField"," an ",[613,1747,1078],{}," field.",[602,1750,1752],{"id":1751},"phone-fields","Phone fields",[594,1754,1755,1756,1758,1759,1762],{},"A ",[613,1757,1087],{}," field is one free-form input by default. ",[613,1760,1761],{},"phone.mode: 'country'"," adds a searchable country selector.",[622,1764,1766],{"className":624,"code":1765,"language":626,"meta":627,"style":627},"type PhoneConfig = {\n  mode?: 'simple' | 'country' \u002F\u002F default 'simple'\n  countries?: string[] \u002F\u002F ISO 3166-1 alpha-2, in display order; default all. Enforced on the server.\n  defaultCountry?: string \u002F\u002F default 'DK' when offered, else the first offered country\n}\n\n{ key: 'phone', type: 'tel', phone: { mode: 'country', countries: ['DK', 'SE', 'NO'], defaultCountry: 'DK' } }\n",[613,1767,1768,1778,1803,1817,1829,1833,1837],{"__ignoreMap":627},[631,1769,1770,1772,1774,1776],{"class":633,"line":634},[631,1771,638],{"class":637},[631,1773,1363],{"class":641},[631,1775,646],{"class":645},[631,1777,649],{"class":645},[631,1779,1780,1782,1784,1786,1789,1791,1793,1795,1798,1800],{"class":633,"line":652},[631,1781,656],{"class":655},[631,1783,734],{"class":645},[631,1785,662],{"class":645},[631,1787,1788],{"class":665},"simple",[631,1790,669],{"class":645},[631,1792,672],{"class":645},[631,1794,662],{"class":645},[631,1796,1797],{"class":665},"country",[631,1799,669],{"class":645},[631,1801,1802],{"class":682}," \u002F\u002F default 'simple'\n",[631,1804,1805,1808,1810,1812,1814],{"class":633,"line":686},[631,1806,1807],{"class":655},"  countries",[631,1809,734],{"class":645},[631,1811,768],{"class":641},[631,1813,792],{"class":724},[631,1815,1816],{"class":682},"\u002F\u002F ISO 3166-1 alpha-2, in display order; default all. Enforced on the server.\n",[631,1818,1819,1822,1824,1826],{"class":633,"line":713},[631,1820,1821],{"class":655},"  defaultCountry",[631,1823,734],{"class":645},[631,1825,768],{"class":641},[631,1827,1828],{"class":682}," \u002F\u002F default 'DK' when offered, else the first offered country\n",[631,1830,1831],{"class":633,"line":728},[631,1832,960],{"class":645},[631,1834,1835],{"class":633,"line":739},[631,1836,967],{"emptyLinePlaceholder":966},[631,1838,1839,1842,1845,1847,1849,1852,1854,1856,1859,1861,1863,1865,1867,1869,1872,1874,1876,1879,1881,1883,1885,1887,1889,1892,1894,1897,1899,1902,1904,1906,1908,1911,1913,1915,1917,1920,1922,1925,1927,1930,1932,1934,1936,1938,1940],{"class":633,"line":750},[631,1840,1841],{"class":645},"{",[631,1843,1844],{"class":655}," key",[631,1846,659],{"class":645},[631,1848,662],{"class":645},[631,1850,1851],{"class":665},"phone",[631,1853,669],{"class":645},[631,1855,886],{"class":645},[631,1857,1858],{"class":655}," type",[631,1860,659],{"class":645},[631,1862,662],{"class":645},[631,1864,1087],{"class":665},[631,1866,669],{"class":645},[631,1868,886],{"class":645},[631,1870,1871],{"class":655}," phone",[631,1873,659],{"class":645},[631,1875,782],{"class":645},[631,1877,1878],{"class":655}," mode",[631,1880,659],{"class":645},[631,1882,662],{"class":645},[631,1884,1797],{"class":665},[631,1886,669],{"class":645},[631,1888,886],{"class":645},[631,1890,1891],{"class":655}," countries",[631,1893,659],{"class":645},[631,1895,1896],{"class":724}," [",[631,1898,669],{"class":645},[631,1900,1901],{"class":665},"DK",[631,1903,669],{"class":645},[631,1905,886],{"class":645},[631,1907,662],{"class":645},[631,1909,1910],{"class":665},"SE",[631,1912,669],{"class":645},[631,1914,886],{"class":645},[631,1916,662],{"class":645},[631,1918,1919],{"class":665},"NO",[631,1921,669],{"class":645},[631,1923,1924],{"class":724},"]",[631,1926,886],{"class":645},[631,1928,1929],{"class":655}," defaultCountry",[631,1931,659],{"class":645},[631,1933,662],{"class":645},[631,1935,1901],{"class":665},[631,1937,669],{"class":645},[631,1939,913],{"class":645},[631,1941,1352],{"class":645},[1624,1943,1944,1958,1968,1974],{},[1627,1945,1946,1949,1950,1953,1954,1957],{},[1630,1947,1948],{},"One string."," With a selector, the answer is ",[613,1951,1952],{},"+\u003Cdial code>\u003Cnumber>",", such as ",[613,1955,1956],{},"+4512345678",". So submissions, emails\nand the API never see two values.",[1627,1959,1960,1963,1964,1967],{},[1630,1961,1962],{},"Trunk prefix."," A leading ",[613,1965,1966],{},"0"," is dropped. Italian numbers keep it.",[1627,1969,1970,1973],{},[1630,1971,1972],{},"Length."," Country mode needs an international (E.164) number of at most 15 digits, with at least 4 after the code.",[1627,1975,1976,1633,1979,1981,1982,1657,1985,1657,1988,1991,1992,600],{},[1630,1977,1978],{},"Helpers.",[613,1980,619],{}," exports ",[613,1983,1984],{},"composePhone",[613,1986,1987],{},"parsePhone",[613,1989,1990],{},"phoneCountries"," and\n",[613,1993,1994],{},"allPhoneCountries",[602,1996,1998],{"id":1997},"open-period","Open period",[594,2000,2001,2004,2005,2008,2009,2012],{},[613,2002,2003],{},"access.schedule"," limits when a form accepts answers, such as a sign-up season. ",[613,2006,2007],{},"from"," is inclusive and ",[613,2010,2011],{},"to"," exclusive.\nA yearly period whose end is before its start wraps over new year.",[622,2014,2016],{"className":624,"code":2015,"language":626,"meta":627,"style":627},"\u002F\u002F Every year from 1 Jan 23:00 to 1 Feb 23:00 (Oslo wall-clock time).\naccess: {\n  availability: 'web',\n  auth: 'none',\n  schedule: {\n    type: 'yearly',\n    timezone: 'Europe\u002FOslo',\n    from: { month: 1, day: 1, time: '23:00' },\n    to: { month: 2, day: 1, time: '23:00' },\n  },\n}\n\n\u002F\u002F One fixed period (either end may be left out for an open-ended window).\nschedule: { type: 'range', from: '2026-03-01T10:00:00Z', to: '2026-03-15T10:00:00Z' }\n",[613,2017,2018,2023,2032,2047,2061,2069,2085,2101,2145,2183,2188,2192,2196,2201],{"__ignoreMap":627},[631,2019,2020],{"class":633,"line":634},[631,2021,2022],{"class":682},"\u002F\u002F Every year from 1 Jan 23:00 to 1 Feb 23:00 (Oslo wall-clock time).\n",[631,2024,2025,2028,2030],{"class":633,"line":652},[631,2026,2027],{"class":641},"access",[631,2029,659],{"class":645},[631,2031,649],{"class":645},[631,2033,2034,2036,2038,2040,2042,2044],{"class":633,"line":686},[631,2035,1510],{"class":641},[631,2037,659],{"class":645},[631,2039,662],{"class":645},[631,2041,1517],{"class":665},[631,2043,669],{"class":645},[631,2045,2046],{"class":645},",\n",[631,2048,2049,2051,2053,2055,2057,2059],{"class":633,"line":713},[631,2050,1537],{"class":641},[631,2052,659],{"class":645},[631,2054,662],{"class":645},[631,2056,705],{"class":665},[631,2058,669],{"class":645},[631,2060,2046],{"class":645},[631,2062,2063,2065,2067],{"class":633,"line":728},[631,2064,1578],{"class":641},[631,2066,659],{"class":645},[631,2068,649],{"class":645},[631,2070,2071,2074,2076,2078,2081,2083],{"class":633,"line":739},[631,2072,2073],{"class":641},"    type",[631,2075,659],{"class":645},[631,2077,662],{"class":645},[631,2079,2080],{"class":665},"yearly",[631,2082,669],{"class":645},[631,2084,2046],{"class":645},[631,2086,2087,2090,2092,2094,2097,2099],{"class":633,"line":750},[631,2088,2089],{"class":641},"    timezone",[631,2091,659],{"class":645},[631,2093,662],{"class":645},[631,2095,2096],{"class":665},"Europe\u002FOslo",[631,2098,669],{"class":645},[631,2100,2046],{"class":645},[631,2102,2103,2106,2108,2110,2113,2115,2119,2121,2124,2126,2128,2130,2133,2135,2137,2140,2142],{"class":633,"line":760},[631,2104,2105],{"class":641},"    from",[631,2107,659],{"class":645},[631,2109,782],{"class":645},[631,2111,2112],{"class":641}," month",[631,2114,659],{"class":645},[631,2116,2118],{"class":2117},"sbssI"," 1",[631,2120,886],{"class":645},[631,2122,2123],{"class":641}," day",[631,2125,659],{"class":645},[631,2127,2118],{"class":2117},[631,2129,886],{"class":645},[631,2131,2132],{"class":641}," time",[631,2134,659],{"class":645},[631,2136,662],{"class":645},[631,2138,2139],{"class":665},"23:00",[631,2141,669],{"class":645},[631,2143,2144],{"class":645}," },\n",[631,2146,2147,2150,2152,2154,2156,2158,2161,2163,2165,2167,2169,2171,2173,2175,2177,2179,2181],{"class":633,"line":774},[631,2148,2149],{"class":641},"    to",[631,2151,659],{"class":645},[631,2153,782],{"class":645},[631,2155,2112],{"class":641},[631,2157,659],{"class":645},[631,2159,2160],{"class":2117}," 2",[631,2162,886],{"class":645},[631,2164,2123],{"class":641},[631,2166,659],{"class":645},[631,2168,2118],{"class":2117},[631,2170,886],{"class":645},[631,2172,2132],{"class":641},[631,2174,659],{"class":645},[631,2176,662],{"class":645},[631,2178,2139],{"class":665},[631,2180,669],{"class":645},[631,2182,2144],{"class":645},[631,2184,2185],{"class":633,"line":801},[631,2186,2187],{"class":645},"  },\n",[631,2189,2190],{"class":633,"line":807},[631,2191,960],{"class":645},[631,2193,2194],{"class":633,"line":817},[631,2195,967],{"emptyLinePlaceholder":966},[631,2197,2198],{"class":633,"line":827},[631,2199,2200],{"class":682},"\u002F\u002F One fixed period (either end may be left out for an open-ended window).\n",[631,2202,2203,2206,2208,2210,2212,2214,2216,2219,2221,2223,2226,2228,2230,2233,2235,2237,2239,2241,2243,2246,2248],{"class":633,"line":842},[631,2204,2205],{"class":641},"schedule",[631,2207,659],{"class":645},[631,2209,782],{"class":645},[631,2211,1858],{"class":641},[631,2213,659],{"class":645},[631,2215,662],{"class":645},[631,2217,2218],{"class":665},"range",[631,2220,669],{"class":645},[631,2222,886],{"class":645},[631,2224,2225],{"class":641}," from",[631,2227,659],{"class":645},[631,2229,662],{"class":645},[631,2231,2232],{"class":665},"2026-03-01T10:00:00Z",[631,2234,669],{"class":645},[631,2236,886],{"class":645},[631,2238,889],{"class":641},[631,2240,659],{"class":645},[631,2242,662],{"class":645},[631,2244,2245],{"class":665},"2026-03-15T10:00:00Z",[631,2247,669],{"class":645},[631,2249,1352],{"class":645},[594,2251,2252,2253,2256,2257,2260,2261,2263,2264,1648,2267,600],{},"Outside the period, the public page shows a \"closed\" notice with the next opening, if there is one. The definition and\nsubmit routes answer ",[613,2254,2255],{},"403"," with ",[613,2258,2259],{},"data: { closed: true, opensAt }",". For your own interface, ",[613,2262,619],{},"\nexports ",[613,2265,2266],{},"isFormOpen",[613,2268,2269],{},"nextFormOpening",[602,2271,2273],{"id":2272},"email-body-and-variables","Email body and variables",[594,2275,2276,2277,2280,2281,1654,2283,2286],{},"Without ",[613,2278,2279],{},"delivery.email.body",", the email lists every visible answer. The body is picked by the submission's locale,\nthen ",[613,2282,1604],{},[613,2284,2285],{},"subject"," takes the same variables.",[622,2288,2290],{"className":624,"code":2289,"language":626,"meta":627,"style":627},"delivery: {\n  email: {\n    to: ['office@example.com'],\n    subject: 'New message from {{ answer.name }}',\n    body: { en: 'Hi team,\\n\\n{{answer.name}} wrote via {{form.name}}:\\n{{answer.message}}\\n\\nAll answers:\\n{{answers}}' },\n  },\n}\n",[613,2291,2292,2301,2310,2329,2345,2390,2394],{"__ignoreMap":627},[631,2293,2294,2297,2299],{"class":633,"line":634},[631,2295,2296],{"class":641},"delivery",[631,2298,659],{"class":645},[631,2300,649],{"class":645},[631,2302,2303,2306,2308],{"class":633,"line":652},[631,2304,2305],{"class":641},"  email",[631,2307,659],{"class":645},[631,2309,649],{"class":645},[631,2311,2312,2314,2316,2318,2320,2323,2325,2327],{"class":633,"line":686},[631,2313,2149],{"class":641},[631,2315,659],{"class":645},[631,2317,1896],{"class":655},[631,2319,669],{"class":645},[631,2321,2322],{"class":665},"office@example.com",[631,2324,669],{"class":645},[631,2326,1924],{"class":655},[631,2328,2046],{"class":645},[631,2330,2331,2334,2336,2338,2341,2343],{"class":633,"line":713},[631,2332,2333],{"class":641},"    subject",[631,2335,659],{"class":645},[631,2337,662],{"class":645},[631,2339,2340],{"class":665},"New message from {{ answer.name }}",[631,2342,669],{"class":645},[631,2344,2046],{"class":645},[631,2346,2347,2350,2352,2354,2357,2359,2361,2364,2367,2370,2373,2376,2378,2381,2383,2386,2388],{"class":633,"line":728},[631,2348,2349],{"class":641},"    body",[631,2351,659],{"class":645},[631,2353,782],{"class":645},[631,2355,2356],{"class":641}," en",[631,2358,659],{"class":645},[631,2360,662],{"class":645},[631,2362,2363],{"class":665},"Hi team,",[631,2365,2366],{"class":724},"\\n\\n",[631,2368,2369],{"class":665},"{{answer.name}} wrote via {{form.name}}:",[631,2371,2372],{"class":724},"\\n",[631,2374,2375],{"class":665},"{{answer.message}}",[631,2377,2366],{"class":724},[631,2379,2380],{"class":665},"All answers:",[631,2382,2372],{"class":724},[631,2384,2385],{"class":665},"{{answers}}",[631,2387,669],{"class":645},[631,2389,2144],{"class":645},[631,2391,2392],{"class":633,"line":739},[631,2393,2187],{"class":645},[631,2395,2396],{"class":633,"line":750},[631,2397,960],{"class":645},[2399,2400,2401,2414],"table",{},[2402,2403,2404],"thead",{},[2405,2406,2407,2411],"tr",{},[2408,2409,2410],"th",{},"Variable",[2408,2412,2413],{},"Replaced with",[2415,2416,2417,2434,2446,2459,2472,2482,2492],"tbody",{},[2405,2418,2419,2431],{},[2420,2421,2422,1657,2425,1657,2428],"td",{},[613,2423,2424],{},"{{form.name}}",[613,2426,2427],{},"{{form.slug}}",[613,2429,2430],{},"{{form.version}}",[2420,2432,2433],{},"The form's name, slug and version.",[2405,2435,2436,2441],{},[2420,2437,2438],{},[613,2439,2440],{},"{{submission.id}}",[2420,2442,2443,2444,600],{},"The stored submission id. Empty when ",[613,2445,1610],{},[2405,2447,2448,2456],{},[2420,2449,2450,1657,2453],{},[613,2451,2452],{},"{{submission.createdAt}}",[613,2454,2455],{},"{{submission.locale}}",[2420,2457,2458],{},"The ISO timestamp and locale of the submission.",[2405,2460,2461,2465],{},[2420,2462,2463],{},[613,2464,2385],{},[2420,2466,2467,2468,2471],{},"Every visible answer except captcha, as ",[613,2469,2470],{},"label: value"," lines. The HTML version is a table.",[2405,2473,2474,2479],{},[2420,2475,2476],{},[613,2477,2478],{},"{{answer.\u003CfieldKey>}}",[2420,2480,2481],{},"One answer, formatted as in the default email: option labels, joined lists, file names, yes or no.",[2405,2483,2484,2489],{},[2420,2485,2486],{},[613,2487,2488],{},"{{files}}",[2420,2490,2491],{},"The names of the files stored with the submission.",[2405,2493,2494,2499],{},[2420,2495,2496],{},[613,2497,2498],{},"{{replyTo}}",[2420,2500,2501,2502,600],{},"The reply-to address from ",[613,2503,1744],{},[1624,2505,2506,2512,2522,2531,2541],{},[1627,2507,2508,2511],{},[1630,2509,2510],{},"Empty values."," Unknown variables, hidden fields and unanswered fields render empty. Spaces inside the braces are\nignored.",[1627,2513,2514,2517,2518,2521],{},[1630,2515,2516],{},"Unknown variables."," The builder warns about them (",[613,2519,2520],{},"unknownBodyVariables","), but never blocks the save.",[1627,2523,2524,2527,2528,2530],{},[1630,2525,2526],{},"No re-scan."," A value is inserted once, so an answer that contains ",[613,2529,2424],{}," stays literal.",[1627,2532,2533,2536,2537,2540],{},[1630,2534,2535],{},"Escaping."," The body is plain text. The HTML version escapes every value and turns newlines into ",[613,2538,2539],{},"\u003Cbr>",". The subject\ncollapses line breaks, so an answer cannot add email headers.",[1627,2542,2543,1633,2546,1657,2549,1648,2552,2555,2556,2558],{},[1630,2544,2545],{},"Preview.",[613,2547,2548],{},"composeEmail",[613,2550,2551],{},"renderTemplateText",[613,2553,2554],{},"renderTemplateHtml"," in ",[613,2557,619],{}," render the\nemail, so the builder previews the exact result.",[602,2560,2561],{"id":1168},"Captcha",[594,2563,1755,2564,2566],{},[613,2565,1168],{}," field renders Cloudflare Turnstile, Google reCAPTCHA v2 (checkbox) or hCaptcha.",[622,2568,2570],{"className":624,"code":2569,"language":626,"meta":627,"style":627},"type CaptchaConfig = {\n  provider?: 'turnstile' | 'recaptcha' | 'hcaptcha' \u002F\u002F default: captcha.defaultProvider\n  siteKey?: string \u002F\u002F public; overrides the configured site key for this field\n  theme?: 'auto' | 'light' | 'dark'\n  size?: 'normal' | 'compact'\n}\n\n{ key: 'human', type: 'captcha', captcha: { provider: 'turnstile' } }\n",[613,2571,2572,2582,2617,2629,2661,2684,2688,2692],{"__ignoreMap":627},[631,2573,2574,2576,2578,2580],{"class":633,"line":634},[631,2575,638],{"class":637},[631,2577,1377],{"class":641},[631,2579,646],{"class":645},[631,2581,649],{"class":645},[631,2583,2584,2587,2589,2591,2594,2596,2598,2600,2603,2605,2607,2609,2612,2614],{"class":633,"line":652},[631,2585,2586],{"class":655},"  provider",[631,2588,734],{"class":645},[631,2590,662],{"class":645},[631,2592,2593],{"class":665},"turnstile",[631,2595,669],{"class":645},[631,2597,672],{"class":645},[631,2599,662],{"class":645},[631,2601,2602],{"class":665},"recaptcha",[631,2604,669],{"class":645},[631,2606,672],{"class":645},[631,2608,662],{"class":645},[631,2610,2611],{"class":665},"hcaptcha",[631,2613,669],{"class":645},[631,2615,2616],{"class":682}," \u002F\u002F default: captcha.defaultProvider\n",[631,2618,2619,2622,2624,2626],{"class":633,"line":686},[631,2620,2621],{"class":655},"  siteKey",[631,2623,734],{"class":645},[631,2625,768],{"class":641},[631,2627,2628],{"class":682}," \u002F\u002F public; overrides the configured site key for this field\n",[631,2630,2631,2634,2636,2638,2641,2643,2645,2647,2650,2652,2654,2656,2659],{"class":633,"line":713},[631,2632,2633],{"class":655},"  theme",[631,2635,734],{"class":645},[631,2637,662],{"class":645},[631,2639,2640],{"class":665},"auto",[631,2642,669],{"class":645},[631,2644,672],{"class":645},[631,2646,662],{"class":645},[631,2648,2649],{"class":665},"light",[631,2651,669],{"class":645},[631,2653,672],{"class":645},[631,2655,662],{"class":645},[631,2657,2658],{"class":665},"dark",[631,2660,1171],{"class":645},[631,2662,2663,2666,2668,2670,2673,2675,2677,2679,2682],{"class":633,"line":728},[631,2664,2665],{"class":655},"  size",[631,2667,734],{"class":645},[631,2669,662],{"class":645},[631,2671,2672],{"class":665},"normal",[631,2674,669],{"class":645},[631,2676,672],{"class":645},[631,2678,662],{"class":645},[631,2680,2681],{"class":665},"compact",[631,2683,1171],{"class":645},[631,2685,2686],{"class":633,"line":739},[631,2687,960],{"class":645},[631,2689,2690],{"class":633,"line":750},[631,2691,967],{"emptyLinePlaceholder":966},[631,2693,2694,2696,2698,2700,2702,2705,2707,2709,2711,2713,2715,2717,2719,2721,2724,2726,2728,2731,2733,2735,2737,2739,2741],{"class":633,"line":760},[631,2695,1841],{"class":645},[631,2697,1844],{"class":655},[631,2699,659],{"class":645},[631,2701,662],{"class":645},[631,2703,2704],{"class":665},"human",[631,2706,669],{"class":645},[631,2708,886],{"class":645},[631,2710,1858],{"class":655},[631,2712,659],{"class":645},[631,2714,662],{"class":645},[631,2716,1168],{"class":665},[631,2718,669],{"class":645},[631,2720,886],{"class":645},[631,2722,2723],{"class":655}," captcha",[631,2725,659],{"class":645},[631,2727,782],{"class":645},[631,2729,2730],{"class":655}," provider",[631,2732,659],{"class":645},[631,2734,662],{"class":645},[631,2736,2593],{"class":665},[631,2738,669],{"class":645},[631,2740,913],{"class":645},[631,2742,1352],{"class":645},[1624,2744,2745,2755,2766,2772,2778],{},[1627,2746,2747,2750,2751,2754],{},[1630,2748,2749],{},"Site key."," The field's ",[613,2752,2753],{},"siteKey",", else the configured one. The builder warns when neither exists.",[1627,2756,2757,2760,2761,2765],{},[1630,2758,2759],{},"Secret key."," The form's own ",[598,2762,2764],{"href":2763},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Fserver#per-form-secrets","encrypted secret",", else the\nconfigured one. With neither, the check fails closed.",[1627,2767,2768,2771],{},[1630,2769,2770],{},"Browser."," The provider script loads lazily. The widget resets after every failed submit. In the admin preview the\nfield is a stub that supplies a dummy token.",[1627,2773,2774,2777],{},[1630,2775,2776],{},"Server."," The server verifies the token, with the visitor's IP, before anything is stored or delivered.",[1627,2779,2780,2783,2784,2787],{},[1630,2781,2782],{},"Form access tokens."," A submission with a valid form access token (",[613,2785,2786],{},"access.auth: 'token'",") skips the captcha.",[2789,2790,2791],"note",{},"The captcha token stays in the form state. It is never stored, delivered or shown in the preview JSON.",[2399,2793,2794,2804],{},[2402,2795,2796],{},[2405,2797,2798,2801],{},[2408,2799,2800],{},"Outcome",[2408,2802,2803],{},"Status",[2415,2805,2806,2820,2830],{},[2405,2807,2808,2811],{},[2420,2809,2810],{},"Token missing or invalid",[2420,2812,2813,2816,2817],{},[613,2814,2815],{},"400",", with an issue on the captcha field key in ",[613,2818,2819],{},"data.issues",[2405,2821,2822,2825],{},[2420,2823,2824],{},"No secret key for the provider",[2420,2826,2827],{},[613,2828,2829],{},"500",[2405,2831,2832,2835],{},[2420,2833,2834],{},"Provider unreachable",[2420,2836,2837],{},[613,2838,2839],{},"502",[594,2841,2842,2843,2849],{},"To replace the network call, in your app or in tests, answer the\n",[598,2844,2846],{"href":2845},"\u002Fmodules\u002Ffeatures\u002Fforms\u002Freference#hooks",[613,2847,2848],{},"forms:captcha:verify"," hook.",[602,2851,2853],{"id":2852},"visual-builder","Visual builder",[594,2855,2856,2857,2860,2861,1657,2864,2046,2867,1648,2870,2873,2874,2877],{},"The builder at ",[613,2858,2859],{},"\u002Fadmin\u002Fforms\u002F:id"," edits the same definition without code. Its ",[1630,2862,2863],{},"Builder",[1630,2865,2866],{},"Delivery & storage",[1630,2868,2869],{},"Access",[1630,2871,2872],{},"JSON"," tabs all change one unsaved copy. ",[1630,2875,2876],{},"Save form"," works only while the definition is valid.",[1624,2879,2880,2890],{},[1627,2881,2882,2884,2885,2889],{},[1630,2883,1682],{}," Drag a field type from the palette, or click it. Reorder fields and steps by dragging or with the arrows.\nSwitching to ",[2886,2887,2888],"em",{},"Single page"," merges all steps.",[1627,2891,2892,2895],{},[1630,2893,2894],{},"Languages."," Every text has a language button. Translating gives one row per locale of your app, plus any code you\nadd. Empty languages are dropped.",[602,2897,2899],{"id":2898},"next-steps","Next steps",[1624,2901,2902,2907,2914],{},[1627,2903,2904,2906],{},[598,2905,495],{"href":496}," – write a definition in code and seed it.",[1627,2908,2909,2911,2912,600],{},[598,2910,175],{"href":304}," – the access modes, form access tokens and passwords behind ",[613,2913,2027],{},[1627,2915,2916,2918,2919,2921],{},[598,2917,179],{"href":310}," – the ",[613,2920,1614],{}," hook that receives every answer.",[2923,2924,2925],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":627,"searchDepth":652,"depth":652,"links":2927},[2928,2929,2930,2931,2932,2933,2934,2935],{"id":604,"depth":652,"text":605},{"id":1618,"depth":652,"text":1619},{"id":1751,"depth":652,"text":1752},{"id":1997,"depth":652,"text":1998},{"id":2272,"depth":652,"text":2273},{"id":1168,"depth":652,"text":2561},{"id":2852,"depth":652,"text":2853},{"id":2898,"depth":652,"text":2899},"What a form is made of, from fields and conditions to open periods, the email it sends and captcha.","md",null,{},{"title":300},{"title":589,"description":2936},"QixRQmEEpd5Y-ty3Bte48vM3XwBNGOtUI4oH27Xz6CE",[2944,2946],{"title":173,"path":295,"stem":296,"description":2945,"children":-1},"Publish forms your staff edit without a deploy, and store, email or forward every submission.",{"title":175,"path":304,"stem":305,"description":2947,"children":-1},"Submit forms from code, choose who may answer them, and seed forms, keep their secrets and give staff access.",1794503158504]