[{"data":1,"prerenderedAt":551},["ShallowReactive",2],{"content-\u002Fdocs\u002Fdevtools-and-debugging\u002Fvue-devtools":3},{"id":4,"title":5,"body":6,"description":530,"extension":531,"meta":532,"metaRows":533,"navigation":154,"path":546,"seo":547,"source":548,"stem":549,"__hash__":550},"docs\u002Fdocs\u002Fdevtools-and-debugging\u002Fvue-devtools.md","Vue DevTools integration",{"type":7,"value":8,"toc":521},"minimark",[9,13,25,28,34,39,42,67,70,92,95,202,209,213,216,270,273,299,306,310,319,404,409,413,423,426,430,464,468,491,495,517],[10,11,5],"h1",{"id":12},"vue-devtools-integration",[14,15,16],"blockquote",{},[17,18,19,20,24],"p",{},"For Vite and bare-Vue projects, install one optional peer dep and the Vue DevTools extension shows an ",[21,22,23],"strong",{},"Attaform"," inspector + timeline alongside Pinia \u002F Vue Router \u002F components.",[26,27],"docs-meta-table",{},[17,29,30,31,33],{},"This page is code-only; the Vue DevTools surface lives in your browser's extension panel, not inside the docs site. Install the extension, open any Vite \u002F bare-Vue Attaform consumer in dev, and pick ",[21,32,23],{}," in the DevTools sidebar to see it.",[35,36,38],"h2",{"id":37},"installing","Installing",[17,40,41],{},"The extension is the same one Vue itself uses; install it once per browser:",[43,44,49],"pre",{"className":45,"code":46,"language":47,"meta":48,"style":48},"language-bash shiki shiki-themes github-light github-dark","# Chrome \u002F Edge \u002F Firefox web stores\n# https:\u002F\u002Fdevtools.vuejs.org\n","bash","",[50,51,52,61],"code",{"__ignoreMap":48},[53,54,57],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"sJ8bj","# Chrome \u002F Edge \u002F Firefox web stores\n",[53,62,64],{"class":55,"line":63},2,[53,65,66],{"class":59},"# https:\u002F\u002Fdevtools.vuejs.org\n",[17,68,69],{},"Then add the peer dep to the project (dev-only):",[43,71,73],{"className":45,"code":72,"language":47,"meta":48,"style":48},"npm install -D @vue\u002Fdevtools-api\n",[50,74,75],{"__ignoreMap":48},[53,76,77,81,85,89],{"class":55,"line":56},[53,78,80],{"class":79},"sScJk","npm",[53,82,84],{"class":83},"sZZnC"," install",[53,86,88],{"class":87},"sj4cs"," -D",[53,90,91],{"class":83}," @vue\u002Fdevtools-api\n",[17,93,94],{},"Attaform auto-wires the inspector + timeline when the dep is present at runtime:",[43,96,100],{"className":97,"code":98,"language":99,"meta":48,"style":48},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F main.ts\nimport { createApp } from 'vue'\nimport { createAttaform } from 'attaform'\nimport App from '.\u002FApp.vue'\n\ncreateApp(App)\n  .use(createAttaform()) \u002F\u002F devtools: true by default\n  .mount('#app')\n","ts",[50,101,102,107,123,136,149,156,165,186],{"__ignoreMap":48},[53,103,104],{"class":55,"line":56},[53,105,106],{"class":59},"\u002F\u002F main.ts\n",[53,108,109,113,117,120],{"class":55,"line":63},[53,110,112],{"class":111},"szBVR","import",[53,114,116],{"class":115},"sVt8B"," { createApp } ",[53,118,119],{"class":111},"from",[53,121,122],{"class":83}," 'vue'\n",[53,124,126,128,131,133],{"class":55,"line":125},3,[53,127,112],{"class":111},[53,129,130],{"class":115}," { createAttaform } ",[53,132,119],{"class":111},[53,134,135],{"class":83}," 'attaform'\n",[53,137,139,141,144,146],{"class":55,"line":138},4,[53,140,112],{"class":111},[53,142,143],{"class":115}," App ",[53,145,119],{"class":111},[53,147,148],{"class":83}," '.\u002FApp.vue'\n",[53,150,152],{"class":55,"line":151},5,[53,153,155],{"emptyLinePlaceholder":154},true,"\n",[53,157,159,162],{"class":55,"line":158},6,[53,160,161],{"class":79},"createApp",[53,163,164],{"class":115},"(App)\n",[53,166,168,171,174,177,180,183],{"class":55,"line":167},7,[53,169,170],{"class":115},"  .",[53,172,173],{"class":79},"use",[53,175,176],{"class":115},"(",[53,178,179],{"class":79},"createAttaform",[53,181,182],{"class":115},"()) ",[53,184,185],{"class":59},"\u002F\u002F devtools: true by default\n",[53,187,189,191,194,196,199],{"class":55,"line":188},8,[53,190,170],{"class":115},[53,192,193],{"class":79},"mount",[53,195,176],{"class":115},[53,197,198],{"class":83},"'#app'",[53,200,201],{"class":115},")\n",[17,203,204,205,208],{},"If the peer dep isn't installed at runtime, nothing breaks; the inspector simply doesn't register, and the form library works as usual. Treating the integration as optional means a freshly-cloned project doesn't fail to start just because ",[50,206,207],{},"@vue\u002Fdevtools-api"," isn't on disk.",[35,210,212],{"id":211},"production-builds","Production builds",[17,214,215],{},"Gate the wiring off explicitly in production:",[43,217,219],{"className":97,"code":218,"language":99,"meta":48,"style":48},"const attaform = import.meta.env.PROD ? createAttaform({ devtools: false }) : createAttaform()\n",[50,220,221],{"__ignoreMap":48},[53,222,223,226,229,232,235,238,241,244,247,250,253,256,259,262,265,267],{"class":55,"line":56},[53,224,225],{"class":111},"const",[53,227,228],{"class":87}," attaform",[53,230,231],{"class":111}," =",[53,233,234],{"class":111}," import",[53,236,237],{"class":115},".",[53,239,240],{"class":87},"meta",[53,242,243],{"class":115},".env.",[53,245,246],{"class":87},"PROD",[53,248,249],{"class":111}," ?",[53,251,252],{"class":79}," createAttaform",[53,254,255],{"class":115},"({ devtools: ",[53,257,258],{"class":87},"false",[53,260,261],{"class":115}," }) ",[53,263,264],{"class":111},":",[53,266,252],{"class":79},[53,268,269],{"class":115},"()\n",[17,271,272],{},"For a zero-overhead production build:",[274,275,276,286],"ol",{},[277,278,279,280,283,284,237],"li",{},"Pass ",[50,281,282],{},"{ devtools: false }"," to ",[50,285,179],{},[277,287,288,289,291,292,295,296,237],{},"Keep ",[50,290,207],{}," in ",[50,293,294],{},"devDependencies",", not ",[50,297,298],{},"dependencies",[17,300,301,302,305],{},"The wire-up is code-split, so the chunk isn't pulled in when ",[50,303,304],{},"devtools: false","; production bundles stay clean even without dropping the peer dep.",[35,307,309],{"id":308},"what-you-see","What you see",[17,311,312,313,318],{},"The Vue DevTools panel surfaces the same data as the ",[314,315,317],"a",{"href":316},"\u002Fdocs\u002Fdevtools-and-debugging\u002Fdevtools-panel","Nuxt panel",": form list, editable JSON value tree, schema\u002Fuser error split, aggregates, and the event timeline. Both surfaces render values raw; DevTools is a dev-only surface, so the sensitive-name list gates persistence and multi-tab broadcasts, not display.",[320,321,322,335],"table",{},[323,324,325],"thead",{},[326,327,328,332],"tr",{},[329,330,331],"th",{},"Surface",[329,333,334],{},"What it is",[336,337,338,350,358,366,386],"tbody",{},[326,339,340,344],{},[341,342,343],"td",{},"Form list",[341,345,346,347,237],{},"One entry per registered form, keyed by ",[50,348,349],{},"form.key",[326,351,352,355],{},[341,353,354],{},"Form value",[341,356,357],{},"Editable JSON tree; writes flow through the same store-mutation path.",[326,359,360,363],{},[341,361,362],{},"Schema \u002F User errors",[341,364,365],{},"Split by source.",[326,367,368,371],{},[341,369,370],{},"Aggregates",[341,372,373,376,377,376,380,376,383,237],{},[50,374,375],{},"submitting",", ",[50,378,379],{},"submissionAttempts",[50,381,382],{},"submitError",[50,384,385],{},"activeValidations",[326,387,388,391],{},[341,389,390],{},"Timeline",[341,392,393,396,397,396,400,403],{},[50,394,395],{},"form.change"," \u002F ",[50,398,399],{},"submit.success",[50,401,402],{},"reset"," events with value snapshots.",[17,405,406,407,237],{},"The only difference is location: instead of the Nuxt DevTools overlay's sidebar, the panel appears in the Vue DevTools' inspector list under ",[21,408,23],{},[35,410,412],{"id":411},"multi-app-setups","Multi-app setups",[17,414,415,416,418,419,422],{},"Each Vue app registers its own inspector entry in the extension. Micro-frontend setups with parallel Vue apps each get their own ",[21,417,23],{}," node; the extension reads from ",[50,420,421],{},"getCurrentApp()"," per panel switch.",[17,424,425],{},"This is the practical advantage over the Nuxt panel for multi-app monorepos: pick the app in the DevTools' app-selector dropdown, the Attaform panel re-binds to that app's forms.",[35,427,429],{"id":428},"when-to-pick-which","When to pick which",[431,432,433,443,449,455],"ul",{},[277,434,435,438,439,442],{},[21,436,437],{},"Nuxt project, single app"," → ",[314,440,441],{"href":316},"Nuxt DevTools panel",". Zero install, dev-only by default.",[277,444,445,448],{},[21,446,447],{},"Vite \u002F bare-Vue project"," → Vue DevTools extension (this page). One peer dep, extension already useful for unrelated Vue debugging.",[277,450,451,454],{},[21,452,453],{},"Multi-app setup (micro-frontend, embedded apps)"," → Vue DevTools. Per-app inspection.",[277,456,457,460,461,463],{},[21,458,459],{},"Both surfaces in one Nuxt project"," → both work simultaneously. The Nuxt overlay surfaces the latest ",[50,462,179],{}," install; the extension surfaces every app.",[35,465,467],{"id":466},"caveats","Caveats",[431,469,470,479,485],{},[277,471,472,475,476,478],{},[21,473,474],{},"Extension version mismatch."," The Vue DevTools extension and ",[50,477,207],{}," evolve in tandem; keep both reasonably current. An outdated extension may not surface newer inspector node types; an outdated peer dep may emit events the extension doesn't render.",[277,480,481,484],{},[21,482,483],{},"Privacy across reloads."," The timeline doesn't persist across reloads; reloading the page wipes the visible history. Persistent debug requires copying events out manually.",[277,486,487,490],{},[21,488,489],{},"Screen-share hygiene."," Values render raw. Same advice as the browser DevTools console: close before sharing the screen.",[35,492,494],{"id":493},"where-to-next","Where to next",[431,496,497,503,510],{},[277,498,499,502],{},[314,500,501],{"href":316},"The Attaform DevTools panel",": the Nuxt-native alternative, same data surface.",[277,504,505,509],{},[314,506,508],{"href":507},"\u002Fdocs\u002Fdevtools-and-debugging\u002Ftroubleshooting","Troubleshooting",": what to look for in the panels when forms misbehave.",[277,511,512,516],{},[314,513,515],{"href":514},"\u002Fdocs\u002Fpersistence\u002Fsensitive-names","Sensitive-name protection",": the list that gates persistence writes and multi-tab broadcasts.",[518,519,520],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}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 pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}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 .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":48,"searchDepth":63,"depth":63,"links":522},[523,524,525,526,527,528,529],{"id":37,"depth":63,"text":38},{"id":211,"depth":63,"text":212},{"id":308,"depth":63,"text":309},{"id":411,"depth":63,"text":412},{"id":428,"depth":63,"text":429},{"id":466,"depth":63,"text":467},{"id":493,"depth":63,"text":494},"Vite and bare-Vue projects get an Attaform inspector + timeline in the Vue DevTools extension via an optional peer dependency. Same data as the Nuxt panel, different surface.","md",{},[534,537,540,543],{"label":535,"value":536},"Category","Module",{"label":538,"value":539},"Where","Vue DevTools browser extension",{"label":541,"value":542,"kind":50},"Peer dep","@vue\u002Fdevtools-api (optional)",{"label":544,"value":545},"Auto-wired?","yes, when the peer dep is present at runtime","\u002Fdocs\u002Fdevtools-and-debugging\u002Fvue-devtools",{"title":5,"description":530},null,"docs\u002Fdevtools-and-debugging\u002Fvue-devtools","uugaU0_pZq7DcsDSTjZEFi0laDBwpQU_ZamiK9M6Ut0",1780949762261]