[{"data":1,"prerenderedAt":373},["ShallowReactive",2],{"navigation_docs":3,"diagnostic-content-NUXT0077":44},[4,8,12,16,20,24,28,32,36,40],{"title":5,"path":6,"stem":7},"CLI","\u002Fcli","1.cli",{"title":9,"path":10,"stem":11},"Nuxt","\u002Fnuxt","2.nuxt",{"title":13,"path":14,"stem":15},"Vue","\u002Fvue","3.vue",{"title":17,"path":18,"stem":19},"Vite","\u002Fvite","4.vite",{"title":21,"path":22,"stem":23},"Nitro","\u002Fnitro","5.nitro",{"title":25,"path":26,"stem":27},"TypeScript","\u002Ftypescript","6.typescript",{"title":29,"path":30,"stem":31},"shadcn","\u002Fshadcn","7.shadcn",{"title":33,"path":34,"stem":35},"Package","\u002Fpackage","8.package",{"title":37,"path":38,"stem":39},"Extending Doctor","\u002Fextending","9.extending",{"title":41,"path":42,"stem":43},"Pinia","\u002Fpinia","9.pinia",{"id":45,"title":46,"body":47,"category":53,"code":361,"description":362,"docsUrl":54,"extension":363,"fix":364,"framework":365,"meta":366,"navigation":367,"pack":56,"path":368,"ruleId":57,"rulePath":58,"seo":369,"severity":59,"source":60,"sourceUrl":61,"stem":370,"why":371,"__hash__":372},"diagnostics\u002Fdiagnostics\u002FNUXT0077.md","NUXT0077: Keep setup-bound functions out of utils\u002F",{"type":48,"value":49,"toc":351},"minimark",[50,62,67,80,84,105,109,114,117,218,221,286,290,293,319,323,335,339,347],[51,52],"rule-metadata",{"category":53,"docsUrl":54,"fix":55,"pack":56,"ruleId":57,"rulePath":58,"severity":59,"source":60,"sourceUrl":61},"architecture","https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fguide\u002Fdirectory-structure\u002Fapp\u002Futils","suggestion","vite-doctor\u002Fnuxt","nuxt\u002Fstructure\u002Fno-composable-in-utils","\u002Fnuxt\u002Frules\u002Fstructure\u002Fno-composable-in-utils","warn","src\u002Frule-packs\u002Fnuxt\u002Frules\u002Fnuxt\u002Fcomposable-placement.ts","https:\u002F\u002Fgithub.com\u002Fonmax\u002Fvite-doctor\u002Fblob\u002Fmain\u002Fsrc\u002Frule-packs\u002Fnuxt\u002Frules\u002Fnuxt\u002Fcomposable-placement.ts",[63,64,66],"h2",{"id":65},"why-it-happens","Why it happens",[68,69,70,71,75,76,79],"p",{},"Nuxt auto-imports both composables\u002F and utils\u002F, so the directory is how readers know whether a function must run during setup. A utils\u002F function that calls lifecycle hooks, ",[72,73,74],"code",{},"inject()",", ",[72,77,78],{},"provide()",", or other composables breaks when it is called from an event handler, timer, or plugin the way plain utilities are.",[63,81,83],{"id":82},"fix","Fix",[68,85,86,87,75,90,75,93,96,97,100,101,104],{},"Move the function to composables\u002F and name it with the use prefix. Functions that only read Nuxt app context, such as ",[72,88,89],{},"useNuxtApp()",[72,91,92],{},"useRuntimeConfig()",[72,94,95],{},"useRouter()",", or ",[72,98,99],{},"useState()",", can stay in utils\u002F, like Nuxt's own ",[72,102,103],{},"navigateTo()",".",[63,106,108],{"id":107},"example","Example",[110,111,113],"h3",{"id":112},"move-setup-bound-tracking-into-a-composable","Move setup-bound tracking into a composable",[68,115,116],{},"Before",[118,119,124],"pre",{"className":120,"code":121,"language":122,"meta":123,"style":123},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F app\u002Futils\u002Ftrack.ts\nexport function trackPageView() {\n  const route = useRoute()\n  onMounted(() => analytics.page(route.fullPath))\n}\n","ts","",[72,125,126,135,157,177,212],{"__ignoreMap":123},[127,128,131],"span",{"class":129,"line":130},"line",1,[127,132,134],{"class":133},"sHwdD","\u002F\u002F app\u002Futils\u002Ftrack.ts\n",[127,136,138,142,146,150,154],{"class":129,"line":137},2,[127,139,141],{"class":140},"s7zQu","export",[127,143,145],{"class":144},"spNyl"," function",[127,147,149],{"class":148},"s2Zo4"," trackPageView",[127,151,153],{"class":152},"sMK4o","()",[127,155,156],{"class":152}," {\n",[127,158,160,163,167,170,173],{"class":129,"line":159},3,[127,161,162],{"class":144},"  const",[127,164,166],{"class":165},"sTEyZ"," route",[127,168,169],{"class":152}," =",[127,171,172],{"class":148}," useRoute",[127,174,176],{"class":175},"swJcz","()\n",[127,178,180,183,186,188,191,194,196,199,201,204,206,209],{"class":129,"line":179},4,[127,181,182],{"class":148},"  onMounted",[127,184,185],{"class":175},"(",[127,187,153],{"class":152},[127,189,190],{"class":144}," =>",[127,192,193],{"class":165}," analytics",[127,195,104],{"class":152},[127,197,198],{"class":148},"page",[127,200,185],{"class":175},[127,202,203],{"class":165},"route",[127,205,104],{"class":152},[127,207,208],{"class":165},"fullPath",[127,210,211],{"class":175},"))\n",[127,213,215],{"class":129,"line":214},5,[127,216,217],{"class":152},"}\n",[68,219,220],{},"After",[118,222,224],{"className":120,"code":223,"language":122,"meta":123,"style":123},"\u002F\u002F app\u002Fcomposables\u002FusePageTracking.ts\nexport function usePageTracking() {\n  const route = useRoute()\n  onMounted(() => analytics.page(route.fullPath))\n}\n",[72,225,226,231,244,256,282],{"__ignoreMap":123},[127,227,228],{"class":129,"line":130},[127,229,230],{"class":133},"\u002F\u002F app\u002Fcomposables\u002FusePageTracking.ts\n",[127,232,233,235,237,240,242],{"class":129,"line":137},[127,234,141],{"class":140},[127,236,145],{"class":144},[127,238,239],{"class":148}," usePageTracking",[127,241,153],{"class":152},[127,243,156],{"class":152},[127,245,246,248,250,252,254],{"class":129,"line":159},[127,247,162],{"class":144},[127,249,166],{"class":165},[127,251,169],{"class":152},[127,253,172],{"class":148},[127,255,176],{"class":175},[127,257,258,260,262,264,266,268,270,272,274,276,278,280],{"class":129,"line":179},[127,259,182],{"class":148},[127,261,185],{"class":175},[127,263,153],{"class":152},[127,265,190],{"class":144},[127,267,193],{"class":165},[127,269,104],{"class":152},[127,271,198],{"class":148},[127,273,185],{"class":175},[127,275,203],{"class":165},[127,277,104],{"class":152},[127,279,208],{"class":165},[127,281,211],{"class":175},[127,283,284],{"class":129,"line":214},[127,285,217],{"class":152},[63,287,289],{"id":288},"verify-the-fix","Verify the fix",[68,291,292],{},"Run only this rule after editing so the report stays focused on the diagnostic you are closing:",[118,294,298],{"className":295,"code":296,"language":297,"meta":123,"style":123},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm nuxt doctor --rules nuxt\u002Fstructure\u002Fno-composable-in-utils\n","bash",[72,299,300],{"__ignoreMap":123},[127,301,302,306,310,313,316],{"class":129,"line":130},[127,303,305],{"class":304},"sBMFI","pnpm",[127,307,309],{"class":308},"sfazB"," nuxt",[127,311,312],{"class":308}," doctor",[127,314,315],{"class":308}," --rules",[127,317,318],{"class":308}," nuxt\u002Fstructure\u002Fno-composable-in-utils\n",[63,320,322],{"id":321},"useful-links","Useful links",[324,325,326],"ul",{},[327,328,329],"li",{},[330,331,334],"a",{"href":54,"rel":332},[333],"nofollow","Upstream docs",[63,336,338],{"id":337},"related-rule","Related rule",[324,340,341],{},[327,342,343],{},[330,344,345],{"href":58},[72,346,57],{},[348,349,350],"style",{},"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 .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":123,"searchDepth":137,"depth":137,"links":352},[353,354,355,358,359,360],{"id":65,"depth":137,"text":66},{"id":82,"depth":137,"text":83},{"id":107,"depth":137,"text":108,"children":356},[357],{"id":112,"depth":159,"text":113},{"id":288,"depth":137,"text":289},{"id":321,"depth":137,"text":322},{"id":337,"depth":137,"text":338},"NUXT0077","Finds functions in Nuxt utils\u002F that need a component setup context and belong in composables\u002F.","md","Move the function to composables\u002F and name it with the use prefix. Functions that only read Nuxt app context, such as useNuxtApp(), useRuntimeConfig(), useRouter(), or useState(), can stay in utils\u002F, like Nuxt's own navigateTo().","nuxt",{},true,"\u002Fdiagnostics\u002Fnuxt0077",{"title":46,"description":362},"diagnostics\u002FNUXT0077","Nuxt auto-imports both composables\u002F and utils\u002F, so the directory is how readers know whether a function must run during setup. A utils\u002F function that calls lifecycle hooks, inject(), provide(), or other composables breaks when it is called from an event handler, timer, or plugin the way plain utilities are.","XPL6rz2_LHTSJG5Ht7_BRoeRD7uN6eK50BZeHAX1NvE",1791309501710]