[{"data":1,"prerenderedAt":382},["ShallowReactive",2],{"docs:page:\u002Fen\u002Fdocs\u002Fguides\u002Flocal-development":3,"docs:navigation:en":287,"docs:section-descriptions:\u002Fen\u002Fdocs\u002Fguides\u002Flocal-development":376,"docs:translations:\u002Fen\u002Fdocs\u002Fguides\u002Flocal-development":377,"docs:surroundings:\u002Fen\u002Fdocs\u002Fguides\u002Flocal-development":379},{"id":4,"title":5,"body":6,"description":279,"extension":280,"meta":281,"navigation":282,"path":283,"seo":284,"stem":285,"__hash__":286},"docs\u002Fen\u002Fdocs\u002F3.guides\u002Flocal-development.md","Local Development",{"type":7,"value":8,"toc":272},"minimark",[9,13,17,22,25,64,87,91,94,102,110,114,121,138,144,148,151,171,174,178,181,199,214,232,235,250,253,268],[10,11,5],"h1",{"id":12},"local-development",[14,15,16],"p",{},"This guide walks through the everyday development loop for a public app.",[18,19,21],"h2",{"id":20},"_1-start-the-app","1. Start the app",[14,23,24],{},"From the workspace root, start the public app dev server:",[26,27,32],"pre",{"className":28,"code":29,"language":30,"meta":31,"style":31},"language-bash shiki shiki-themes github-light github-dark","cd apps\u002Fhome\npnpm exec nuxt dev\n","bash","",[33,34,35,48],"code",{"__ignoreMap":31},[36,37,40,44],"span",{"class":38,"line":39},"line",1,[36,41,43],{"class":42},"sj4cs","cd",[36,45,47],{"class":46},"sZZnC"," apps\u002Fhome\n",[36,49,51,55,58,61],{"class":38,"line":50},2,[36,52,54],{"class":53},"sScJk","pnpm",[36,56,57],{"class":46}," exec",[36,59,60],{"class":46}," nuxt",[36,62,63],{"class":46}," dev\n",[14,65,66,67,70,71,74,75,78,79,82,83,86],{},"The server listens on ",[33,68,69],{},"http:\u002F\u002Flocalhost:4200"," — the port is pinned in\n",[33,72,73],{},"devServer"," in the app's ",[33,76,77],{},"nuxt.config.ts",". The Nx target ",[33,80,81],{},"serve"," runs the same\ncommand: ",[33,84,85],{},"npx nx serve @ecoma-io\u002Fhome",".",[18,88,90],{"id":89},"_2-inspect-a-page","2. Inspect a page",[14,92,93],{},"Open a document in the browser, for example:",[26,95,100],{"className":96,"code":98,"language":99,"meta":31},[97],"language-text","http:\u002F\u002Flocalhost:4200\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation\n","text",[33,101,98],{"__ignoreMap":31},[14,103,104,105,109],{},"Look at the rendered page: the header with global navigation and locale\nswitcher, the docs sidebar, breadcrumbs, the table of contents, and the\nprevious\u002Fnext links. Use the browser ",[106,107,108],"em",{},"View Source"," to confirm the page is\nserver-rendered.",[18,111,113],{"id":112},"_3-change-content","3. Change content",[14,115,116,117,120],{},"Markdown content lives under ",[33,118,119],{},"apps\u002Fhome\u002Fcontent",". Edit an English page and open\nits Vietnamese counterpart to see both sides:",[26,122,124],{"className":28,"code":123,"language":30,"meta":31,"style":31},"# pick a page, e.g.\n$EDITOR apps\u002Fhome\u002Fcontent\u002Fen\u002Fdocs\u002Fgetting-started\u002Flocal-development.md\n",[33,125,126,132],{"__ignoreMap":31},[36,127,128],{"class":38,"line":39},[36,129,131],{"class":130},"sJ8bj","# pick a page, e.g.\n",[36,133,134],{"class":38,"line":50},[36,135,137],{"class":136},"sVt8B","$EDITOR apps\u002Fhome\u002Fcontent\u002Fen\u002Fdocs\u002Fgetting-started\u002Flocal-development.md\n",[14,139,140,143],{},[33,141,142],{},"nuxt dev"," picks up the change; the page reloads with the new content.",[18,145,147],{"id":146},"_4-run-tests","4. Run tests",[14,149,150],{},"From the workspace root, run the unit tests:",[26,152,154],{"className":28,"code":153,"language":30,"meta":31,"style":31},"pnpm exec nx test home\n",[33,155,156],{"__ignoreMap":31},[36,157,158,160,162,165,168],{"class":38,"line":39},[36,159,54],{"class":53},[36,161,57],{"class":46},[36,163,164],{"class":46}," nx",[36,166,167],{"class":46}," test",[36,169,170],{"class":46}," home\n",[14,172,173],{},"This runs the Vitest suites colocated with the home app — including the\npath-validation and content-resolution tests.",[18,175,177],{"id":176},"_5-build","5. Build",[14,179,180],{},"The public app is a Cloudflare Worker with SSR; the production build also\nprerenders every content page:",[26,182,184],{"className":28,"code":183,"language":30,"meta":31,"style":31},"npx nx build @ecoma-io\u002Fhome\n",[33,185,186],{"__ignoreMap":31},[36,187,188,191,193,196],{"class":38,"line":39},[36,189,190],{"class":53},"npx",[36,192,164],{"class":46},[36,194,195],{"class":46}," build",[36,197,198],{"class":46}," @ecoma-io\u002Fhome\n",[14,200,201,202,205,206,209,210,213],{},"The output lands in ",[33,203,204],{},"apps\u002Fhome\u002F.output"," — the Worker entry in ",[33,207,208],{},"server\u002F"," plus\nprerendered HTML and assets in ",[33,211,212],{},"public\u002F",". One Nx target consumes that output:",[215,216,217],"ul",{},[218,219,220,223,224,227,228,231],"li",{},[33,221,222],{},"npx nx deploy @ecoma-io\u002Fhome --configuration=staging"," publishes it to\nCloudflare as the staging Worker (",[33,225,226],{},"build"," runs first automatically); use\n",[33,229,230],{},"--configuration=production"," for the production Worker — a bare deploy\nwithout a configuration refuses to run.",[14,233,234],{},"To inspect the prerendered pages without deploying, point any static file\nserver at the output directory, for example:",[26,236,238],{"className":28,"code":237,"language":30,"meta":31,"style":31},"npx serve apps\u002Fhome\u002F.output\u002Fpublic\n",[33,239,240],{"__ignoreMap":31},[36,241,242,244,247],{"class":38,"line":39},[36,243,190],{"class":53},[36,245,246],{"class":46}," serve",[36,248,249],{"class":46}," apps\u002Fhome\u002F.output\u002Fpublic\n",[251,252],"hr",{},[14,254,255],{},[106,256,257,258,263,264],{},"Previous: ",[259,260,262],"a",{"href":261},"\u002Fen\u002Fdocs\u002Fguides","Guides"," · Next: ",[259,265,267],{"href":266},"\u002Fen\u002Fdocs\u002Fguides\u002Fbuilding-a-public-page","Building a Public Page",[269,270,271],"style",{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":31,"searchDepth":50,"depth":50,"links":273},[274,275,276,277,278],{"id":20,"depth":50,"text":21},{"id":89,"depth":50,"text":90},{"id":112,"depth":50,"text":113},{"id":146,"depth":50,"text":147},{"id":176,"depth":50,"text":177},"A concrete development loop — start the app, inspect a page, change content, run tests, build.","md",{},true,"\u002Fen\u002Fdocs\u002Fguides\u002Flocal-development",{"title":5,"description":279},"en\u002Fdocs\u002F3.guides\u002Flocal-development","K1tt9dwu6HIJi8k2JnmhuoQQvp1sg9M1hQzgycqchas",[288],{"title":289,"path":290,"stem":291,"children":292,"page":334},"En","\u002Fen","en",[293,335],{"title":294,"path":295,"stem":296,"children":297,"page":334},"Blog","\u002Fen\u002Fblog","en\u002Fblog",[298,304,310,316,322,328],{"title":299,"path":300,"stem":301,"children":302},"One URL model for every public page","\u002Fen\u002Fblog\u002Furl-model","en\u002Fblog\u002F1.url-model\u002Findex",[303],{"title":299,"path":300,"stem":301},{"title":305,"path":306,"stem":307,"children":308},"Content is resolved at build time","\u002Fen\u002Fblog\u002Fbuild-time-content","en\u002Fblog\u002F2.build-time-content\u002Findex",[309],{"title":305,"path":306,"stem":307},{"title":311,"path":312,"stem":313,"children":314},"Locale switching that never lies","\u002Fen\u002Fblog\u002Flocale-switching","en\u002Fblog\u002F3.locale-switching\u002Findex",[315],{"title":311,"path":312,"stem":313},{"title":317,"path":318,"stem":319,"children":320},"Deploying a blog as static assets","\u002Fen\u002Fblog\u002Fstatic-deployment","en\u002Fblog\u002F4.static-deployment\u002Findex",[321],{"title":317,"path":318,"stem":319},{"title":323,"path":324,"stem":325,"children":326},"A reading page is not a documentation page","\u002Fen\u002Fblog\u002Freading-first-design","en\u002Fblog\u002F5.reading-first-design\u002Findex",[327],{"title":323,"path":324,"stem":325},{"title":329,"path":330,"stem":331,"children":332},"What this blog is (and is not)","\u002Fen\u002Fblog\u002Fdemo-content-note","en\u002Fblog\u002F6.demo-content-note\u002Findex",[333],{"title":329,"path":330,"stem":331},false,{"title":336,"path":337,"stem":338,"children":339},"Overview","\u002Fen\u002Fdocs","en\u002Fdocs\u002Findex",[340,341,355,369],{"title":336,"path":337,"stem":338},{"title":342,"path":343,"stem":344,"children":345},"Getting Started","\u002Fen\u002Fdocs\u002Fgetting-started","en\u002Fdocs\u002F1.getting-started\u002Findex",[346,347,351],{"title":342,"path":343,"stem":344},{"title":348,"path":349,"stem":350},"First Steps","\u002Fen\u002Fdocs\u002Fgetting-started\u002Ffirst-steps","en\u002Fdocs\u002F1.getting-started\u002Ffirst-steps",{"title":352,"path":353,"stem":354},"Installation","\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation","en\u002Fdocs\u002F1.getting-started\u002Finstallation",{"title":356,"path":357,"stem":358,"children":359},"Concepts","\u002Fen\u002Fdocs\u002Fconcepts","en\u002Fdocs\u002F2.concepts\u002Findex",[360,361,365],{"title":356,"path":357,"stem":358},{"title":362,"path":363,"stem":364},"Content and Locales","\u002Fen\u002Fdocs\u002Fconcepts\u002Fcontent-and-locales","en\u002Fdocs\u002F2.concepts\u002Fcontent-and-locales",{"title":366,"path":367,"stem":368},"Public Web","\u002Fen\u002Fdocs\u002Fconcepts\u002Fpublic-web","en\u002Fdocs\u002F2.concepts\u002Fpublic-web",{"title":262,"path":261,"stem":370,"children":371},"en\u002Fdocs\u002F3.guides\u002Findex",[372,373,375],{"title":262,"path":261,"stem":370},{"title":267,"path":266,"stem":374},"en\u002Fdocs\u002F3.guides\u002Fbuilding-a-public-page",{"title":5,"path":283,"stem":285},{},[291,378],"vi",[380,381],{"title":267,"path":266,"stem":374,"children":-1},null,1791809693960]