[{"data":1,"prerenderedAt":982},["ShallowReactive",2],{"content-\u002Fdocs\u002Fquickstart":3},{"id":4,"title":5,"body":6,"description":16,"extension":976,"meta":977,"navigation":175,"path":978,"seo":979,"stem":980,"__hash__":981},"docs\u002Fdocs\u002Fquickstart.md","Quick start",{"type":7,"value":8,"toc":967},"minimark",[9,13,17,22,26,41,45,50,57,105,116,120,212,293,306,310,775,778,814,822,826,963],[10,11,5],"h1",{"id":12},"quick-start",[14,15,16],"p",{},"Get a working Attaform form on screen in under five minutes. The\nmainline path is Nuxt — bare-Vue + Vite is one section down.",[18,19,21],"h2",{"id":20},"_1-install","1. Install",[23,24],"ui-install-command",{":show-quick-start":25},"false",[14,27,28,32,33,40],{},[29,30,31],"code",{},"zod"," is a peer dependency. Requires Vue 3 and Zod 4 — for Zod v3,\nswap the import for ",[34,35,37],"a",{"href":36},"\u002Fdocs\u002Fapi\u002Fzod-v3",[29,38,39],{},"attaform\u002Fzod-v3"," (same\nsurface, separate adapter).",[18,42,44],{"id":43},"_2-wire-it-up","2. Wire it up",[46,47,49],"h3",{"id":48},"nuxt-3-4","Nuxt 3 \u002F 4",[14,51,52,53,56],{},"Add the module to ",[29,54,55],{},"nuxt.config.ts",":",[58,59,64],"pre",{"className":60,"code":61,"language":62,"meta":63,"style":63},"language-ts shiki shiki-themes github-light github-dark","export default defineNuxtConfig({\n  modules: ['attaform\u002Fnuxt'],\n})\n","ts","",[29,65,66,86,99],{"__ignoreMap":63},[67,68,71,75,78,82],"span",{"class":69,"line":70},"line",1,[67,72,74],{"class":73},"szBVR","export",[67,76,77],{"class":73}," default",[67,79,81],{"class":80},"sScJk"," defineNuxtConfig",[67,83,85],{"class":84},"sVt8B","({\n",[67,87,89,92,96],{"class":69,"line":88},2,[67,90,91],{"class":84},"  modules: [",[67,93,95],{"class":94},"sZZnC","'attaform\u002Fnuxt'",[67,97,98],{"class":84},"],\n",[67,100,102],{"class":69,"line":101},3,[67,103,104],{"class":84},"})\n",[14,106,107,108,111,112,115],{},"That's everything. The module installs the plugin, registers the\n",[29,109,110],{},"v-register"," directive, and auto-imports ",[29,113,114],{},"useForm"," so you can call\nit without an explicit import.",[46,117,119],{"id":118},"bare-vue-vite","Bare Vue + Vite",[58,121,123],{"className":60,"code":122,"language":62,"meta":63,"style":63},"\u002F\u002F vite.config.ts\nimport { defineConfig } from 'vite'\nimport vue from '@vitejs\u002Fplugin-vue'\nimport { attaform } from 'attaform\u002Fvite'\n\nexport default defineConfig({\n  plugins: [vue(), attaform()],\n})\n",[29,124,125,131,145,157,170,177,189,207],{"__ignoreMap":63},[67,126,127],{"class":69,"line":70},[67,128,130],{"class":129},"sJ8bj","\u002F\u002F vite.config.ts\n",[67,132,133,136,139,142],{"class":69,"line":88},[67,134,135],{"class":73},"import",[67,137,138],{"class":84}," { defineConfig } ",[67,140,141],{"class":73},"from",[67,143,144],{"class":94}," 'vite'\n",[67,146,147,149,152,154],{"class":69,"line":101},[67,148,135],{"class":73},[67,150,151],{"class":84}," vue ",[67,153,141],{"class":73},[67,155,156],{"class":94}," '@vitejs\u002Fplugin-vue'\n",[67,158,160,162,165,167],{"class":69,"line":159},4,[67,161,135],{"class":73},[67,163,164],{"class":84}," { attaform } ",[67,166,141],{"class":73},[67,168,169],{"class":94}," 'attaform\u002Fvite'\n",[67,171,173],{"class":69,"line":172},5,[67,174,176],{"emptyLinePlaceholder":175},true,"\n",[67,178,180,182,184,187],{"class":69,"line":179},6,[67,181,74],{"class":73},[67,183,77],{"class":73},[67,185,186],{"class":80}," defineConfig",[67,188,85],{"class":84},[67,190,192,195,198,201,204],{"class":69,"line":191},7,[67,193,194],{"class":84},"  plugins: [",[67,196,197],{"class":80},"vue",[67,199,200],{"class":84},"(), ",[67,202,203],{"class":80},"attaform",[67,205,206],{"class":84},"()],\n",[67,208,210],{"class":69,"line":209},8,[67,211,104],{"class":84},[58,213,215],{"className":60,"code":214,"language":62,"meta":63,"style":63},"\u002F\u002F main.ts\nimport { createApp } from 'vue'\nimport { createAttaform } from 'attaform'\nimport App from '.\u002FApp.vue'\n\ncreateApp(App).use(createAttaform()).mount('#app')\n",[29,216,217,222,234,246,258,262],{"__ignoreMap":63},[67,218,219],{"class":69,"line":70},[67,220,221],{"class":129},"\u002F\u002F main.ts\n",[67,223,224,226,229,231],{"class":69,"line":88},[67,225,135],{"class":73},[67,227,228],{"class":84}," { createApp } ",[67,230,141],{"class":73},[67,232,233],{"class":94}," 'vue'\n",[67,235,236,238,241,243],{"class":69,"line":101},[67,237,135],{"class":73},[67,239,240],{"class":84}," { createAttaform } ",[67,242,141],{"class":73},[67,244,245],{"class":94}," 'attaform'\n",[67,247,248,250,253,255],{"class":69,"line":159},[67,249,135],{"class":73},[67,251,252],{"class":84}," App ",[67,254,141],{"class":73},[67,256,257],{"class":94}," '.\u002FApp.vue'\n",[67,259,260],{"class":69,"line":172},[67,261,176],{"emptyLinePlaceholder":175},[67,263,264,267,270,273,276,279,282,285,287,290],{"class":69,"line":179},[67,265,266],{"class":80},"createApp",[67,268,269],{"class":84},"(App).",[67,271,272],{"class":80},"use",[67,274,275],{"class":84},"(",[67,277,278],{"class":80},"createAttaform",[67,280,281],{"class":84},"()).",[67,283,284],{"class":80},"mount",[67,286,275],{"class":84},[67,288,289],{"class":94},"'#app'",[67,291,292],{"class":84},")\n",[14,294,295,296,298,299,305],{},"The Vite plugin is required for SSR-correct ",[29,297,110],{}," bindings.\nFor other bundlers, see ",[34,300,302],{"href":301},"\u002Fdocs\u002Fapi\u002Ftransforms",[29,303,304],{},"attaform\u002Ftransforms",".",[18,307,309],{"id":308},"_3-your-first-form","3. Your first form",[58,311,314],{"className":312,"code":313,"language":197,"meta":63,"style":63},"language-vue shiki shiki-themes github-light github-dark","\u003Cscript setup lang=\"ts\">\n  import { z } from 'zod'\n  import { useForm } from 'attaform\u002Fzod' \u002F\u002F or auto-imported under Nuxt\n\n  const schema = z.object({\n    email: z.email(),\n    password: z.string().min(8, 'At least 8 characters'),\n  })\n\n  const form = useForm({ schema, key: 'signup' })\n\n  const onSubmit = form.handleSubmit(async (values) => {\n    \u002F\u002F `values` is fully typed from the schema — no `as`, no manual narrowing.\n    await api.signup(values)\n  })\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cform @submit.prevent=\"onSubmit\">\n    \u003Clabel>\n      Email\n      \u003Cinput v-register=\"form.register('email')\" type=\"email\" \u002F>\n      \u003Csmall>{{ form.errors.email?.[0]?.message }}\u003C\u002Fsmall>\n    \u003C\u002Flabel>\n\n    \u003Clabel>\n      Password\n      \u003Cinput v-register=\"form.register('password')\" type=\"password\" \u002F>\n      \u003Csmall>{{ form.errors.password?.[0]?.message }}\u003C\u002Fsmall>\n    \u003C\u002Flabel>\n\n    \u003Cbutton type=\"submit\" :disabled=\"!form.meta.isValid || form.meta.isSubmitting\">\n      {{ form.meta.isSubmitting ? 'Creating account…' : 'Create account' }}\n    \u003C\u002Fbutton>\n  \u003C\u002Fform>\n\u003C\u002Ftemplate>\n",[29,315,316,340,353,368,372,392,403,431,436,441,463,468,505,511,526,531,541,546,556,575,586,592,620,635,645,650,659,665,688,702,711,716,741,747,756,766],{"__ignoreMap":63},[67,317,318,321,325,328,331,334,337],{"class":69,"line":70},[67,319,320],{"class":84},"\u003C",[67,322,324],{"class":323},"s9eBZ","script",[67,326,327],{"class":80}," setup",[67,329,330],{"class":80}," lang",[67,332,333],{"class":84},"=",[67,335,336],{"class":94},"\"ts\"",[67,338,339],{"class":84},">\n",[67,341,342,345,348,350],{"class":69,"line":88},[67,343,344],{"class":73},"  import",[67,346,347],{"class":84}," { z } ",[67,349,141],{"class":73},[67,351,352],{"class":94}," 'zod'\n",[67,354,355,357,360,362,365],{"class":69,"line":101},[67,356,344],{"class":73},[67,358,359],{"class":84}," { useForm } ",[67,361,141],{"class":73},[67,363,364],{"class":94}," 'attaform\u002Fzod'",[67,366,367],{"class":129}," \u002F\u002F or auto-imported under Nuxt\n",[67,369,370],{"class":69,"line":159},[67,371,176],{"emptyLinePlaceholder":175},[67,373,374,377,381,384,387,390],{"class":69,"line":172},[67,375,376],{"class":73},"  const",[67,378,380],{"class":379},"sj4cs"," schema",[67,382,383],{"class":73}," =",[67,385,386],{"class":84}," z.",[67,388,389],{"class":80},"object",[67,391,85],{"class":84},[67,393,394,397,400],{"class":69,"line":179},[67,395,396],{"class":84},"    email: z.",[67,398,399],{"class":80},"email",[67,401,402],{"class":84},"(),\n",[67,404,405,408,411,414,417,419,422,425,428],{"class":69,"line":191},[67,406,407],{"class":84},"    password: z.",[67,409,410],{"class":80},"string",[67,412,413],{"class":84},"().",[67,415,416],{"class":80},"min",[67,418,275],{"class":84},[67,420,421],{"class":379},"8",[67,423,424],{"class":84},", ",[67,426,427],{"class":94},"'At least 8 characters'",[67,429,430],{"class":84},"),\n",[67,432,433],{"class":69,"line":209},[67,434,435],{"class":84},"  })\n",[67,437,439],{"class":69,"line":438},9,[67,440,176],{"emptyLinePlaceholder":175},[67,442,444,446,449,451,454,457,460],{"class":69,"line":443},10,[67,445,376],{"class":73},[67,447,448],{"class":379}," form",[67,450,383],{"class":73},[67,452,453],{"class":80}," useForm",[67,455,456],{"class":84},"({ schema, key: ",[67,458,459],{"class":94},"'signup'",[67,461,462],{"class":84}," })\n",[67,464,466],{"class":69,"line":465},11,[67,467,176],{"emptyLinePlaceholder":175},[67,469,471,473,476,478,481,484,486,489,492,496,499,502],{"class":69,"line":470},12,[67,472,376],{"class":73},[67,474,475],{"class":379}," onSubmit",[67,477,383],{"class":73},[67,479,480],{"class":84}," form.",[67,482,483],{"class":80},"handleSubmit",[67,485,275],{"class":84},[67,487,488],{"class":73},"async",[67,490,491],{"class":84}," (",[67,493,495],{"class":494},"s4XuR","values",[67,497,498],{"class":84},") ",[67,500,501],{"class":73},"=>",[67,503,504],{"class":84}," {\n",[67,506,508],{"class":69,"line":507},13,[67,509,510],{"class":129},"    \u002F\u002F `values` is fully typed from the schema — no `as`, no manual narrowing.\n",[67,512,514,517,520,523],{"class":69,"line":513},14,[67,515,516],{"class":73},"    await",[67,518,519],{"class":84}," api.",[67,521,522],{"class":80},"signup",[67,524,525],{"class":84},"(values)\n",[67,527,529],{"class":69,"line":528},15,[67,530,435],{"class":84},[67,532,534,537,539],{"class":69,"line":533},16,[67,535,536],{"class":84},"\u003C\u002F",[67,538,324],{"class":323},[67,540,339],{"class":84},[67,542,544],{"class":69,"line":543},17,[67,545,176],{"emptyLinePlaceholder":175},[67,547,549,551,554],{"class":69,"line":548},18,[67,550,320],{"class":84},[67,552,553],{"class":323},"template",[67,555,339],{"class":84},[67,557,559,562,565,568,570,573],{"class":69,"line":558},19,[67,560,561],{"class":84},"  \u003C",[67,563,564],{"class":323},"form",[67,566,567],{"class":80}," @submit.prevent",[67,569,333],{"class":84},[67,571,572],{"class":94},"\"onSubmit\"",[67,574,339],{"class":84},[67,576,578,581,584],{"class":69,"line":577},20,[67,579,580],{"class":84},"    \u003C",[67,582,583],{"class":323},"label",[67,585,339],{"class":84},[67,587,589],{"class":69,"line":588},21,[67,590,591],{"class":84},"      Email\n",[67,593,595,598,601,604,606,609,612,614,617],{"class":69,"line":594},22,[67,596,597],{"class":84},"      \u003C",[67,599,600],{"class":323},"input",[67,602,603],{"class":80}," v-register",[67,605,333],{"class":84},[67,607,608],{"class":94},"\"form.register('email')\"",[67,610,611],{"class":80}," type",[67,613,333],{"class":84},[67,615,616],{"class":94},"\"email\"",[67,618,619],{"class":84}," \u002F>\n",[67,621,623,625,628,631,633],{"class":69,"line":622},23,[67,624,597],{"class":84},[67,626,627],{"class":323},"small",[67,629,630],{"class":84},">{{ form.errors.email?.[0]?.message }}\u003C\u002F",[67,632,627],{"class":323},[67,634,339],{"class":84},[67,636,638,641,643],{"class":69,"line":637},24,[67,639,640],{"class":84},"    \u003C\u002F",[67,642,583],{"class":323},[67,644,339],{"class":84},[67,646,648],{"class":69,"line":647},25,[67,649,176],{"emptyLinePlaceholder":175},[67,651,653,655,657],{"class":69,"line":652},26,[67,654,580],{"class":84},[67,656,583],{"class":323},[67,658,339],{"class":84},[67,660,662],{"class":69,"line":661},27,[67,663,664],{"class":84},"      Password\n",[67,666,668,670,672,674,676,679,681,683,686],{"class":69,"line":667},28,[67,669,597],{"class":84},[67,671,600],{"class":323},[67,673,603],{"class":80},[67,675,333],{"class":84},[67,677,678],{"class":94},"\"form.register('password')\"",[67,680,611],{"class":80},[67,682,333],{"class":84},[67,684,685],{"class":94},"\"password\"",[67,687,619],{"class":84},[67,689,691,693,695,698,700],{"class":69,"line":690},29,[67,692,597],{"class":84},[67,694,627],{"class":323},[67,696,697],{"class":84},">{{ form.errors.password?.[0]?.message }}\u003C\u002F",[67,699,627],{"class":323},[67,701,339],{"class":84},[67,703,705,707,709],{"class":69,"line":704},30,[67,706,640],{"class":84},[67,708,583],{"class":323},[67,710,339],{"class":84},[67,712,714],{"class":69,"line":713},31,[67,715,176],{"emptyLinePlaceholder":175},[67,717,719,721,724,726,728,731,734,736,739],{"class":69,"line":718},32,[67,720,580],{"class":84},[67,722,723],{"class":323},"button",[67,725,611],{"class":80},[67,727,333],{"class":84},[67,729,730],{"class":94},"\"submit\"",[67,732,733],{"class":80}," :disabled",[67,735,333],{"class":84},[67,737,738],{"class":94},"\"!form.meta.isValid || form.meta.isSubmitting\"",[67,740,339],{"class":84},[67,742,744],{"class":69,"line":743},33,[67,745,746],{"class":84},"      {{ form.meta.isSubmitting ? 'Creating account…' : 'Create account' }}\n",[67,748,750,752,754],{"class":69,"line":749},34,[67,751,640],{"class":84},[67,753,723],{"class":323},[67,755,339],{"class":84},[67,757,759,762,764],{"class":69,"line":758},35,[67,760,761],{"class":84},"  \u003C\u002F",[67,763,564],{"class":323},[67,765,339],{"class":84},[67,767,769,771,773],{"class":69,"line":768},36,[67,770,536],{"class":84},[67,772,553],{"class":323},[67,774,339],{"class":84},[14,776,777],{},"Three things this demonstrates:",[779,780,781,794,802],"ul",{},[782,783,784,789,790,793],"li",{},[785,786,787],"strong",{},[29,788,110],{}," binds a native input directly to a path on the form.\nNo two-way wiring, no manual ",[29,791,792],{},"v-model"," plumbing.",[782,795,796,801],{},[785,797,798],{},[29,799,800],{},"form.errors"," is a reactive proxy. Refinement errors surface as\nthe user types; required-field \"no value supplied\" errors fire on\nsubmit.",[782,803,804,809,810,813],{},[785,805,806],{},[29,807,808],{},"form.meta.isValid"," and ",[29,811,812],{},"form.meta.isSubmitting"," gate the\nsubmit button — submit auto-runs validation first, so the callback\nreceives strictly-typed values.",[14,815,816,817,821],{},"Open the ",[34,818,820],{"href":819},"\u002Fplay","live playground"," to edit this exact example without\nleaving the browser.",[18,823,825],{"id":824},"_4-where-to-next","4. Where to next",[827,828,829,842],"table",{},[830,831,832],"thead",{},[833,834,835,839],"tr",{},[836,837,838],"th",{},"If you want to…",[836,840,841],{},"Read",[843,844,845,862,882,893,911,922,933,952],"tbody",{},[833,846,847,854],{},[848,849,850,851,853],"td",{},"See every option ",[29,852,114],{}," accepts",[848,855,856],{},[34,857,859],{"href":858},"\u002Fdocs\u002Fapi\u002Fzod",[29,860,861],{},"attaform\u002Fzod",[833,863,864,876],{},[848,865,866,867,870,871,870,873],{},"Understand ",[29,868,869],{},"form.values"," \u002F ",[29,872,800],{},[29,874,875],{},"meta",[848,877,878],{},[34,879,881],{"href":880},"\u002Fdocs\u002Fapi\u002Fuse-form-return","The useForm return value",[833,883,884,887],{},[848,885,886],{},"Persist drafts across reloads",[848,888,889],{},[34,890,892],{"href":891},"\u002Fdocs\u002Frecipes\u002Fpersistence","Persistence",[833,894,895,905],{},[848,896,897,898,901,902],{},"Validate on ",[29,899,900],{},"blur"," instead of ",[29,903,904],{},"change",[848,906,907],{},[34,908,910],{"href":909},"\u002Fdocs\u002Frecipes\u002Ffield-level-validation","Field-level validation",[833,912,913,916],{},[848,914,915],{},"Handle server-side validation errors",[848,917,918],{},[34,919,921],{"href":920},"\u002Fdocs\u002Frecipes\u002Fserver-errors","Server errors",[833,923,924,927],{},[848,925,926],{},"Add undo \u002F redo",[848,928,929],{},[34,930,932],{"href":931},"\u002Fdocs\u002Frecipes\u002Fundo-redo","Undo \u002F redo",[833,934,935,946],{},[848,936,937,938,941,942,945],{},"Build dynamic field arrays (",[29,939,940],{},"append","\u002F",[29,943,944],{},"remove","\u002F…)",[848,947,948],{},[34,949,951],{"href":950},"\u002Fdocs\u002Frecipes\u002Fdynamic-field-arrays","Dynamic field arrays",[833,953,954,957],{},[848,955,956],{},"Hit a problem",[848,958,959],{},[34,960,962],{"href":961},"\u002Fdocs\u002Ftroubleshooting","Troubleshooting",[964,965,966],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":63,"searchDepth":88,"depth":88,"links":968},[969,970,974,975],{"id":20,"depth":88,"text":21},{"id":43,"depth":88,"text":44,"children":971},[972,973],{"id":48,"depth":101,"text":49},{"id":118,"depth":101,"text":119},{"id":308,"depth":88,"text":309},{"id":824,"depth":88,"text":825},"md",{},"\u002Fdocs\u002Fquickstart",{"title":5,"description":16},"docs\u002Fquickstart","g6ZfTnmytabtMG_XIZHSdy7LVSYLNFqkUcLnk6CX6b0",1777934135554]