[{"data":1,"prerenderedAt":358},["ShallowReactive",2],{"navigation_docs":3,"rule-content-\u002Fnuxt\u002Frules\u002Fstructure\u002Fno-composable-in-utils":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,"description":345,"diagnosticCodes":346,"docsUrl":55,"extension":347,"fix":56,"framework":348,"meta":349,"navigation":350,"pack":57,"path":352,"recommendedReplacement":353,"ruleId":58,"seo":354,"severity":59,"source":60,"sourceUrl":61,"stem":355,"why":356,"__hash__":357},"rules\u002Fnuxt\u002Frules\u002Fstructure\u002Fno-composable-in-utils.md","Keep setup-bound functions out of utils\u002F",{"type":48,"value":49,"toc":336},"minimark",[50,62,67,99,103,115,119,140,144,156,160,165,168,264,267,332],[51,52],"rule-metadata",{"category":53,"diagnosticCodes":54,"docsUrl":55,"fix":56,"pack":57,"ruleId":58,"severity":59,"source":60,"sourceUrl":61},"architecture","NUXT0077","https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fguide\u002Fdirectory-structure\u002Fapp\u002Futils","suggestion","vite-doctor\u002Fnuxt","nuxt\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},"run-this-rule","Run this rule",[68,69,74],"pre",{"className":70,"code":71,"language":72,"meta":73,"style":73},"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","",[75,76,77],"code",{"__ignoreMap":73},[78,79,82,86,90,93,96],"span",{"class":80,"line":81},"line",1,[78,83,85],{"class":84},"sBMFI","pnpm",[78,87,89],{"class":88},"sfazB"," nuxt",[78,91,92],{"class":88}," doctor",[78,94,95],{"class":88}," --rules",[78,97,98],{"class":88}," nuxt\u002Fstructure\u002Fno-composable-in-utils\n",[63,100,102],{"id":101},"why-it-matters","Why it matters",[104,105,106,107,110,111,114],"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, ",[75,108,109],{},"inject()",", ",[75,112,113],{},"provide()",", or other composables breaks when it is called from an event handler, timer, or plugin the way plain utilities are.",[63,116,118],{"id":117},"recommended-fix","Recommended fix",[104,120,121,122,110,125,110,128,131,132,135,136,139],{},"Move the function to composables\u002F and name it with the use prefix. Functions that only read Nuxt app context, such as ",[75,123,124],{},"useNuxtApp()",[75,126,127],{},"useRuntimeConfig()",[75,129,130],{},"useRouter()",", or ",[75,133,134],{},"useState()",", can stay in utils\u002F, like Nuxt's own ",[75,137,138],{},"navigateTo()",".",[63,141,143],{"id":142},"useful-links","Useful links",[145,146,147],"ul",{},[148,149,150],"li",{},[151,152,155],"a",{"href":55,"rel":153},[154],"nofollow","Rule reference",[63,157,159],{"id":158},"example","Example",[161,162,164],"h3",{"id":163},"move-setup-bound-tracking-into-a-composable","Move setup-bound tracking into a composable",[104,166,167],{},"Before",[68,169,173],{"className":170,"code":171,"language":172,"meta":73,"style":73},"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",[75,174,175,181,203,223,258],{"__ignoreMap":73},[78,176,177],{"class":80,"line":81},[78,178,180],{"class":179},"sHwdD","\u002F\u002F app\u002Futils\u002Ftrack.ts\n",[78,182,184,188,192,196,200],{"class":80,"line":183},2,[78,185,187],{"class":186},"s7zQu","export",[78,189,191],{"class":190},"spNyl"," function",[78,193,195],{"class":194},"s2Zo4"," trackPageView",[78,197,199],{"class":198},"sMK4o","()",[78,201,202],{"class":198}," {\n",[78,204,206,209,213,216,219],{"class":80,"line":205},3,[78,207,208],{"class":190},"  const",[78,210,212],{"class":211},"sTEyZ"," route",[78,214,215],{"class":198}," =",[78,217,218],{"class":194}," useRoute",[78,220,222],{"class":221},"swJcz","()\n",[78,224,226,229,232,234,237,240,242,245,247,250,252,255],{"class":80,"line":225},4,[78,227,228],{"class":194},"  onMounted",[78,230,231],{"class":221},"(",[78,233,199],{"class":198},[78,235,236],{"class":190}," =>",[78,238,239],{"class":211}," analytics",[78,241,139],{"class":198},[78,243,244],{"class":194},"page",[78,246,231],{"class":221},[78,248,249],{"class":211},"route",[78,251,139],{"class":198},[78,253,254],{"class":211},"fullPath",[78,256,257],{"class":221},"))\n",[78,259,261],{"class":80,"line":260},5,[78,262,263],{"class":198},"}\n",[104,265,266],{},"After",[68,268,270],{"className":170,"code":269,"language":172,"meta":73,"style":73},"\u002F\u002F app\u002Fcomposables\u002FusePageTracking.ts\nexport function usePageTracking() {\n  const route = useRoute()\n  onMounted(() => analytics.page(route.fullPath))\n}\n",[75,271,272,277,290,302,328],{"__ignoreMap":73},[78,273,274],{"class":80,"line":81},[78,275,276],{"class":179},"\u002F\u002F app\u002Fcomposables\u002FusePageTracking.ts\n",[78,278,279,281,283,286,288],{"class":80,"line":183},[78,280,187],{"class":186},[78,282,191],{"class":190},[78,284,285],{"class":194}," usePageTracking",[78,287,199],{"class":198},[78,289,202],{"class":198},[78,291,292,294,296,298,300],{"class":80,"line":205},[78,293,208],{"class":190},[78,295,212],{"class":211},[78,297,215],{"class":198},[78,299,218],{"class":194},[78,301,222],{"class":221},[78,303,304,306,308,310,312,314,316,318,320,322,324,326],{"class":80,"line":225},[78,305,228],{"class":194},[78,307,231],{"class":221},[78,309,199],{"class":198},[78,311,236],{"class":190},[78,313,239],{"class":211},[78,315,139],{"class":198},[78,317,244],{"class":194},[78,319,231],{"class":221},[78,321,249],{"class":211},[78,323,139],{"class":198},[78,325,254],{"class":211},[78,327,257],{"class":221},[78,329,330],{"class":80,"line":260},[78,331,263],{"class":198},[333,334,335],"style",{},"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}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 .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}",{"title":73,"searchDepth":183,"depth":183,"links":337},[338,339,340,341,342],{"id":65,"depth":183,"text":66},{"id":101,"depth":183,"text":102},{"id":117,"depth":183,"text":118},{"id":142,"depth":183,"text":143},{"id":158,"depth":183,"text":159,"children":343},[344],{"id":163,"depth":205,"text":164},"Finds functions in Nuxt utils\u002F that need a component setup context and belong in composables\u002F.",[54],"md","nuxt",{},{"title":351},"utils\u002F composables","\u002Fnuxt\u002Frules\u002Fstructure\u002Fno-composable-in-utils","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().",{"title":46,"description":345},"nuxt\u002Frules\u002Fstructure\u002Fno-composable-in-utils","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.","uhqpHg1VaJOFyCeF1XoTc1NGIe6OvDjqogZjR-1mR6I",1791309473772]