[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-navigation":3,"docs-page-layout":166},[4,38,57,65,114,138,157],{"id":5,"group":6,"pages":7},"get-started","Get started",[8,13,18,23,28,33],{"path":9,"title":10,"description":11,"navTitle":10,"group":6,"order":12},"\u002Fdocs\u002Fgetting-started","Getting started","Create your app from the kit, run it locally with no credentials, make yourself superadmin and find where your own code goes.",1,{"path":14,"title":15,"description":16,"navTitle":15,"group":6,"order":17},"\u002Fdocs\u002Flayout","Project structure","Where code lives by where it runs, and which server\u002F directories turn a new file into a route, a job or a provider.",2,{"path":19,"title":20,"description":21,"navTitle":20,"group":6,"order":22},"\u002Fdocs\u002Fconfiguration","Configuration","starter.config.ts switches each part of the kit and its providers, environment variables hold the secrets: every key and what it changes.",3,{"path":24,"title":25,"description":26,"navTitle":25,"group":6,"order":27},"\u002Fdocs\u002Ftemplate","Updating from the kit","Keep the kit as a git remote and take each update as one commit you review, with pnpm template:update, then resolve what conflicts.",4,{"path":29,"title":30,"description":31,"navTitle":30,"group":6,"order":32},"\u002Fdocs\u002Fdeployment","Deployment","Ship the app as one Cloudflare Worker: create the resources, set the secrets, deploy main from GitHub Actions or your machine.",5,{"path":34,"title":35,"description":36,"navTitle":35,"group":6,"order":37},"\u002Fdocs\u002Fmcp","MCP server","Connect Claude Code, Cursor or VS Code to https:\u002F\u002Fnuxter.app\u002Fmcp, so your agent searches and reads these docs and their design notes.",6,{"id":39,"group":40,"pages":41},"accounts","Accounts",[42,47,52],{"path":43,"title":44,"description":45,"navTitle":44,"group":40,"order":46},"\u002Fdocs\u002Fauth","Auth","Pick the sign-in methods, add an OAuth provider, protect a route, and handle sessions, second factors and account deletion.",7,{"path":48,"title":49,"description":50,"navTitle":49,"group":40,"order":51},"\u002Fdocs\u002Ftenancy","Organizations","Scope routes and pages to an organization, and work with its members, roles, seats, invitations and a second level such as branches.",8,{"path":53,"title":54,"description":55,"navTitle":54,"group":40,"order":56},"\u002Fdocs\u002Fpermissions","Roles and permissions","Routes check permissions that an account’s role or its organization’s plan grants: checking one, adding a role, and the staff tools.",9,{"id":58,"group":59,"pages":60},"payments","Payments",[61],{"path":62,"title":59,"description":63,"navTitle":59,"group":59,"order":64},"\u002Fdocs\u002Fpayments","Sell plans through Stripe, Polar, Lemon Squeezy or Creem: define plans, connect a provider, gate features, trials, coupons and refunds.",10,{"id":66,"group":67,"pages":68},"building-blocks","Building blocks",[69,74,79,84,89,94,99,104,109],{"path":70,"title":71,"description":72,"navTitle":71,"group":67,"order":73},"\u002Fdocs\u002Fdatabase","Database","Postgres through Drizzle, on Hyperdrive in production and PGlite locally: add a table, query, transactions, migrations and seed data.",11,{"path":75,"title":76,"description":77,"navTitle":76,"group":67,"order":78},"\u002Fdocs\u002Fbackground-jobs","Background jobs","Run work after the response on Cloudflare Queues with retries: add and enqueue a job, run jobs locally, and schedule cron tasks.",12,{"path":80,"title":81,"description":82,"navTitle":81,"group":67,"order":83},"\u002Fdocs\u002Fevents","Events","React to what the kit does by adding a file to server\u002Flisteners\u002F, fire events of your own, and look up every event’s payload.",13,{"path":85,"title":86,"description":87,"navTitle":86,"group":67,"order":88},"\u002Fdocs\u002Femail","Email","Set up sending, send your own mail with deliverEmail, change the templates and wording, handle unsubscribes and add a provider.",14,{"path":90,"title":91,"description":92,"navTitle":91,"group":67,"order":93},"\u002Fdocs\u002Fcontact","Contact","A \u002Fcontact page that mails you a message or shows your address after a Turnstile check: choose the channels, set the address, know the limits.",15,{"path":95,"title":96,"description":97,"navTitle":96,"group":67,"order":98},"\u002Fdocs\u002Fnotifications","Notifications","The dashboard bell: add a notification type, send one with notify(), and how categories, opt-outs and retention apply.",16,{"path":100,"title":101,"description":102,"navTitle":101,"group":67,"order":103},"\u002Fdocs\u002Fstorage","Storage","Uploads in R2 with one policy per purpose: add a purpose, accept an upload, replace or delete a file, and serve it to its owner.",17,{"path":105,"title":106,"description":107,"navTitle":106,"group":67,"order":108},"\u002Fdocs\u002Ffeature-flags","Feature flags","Declare typed flags in starter.config.ts, read them with flag() or useFlag(), roll them out by rule or percentage, and add a provider.",18,{"path":110,"title":111,"description":112,"navTitle":111,"group":67,"order":113},"\u002Fdocs\u002Fai","AI","Call models from server code by role: text, images, speech, transcription, embeddings and video, with provider fallbacks.",19,{"id":115,"group":116,"pages":117},"web","Web",[118,123,128,133],{"path":119,"title":120,"description":121,"navTitle":120,"group":116,"order":122},"\u002Fdocs\u002Fsecurity-headers","Security headers","The Content-Security-Policy and hardening headers on every response: allow another origin, keep tokens out of Referer, accept cross-site posts.",20,{"path":124,"title":125,"description":126,"navTitle":125,"group":116,"order":127},"\u002Fdocs\u002Frate-limiting","Rate limiting","Cap how often a caller hits a route with requireRateLimit, count only failures, space out sends, and protect the zone.",21,{"path":129,"title":130,"description":131,"navTitle":130,"group":116,"order":132},"\u002Fdocs\u002Fanalytics","Analytics","Product analytics and ad conversions sent from the server with no browser script: add an event, connect a provider, and handle consent.",22,{"path":134,"title":135,"description":136,"navTitle":135,"group":116,"order":137},"\u002Fdocs\u002Fobservability","Observability","Find a failed request by its id, send faults to Sentry or Better Stack, report an error you caught, and change the error page.",23,{"id":139,"group":140,"pages":141},"content-and-look","Content and look",[142,147,152],{"path":143,"title":144,"description":145,"navTitle":144,"group":140,"order":146},"\u002Fdocs\u002Fblog","Blog","Markdown posts with an RSS feed per language, and workflows that draft posts with an AI model and open each one as a pull request.",24,{"path":148,"title":149,"description":150,"navTitle":149,"group":140,"order":151},"\u002Fdocs\u002Flanguages","Languages","Add or remove a language, write copy in the locale files, and write code, refusals and links that follow the reader’s language.",25,{"path":153,"title":154,"description":155,"navTitle":154,"group":140,"order":156},"\u002Fdocs\u002Ftheme","Theme","Change the brand colour and font, and build dashboard sections, list pages, loading placeholders and charts that match the kit.",26,{"id":158,"group":159,"pages":160},"quality","Quality",[161],{"path":162,"title":163,"description":164,"navTitle":163,"group":159,"order":165},"\u002Fdocs\u002Ftesting","Testing","Unit tests in Node, component tests in a real Nuxt app and Playwright end to end: test a route or a component, and what CI runs.",27,{"page":167,"surround":997,"linksToKit":1000},{"path":14,"title":15,"description":16,"navTitle":15,"group":6,"seo":168,"body":170},{"title":169,"description":16},"Nuxt 4 SaaS project structure",{"type":171,"value":172,"toc":989},"minimark",[173,177,197,202,425,431,434,464,475,478,576,587,666,706,714,718,746,781,785,807,832,849,852,913,927,931,985],[174,175,15],"h1",{"id":176},"project-structure",[178,179,180,181,185,186,189,190,193,194,196],"p",{},"The kit's code is split by where it runs: ",[182,183,184],"code",{},"app\u002F"," in the browser, ",[182,187,188],{},"server\u002F"," on\nthe Worker, ",[182,191,192],{},"shared\u002F"," in both. Check this page before you add a file under\n",[182,195,188],{},": in some directories a new file becomes a route, a job or a provider,\nand in others it does nothing until you import it.",[198,199,201],"h2",{"id":200},"top-level","Top level",[203,204,205,218],"table",{},[206,207,208],"thead",{},[209,210,211,215],"tr",{},[212,213,214],"th",{},"Path",[212,216,217],{},"What lives there",[219,220,221,242,255,268,282,300,317,329,341,351,379,393,409],"tbody",{},[209,222,223,235],{},[224,225,226],"td",{},[227,228,233],"a",{"href":229,"rel":230,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Fapp",[231],"nofollow","Licensees only",[182,234,184],{},[224,236,237,238,241],{},"The Vue app, Nuxt 4's ",[182,239,240],{},"srcDir",": pages, components, layouts, composables, Pinia stores",[209,243,244,252],{},[224,245,246],{},[227,247,250],{"href":248,"rel":249,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Fserver",[231],[182,251,188],{},[224,253,254],{},"Everything that runs on the Worker",[209,256,257,265],{},[224,258,259],{},[227,260,263],{"href":261,"rel":262,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Fshared",[231],[182,264,192],{},[224,266,267],{},"Types, zod schemas and pure helpers that both the app and the server import",[209,269,270,279],{},[224,271,272],{},[227,273,276],{"href":274,"rel":275,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Fmodules",[231],[182,277,278],{},"modules\u002F",[224,280,281],{},"Nuxt modules that run at build time and generate the registries",[209,283,284,293],{},[224,285,286],{},[227,287,290],{"href":288,"rel":289,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Fbuild",[231],[182,291,292],{},"build\u002F",[224,294,295,296,299],{},"Plain functions ",[182,297,298],{},"nuxt.config.ts"," calls while it loads",[209,301,302,311],{},[224,303,304],{},[227,305,308],{"href":306,"rel":307,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Femails",[231],[182,309,310],{},"emails\u002F",[224,312,313,314,316],{},"Mail templates, written as Vue components (",[227,315,86],{"href":85},")",[209,318,319,324],{},[224,320,321],{},[182,322,323],{},"content\u002F",[224,325,326,327,316],{},"Blog posts and legal pages, one folder per locale (",[227,328,144],{"href":143},[209,330,331,336],{},[224,332,333],{},[182,334,335],{},"i18n\u002Flocales\u002F",[224,337,338,339,316],{},"One JSON catalogue per locale (",[227,340,149],{"href":148},[209,342,343,348],{},[224,344,345],{},[182,346,347],{},"public\u002F",[224,349,350],{},"Static files, served as they are",[209,352,353,362],{},[224,354,355],{},[227,356,359],{"href":357,"rel":358,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Ftest",[231],[182,360,361],{},"test\u002F",[224,363,364,365,368,369,372,373,376,377,316],{},"The ",[182,366,367],{},"unit",", ",[182,370,371],{},"nuxt"," and ",[182,374,375],{},"e2e"," suites and their shared helpers (",[227,378,163],{"href":162},[209,380,381,390],{},[224,382,383],{},[227,384,387],{"href":385,"rel":386,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Ftree\u002Fmain\u002Fscripts",[231],[182,388,389],{},"scripts\u002F",[224,391,392],{},"Node scripts for the database, the seed, the blog pipeline and template updates. Never bundled",[209,394,395,404],{},[224,396,397],{},[227,398,401],{"href":399,"rel":400,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fstarter.config.ts",[231],[182,402,403],{},"starter.config.ts",[224,405,406,407,316],{},"Which parts are on, and with which providers (",[227,408,20],{"href":19},[209,410,411,420],{},[224,412,413],{},[227,414,417],{"href":415,"rel":416,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fwrangler.jsonc",[231],[182,418,419],{},"wrangler.jsonc",[224,421,422,423,316],{},"Cloudflare bindings, queues and crons (",[227,424,30],{"href":29},[178,426,427,428,430],{},"Which of these are yours and which the kit updates is on\n",[227,429,25],{"href":24},".",[198,432,188],{"id":433},"server",[178,435,436,437,440,441,444,445,448,449,452,453,456,457,459,460,463],{},"Nitro scans six directories. A file in ",[182,438,439],{},"api\u002F"," or ",[182,442,443],{},"routes\u002F"," is a route,\n",[182,446,447],{},"middleware\u002F"," runs on every request, ",[182,450,451],{},"plugins\u002F"," runs once when the Worker\nstarts, and ",[182,454,455],{},"tasks\u002F"," holds the tasks the cron runs\n(",[227,458,76],{"href":75},"). Every named export in ",[182,461,462],{},"utils\u002F","\nbecomes a global in server code.",[178,465,466,467,474],{},"Middleware runs in filename order, so the name you give a new file decides\nwhere it sits in the chain.\n",[227,468,471],{"href":469,"rel":470,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Ftest\u002Funit\u002Fmiddleware-order.test.ts",[231],[182,472,473],{},"test\u002Funit\u002Fmiddleware-order.test.ts","\npins the order the kit relies on.",[178,476,477],{},"The kit's own build code scans a few more:",[203,479,480,497],{},[206,481,482],{},[209,483,484,487,494],{},[212,485,486],{},"Directory",[212,488,489,490,493],{},"A ",[182,491,492],{},".ts"," file there becomes",[212,495,496],{},"Scanned by",[219,498,499,518,537,556],{},[209,500,501,506,509],{},[224,502,503],{},[182,504,505],{},"server\u002Fjobs\u002F",[224,507,508],{},"A background job, with the filename as kind",[224,510,511],{},[227,512,515],{"href":513,"rel":514,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fmodules\u002Fjobs-registry.ts",[231],[182,516,517],{},"modules\u002Fjobs-registry.ts",[209,519,520,525,528],{},[224,521,522],{},[182,523,524],{},"server\u002Flisteners\u002F",[224,526,527],{},"An event listener",[224,529,530],{},[227,531,534],{"href":532,"rel":533,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fmodules\u002Flisteners-registry.ts",[231],[182,535,536],{},"modules\u002Flisteners-registry.ts",[209,538,539,544,547],{},[224,540,541],{},[182,542,543],{},"server\u002F{ai,email,flags,monitoring,payments}\u002Fadapters\u002Fcustom\u002F",[224,545,546],{},"A provider, with the filename as its id",[224,548,549],{},[227,550,553],{"href":551,"rel":552,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fbuild\u002Fcustom-adapters.ts",[231],[182,554,555],{},"build\u002Fcustom-adapters.ts",[209,557,558,566,569],{},[224,559,560,368,563],{},[182,561,562],{},"server\u002Fsignals\u002Fanalytics\u002Fcustom\u002F",[182,564,565],{},"server\u002Fsignals\u002Fmarketing\u002Fcustom\u002F",[224,567,568],{},"An analytics or marketing provider",[224,570,571],{},[227,572,574],{"href":551,"rel":573,"title":232},[231],[182,575,555],{},[178,577,578,579,582,583,586],{},"The adapter ",[182,580,581],{},"custom\u002F"," directories don't ship; create one when you add a\nprovider. The registries read these directories when Nuxt starts, so restart\n",[182,584,585],{},"pnpm dev"," after you add, rename or delete a file in them.",[178,588,589,590,592,593,596,597,368,600,368,603,368,606,368,609,368,612,368,615,596,618,368,621,368,624,368,627,368,630,368,633,596,636,372,639,642,643,646,647,650,651,658,659,661,662,665],{},"Everything else under ",[182,591,188],{}," is plain code that nothing scans: ",[182,594,595],{},"ai\u002F",",\n",[182,598,599],{},"auth\u002F",[182,601,602],{},"cache\u002F",[182,604,605],{},"contact\u002F",[182,607,608],{},"database\u002F",[182,610,611],{},"durable\u002F",[182,613,614],{},"email\u002F",[182,616,617],{},"events\u002F",[182,619,620],{},"flags\u002F",[182,622,623],{},"monitoring\u002F",[182,625,626],{},"notifications\u002F",[182,628,629],{},"payments\u002F",[182,631,632],{},"signals\u002F",[182,634,635],{},"storage\u002F",[182,637,638],{},"tenancy\u002F",[182,640,641],{},"types\u002F",". The two handlers in ",[182,644,645],{},"contact\u002Froutes\u002F"," are registered\nby name, one per entry in ",[182,648,649],{},"contact.channels",", from\n",[227,652,655],{"href":653,"rel":654,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fmodules\u002Fcontact-routes.ts",[231],[182,656,657],{},"modules\u002Fcontact-routes.ts","\n(",[227,660,91],{"href":90},"), so a file you add there is not a route. Import the\nrest through the ",[182,663,664],{},"#server\u002F*"," alias:",[667,668,673],"pre",{"className":669,"code":670,"language":671,"meta":672,"style":672},"language-ts shiki shiki-themes github-light github-light github-dark","import { defineListener } from '#server\u002Fevents\u002Ftypes'\nimport { requireOrgScope } from '#server\u002Ftenancy\u002Fscope'\n","ts","",[182,674,675,694],{"__ignoreMap":672},[676,677,679,683,687,690],"span",{"class":678,"line":12},"line",[676,680,682],{"class":681},"s8jYJ","import",[676,684,686],{"class":685},"sxrX7"," { defineListener } ",[676,688,689],{"class":681},"from",[676,691,693],{"class":692},"sIIMD"," '#server\u002Fevents\u002Ftypes'\n",[676,695,696,698,701,703],{"class":678,"line":17},[676,697,682],{"class":681},[676,699,700],{"class":685}," { requireOrgScope } ",[676,702,689],{"class":681},[676,704,705],{"class":692}," '#server\u002Ftenancy\u002Fscope'\n",[178,707,708,709,711,712,430],{},"Nuxt refuses an import from ",[182,710,188],{}," in app code, so nothing here can reach\nthe browser bundle by accident. Code that both sides need goes in ",[182,713,192],{},[198,715,717],{"id":716},"modules-and-build","modules\u002F and build\u002F",[178,719,720,721,723,724,726,727,730,731,368,734,737,738,741,742,745],{},"Both run at build time. A file in ",[182,722,278],{}," is a Nuxt module: Nuxt registers\nevery file directly under ",[182,725,278],{}," and every ",[182,728,729],{},"modules\u002F*\u002Findex.ts",". The kit's\nmodules generate the registries (",[182,732,733],{},"#jobs-registry",[182,735,736],{},"#payments-registry"," and the\nrest), add routes, and fail the build when the config doesn't add up.\n",[182,739,740],{},"modules\u002Fsupport\u002F"," has no ",[182,743,744],{},"index.ts",", so the helpers there are shared by the\nmodules and never registered.",[178,747,748,750,751,753,754,756,757,764,765,772,773,775,776,778,779,430],{},[182,749,292],{}," holds plain functions that ",[182,752,298],{}," calls while it is being\nevaluated, before Nuxt or its aliases exist, so it imports them by relative\npath. That covers reading ",[182,755,419],{},", the binding checks in\n",[227,758,761],{"href":759,"rel":760,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fbuild\u002Fassertions.ts",[231],[182,762,763],{},"build\u002Fassertions.ts",", the runtime-config slots in\n",[227,766,769],{"href":767,"rel":768,"title":232},"https:\u002F\u002Fgithub.com\u002Fnuxter-app\u002Fkit\u002Fblob\u002Fmain\u002Fbuild\u002Fruntime-config.ts",[231],[182,770,771],{},"build\u002Fruntime-config.ts"," and the locale list.\nNothing in ",[182,774,292],{}," is bundled. If your code needs Nuxt, write a module; if\n",[182,777,298],{}," needs a value from it, put it in ",[182,780,292],{},[198,782,784],{"id":783},"app-and-shared","app\u002F and shared\u002F",[178,786,787,789,790,368,793,372,796,798,799,802,803,806],{},[182,788,184],{}," follows Nuxt's defaults: ",[182,791,792],{},"components\u002F",[182,794,795],{},"composables\u002F",[182,797,462],{}," are\nauto-imported in the app, and ",[182,800,801],{},"pages\u002F"," is the router. ",[182,804,805],{},"app\u002Ftypes\u002F"," holds the\ntypes of the kit's own components and queries.",[178,808,809,810,812,813,816,817,820,821,372,824,827,828,831],{},"In ",[182,811,192],{},", the exports of ",[182,814,815],{},"shared\u002Futils\u002F"," are auto-imported on both sides,\nand so are the types in ",[182,818,819],{},"shared\u002Ftypes\u002F",", such as ",[182,822,823],{},"PlanId",[182,825,826],{},"Permission",".\nImport anything else there through ",[182,829,830],{},"#shared\u002F*",":",[667,833,835],{"className":669,"code":834,"language":671,"meta":672,"style":672},"import { planRefSlots } from '#shared\u002Fpayments\u002Fref-slots'\n",[182,836,837],{"__ignoreMap":672},[676,838,839,841,844,846],{"class":678,"line":12},[676,840,682],{"class":681},[676,842,843],{"class":685}," { planRefSlots } ",[676,845,689],{"class":681},[676,847,848],{"class":692}," '#shared\u002Fpayments\u002Fref-slots'\n",[198,850,361],{"id":851},"test",[203,853,854,866],{},[206,855,856],{},[209,857,858,860,863],{},[212,859,486],{},[212,861,862],{},"Runner",[212,864,865],{},"Environment",[219,867,868,883,897],{},[209,869,870,875,880],{},[224,871,872],{},[182,873,874],{},"test\u002Funit",[224,876,877,878],{},"vitest, project ",[182,879,367],{},[224,881,882],{},"Node",[209,884,885,890,894],{},[224,886,887],{},[182,888,889],{},"test\u002Fnuxt",[224,891,877,892],{},[182,893,371],{},[224,895,896],{},"A built Nuxt app",[209,898,899,904,907],{},[224,900,901],{},[182,902,903],{},"test\u002Fe2e",[224,905,906],{},"Playwright",[224,908,909,910],{},"A running ",[182,911,912],{},"nuxt dev",[178,914,915,918,919,922,923,926],{},[182,916,917],{},"test\u002Fhelpers"," is shared by the two vitest projects. ",[182,920,921],{},"pnpm test --run"," runs\nboth; ",[182,924,925],{},"pnpm test:e2e"," runs Playwright.",[198,928,930],{"id":929},"good-to-know","Good to know",[932,933,934,946,955,968],"ul",{},[935,936,937,938,940,941,372,943,945],"li",{},"Every ",[182,939,492],{}," file in ",[182,942,505],{},[182,944,524],{}," is registered as\na job or a listener. Keep helpers out of both.",[935,947,948,949,440,952,954],{},"An export added to ",[182,950,951],{},"server\u002Futils\u002F",[182,953,815],{}," becomes a global, and\ncan collide with an existing auto-import. Put a helper you don't want global\nsomewhere else and import it.",[935,956,957,958,372,961,658,964,967],{},"Vitest collects only files directly inside ",[182,959,960],{},"test\u002Funit\u002F",[182,962,963],{},"test\u002Fnuxt\u002F",[182,965,966],{},"test\u002Funit\u002F*.test.ts","). A test in a subfolder never runs.",[935,969,970,971,973,974,977,978,981,982,430],{},"Code in ",[182,972,292],{}," runs before Nuxt's aliases exist. Import by relative path\nthere, as its files do with ",[182,975,976],{},"..\u002Fstarter.config",", never through ",[182,979,980],{},"~~\u002F"," or\n",[182,983,984],{},"#shared\u002F",[986,987,988],"style",{},"html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}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);}",{"title":672,"searchDepth":17,"depth":17,"links":990},[991,992,993,994,995,996],{"id":200,"depth":17,"text":201},{"id":433,"depth":17,"text":188},{"id":716,"depth":17,"text":717},{"id":783,"depth":17,"text":784},{"id":851,"depth":17,"text":361},{"id":929,"depth":17,"text":930},[998,999],{"path":9,"title":10,"description":11,"navTitle":10,"group":6,"order":12},{"path":19,"title":20,"description":21,"navTitle":20,"group":6,"order":22},true]