[{"data":1,"prerenderedAt":511},["ShallowReactive",2],{"docs:page:\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation":3,"docs:navigation:en":414,"docs:section-descriptions:\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation":505,"docs:translations:\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation":506,"docs:surroundings:\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation":508},{"id":4,"title":5,"body":6,"description":406,"extension":407,"meta":408,"navigation":409,"path":410,"seo":411,"stem":412,"__hash__":413},"docs\u002Fen\u002Fdocs\u002F1.getting-started\u002Finstallation.md","Installation",{"type":7,"value":8,"toc":395},"minimark",[9,13,17,22,25,69,85,99,103,118,128,154,158,161,166,169,189,193,200,228,232,248,255,271,274,294,298,313,331,338,344,362,378,381,391],[10,11,5],"h1",{"id":12},"installation",[14,15,16],"p",{},"This page covers what you need before you can run the repository locally, and\nroughly what \"local development\" means in this workspace.",[18,19,21],"h2",{"id":20},"prerequisites","Prerequisites",[14,23,24],{},"You need the following tools:",[26,27,28,41],"table",{},[29,30,31],"thead",{},[32,33,34,38],"tr",{},[35,36,37],"th",{},"Tool",[35,39,40],{},"Purpose",[42,43,44,53,61],"tbody",{},[32,45,46,50],{},[47,48,49],"td",{},"Node.js 24+",[47,51,52],{},"Runtime for tooling and the build",[32,54,55,58],{},[47,56,57],{},"pnpm 12+",[47,59,60],{},"Package manager for the workspace",[32,62,63,66],{},[47,64,65],{},"Git",[47,67,68],{},"Version control",[14,70,71,72,76,77,80,81,84],{},"The exact versions are pinned in the repository: ",[73,74,75],"code",{},".node-version"," pins Node.js\nand the ",[73,78,79],{},"packageManager"," field in ",[73,82,83],{},"package.json"," pins pnpm. Use Corepack or\ninstall those versions directly and the whole toolchain agrees.",[86,87,88],"blockquote",{},[14,89,90,94,95,98],{},[91,92,93],"strong",{},"Note"," — macOS users may need ",[73,96,97],{},"watchman"," for file watching if the DevTools\nwatcher reports unrelated rebuilds.",[18,100,102],{"id":101},"the-repository-and-workspace","The repository and workspace",[14,104,105,106,109,110,117],{},"The repository is a ",[91,107,108],{},"monorepo"," managed with ",[111,112,116],"a",{"href":113,"rel":114},"https:\u002F\u002Fnx.dev\u002F",[115],"nofollow","Nx"," and pnpm:",[119,120,126],"pre",{"className":121,"code":123,"language":124,"meta":125},[122],"language-text","apps\u002F    runtime and deploy units (web apps, services)\nlibs\u002F    shared libraries owned by bounded contexts\ndocs\u002F    architecture and operations documentation\ntools\u002F   developer tooling such as the `dx` CLI\n","text","",[73,127,123],{"__ignoreMap":125},[14,129,130,131,134,135,138,139,142,143,146,147,149,150,153],{},"The pnpm workspace covers ",[73,132,133],{},"apps\u002F*",", ",[73,136,137],{},"tools\u002F*"," and ",[73,140,141],{},"docs","; the libraries under\n",[73,144,145],{},"libs\u002F"," are Nx projects without their own ",[73,148,83],{},", resolved through\nworkspace aliases. Everything else in that layout is a pnpm workspace package.\nThe ",[73,151,152],{},"apps\u002Fhome"," package is the public app you are reading right now — docs and\nblog included.",[18,155,157],{"id":156},"local-development-overview","Local development overview",[14,159,160],{},"The typical loop has three steps.",[162,163,165],"h3",{"id":164},"install-the-dependencies","Install the dependencies",[14,167,168],{},"From the workspace root:",[119,170,174],{"className":171,"code":172,"language":173,"meta":125,"style":125},"language-bash shiki shiki-themes github-light github-dark","pnpm install\n","bash",[73,175,176],{"__ignoreMap":125},[177,178,181,185],"span",{"class":179,"line":180},"line",1,[177,182,184],{"class":183},"sScJk","pnpm",[177,186,188],{"class":187},"sZZnC"," install\n",[162,190,192],{"id":191},"prepare-the-nuxt-types","Prepare the Nuxt types",[14,194,195,196,199],{},"Nuxt generates the ",[73,197,198],{},".nuxt\u002F"," type files once before the first run:",[119,201,203],{"className":171,"code":202,"language":173,"meta":125,"style":125},"cd apps\u002Fhome\npnpm exec nuxt prepare\n",[73,204,205,214],{"__ignoreMap":125},[177,206,207,211],{"class":179,"line":180},[177,208,210],{"class":209},"sj4cs","cd",[177,212,213],{"class":187}," apps\u002Fhome\n",[177,215,217,219,222,225],{"class":179,"line":216},2,[177,218,184],{"class":183},[177,220,221],{"class":187}," exec",[177,223,224],{"class":187}," nuxt",[177,226,227],{"class":187}," prepare\n",[162,229,231],{"id":230},"start-the-dev-server","Start the dev server",[119,233,235],{"className":171,"code":234,"language":173,"meta":125,"style":125},"pnpm exec nuxt dev\n",[73,236,237],{"__ignoreMap":125},[177,238,239,241,243,245],{"class":179,"line":180},[177,240,184],{"class":183},[177,242,221],{"class":187},[177,244,224],{"class":187},[177,246,247],{"class":187}," dev\n",[14,249,250,251,254],{},"The dev server is then available at ",[73,252,253],{},"http:\u002F\u002Flocalhost:4200",", for example:",[119,256,258],{"className":171,"code":257,"language":173,"meta":125,"style":125},"curl -I http:\u002F\u002Flocalhost:4200\u002Fen\u002Fdocs\u002Fgetting-started\n",[73,259,260],{"__ignoreMap":125},[177,261,262,265,268],{"class":179,"line":180},[177,263,264],{"class":183},"curl",[177,266,267],{"class":209}," -I",[177,269,270],{"class":187}," http:\u002F\u002Flocalhost:4200\u002Fen\u002Fdocs\u002Fgetting-started\n",[14,272,273],{},"Run the unit tests for a single app from the workspace root:",[119,275,277],{"className":171,"code":276,"language":173,"meta":125,"style":125},"pnpm exec nx test home\n",[73,278,279],{"__ignoreMap":125},[177,280,281,283,285,288,291],{"class":179,"line":180},[177,282,184],{"class":183},[177,284,221],{"class":187},[177,286,287],{"class":187}," nx",[177,289,290],{"class":187}," test",[177,292,293],{"class":187}," home\n",[18,295,297],{"id":296},"what-happens-during-a-build","What happens during a build",[14,299,300,301,304,305,308,309,312],{},"The public app is a ",[91,302,303],{},"Cloudflare Worker with SSR",": ",[73,306,307],{},"nitro.config.ts"," selects\nthe ",[73,310,311],{},"cloudflare-module"," preset, and the content pages are prerendered at build\ntime on Node — where content queries are allowed — so no runtime database is\ninvolved. Building the Nx target runs Nuxt:",[119,314,316],{"className":171,"code":315,"language":173,"meta":125,"style":125},"npx nx build @ecoma-io\u002Fhome\n",[73,317,318],{"__ignoreMap":125},[177,319,320,323,325,328],{"class":179,"line":180},[177,321,322],{"class":183},"npx",[177,324,287],{"class":187},[177,326,327],{"class":187}," build",[177,329,330],{"class":187}," @ecoma-io\u002Fhome\n",[14,332,333,334,337],{},"The output lands in ",[73,335,336],{},"apps\u002Fhome\u002F.output",":",[119,339,342],{"className":340,"code":341,"language":124,"meta":125},[122],".output\u002Fserver\u002Findex.mjs  the Worker entry script\n.output\u002Fpublic\u002F           prerendered content HTML, one directory per route\n.output\u002Fpublic\u002F_nuxt\u002F     hashed client assets\n.output\u002Fpublic\u002F__nuxt_content\u002F  the content database dump\n",[73,343,341],{"__ignoreMap":125},[14,345,346,349,350,353,354,357,358,361],{},[73,347,348],{},"wrangler.jsonc"," points the Worker at that output and deploys the prerendered\npages as Worker static assets — ",[73,351,352],{},"nx deploy @ecoma-io\u002Fhome --configuration=staging","\n(builds first, then publishes) targets staging; use ",[73,355,356],{},"--configuration=production","\nfor the production Worker. A bare ",[73,359,360],{},"nx deploy"," without a configuration refuses\nto run — the Wrangler environment is an explicit choice.",[86,363,364],{},[14,365,366,369,370,373,374,377],{},[91,367,368],{},"Warning"," — never commit secrets into ",[73,371,372],{},".dev.vars*"," or ",[73,375,376],{},".env*",". Local Worker\nconfiguration is for development only.",[379,380],"hr",{},[14,382,383],{},[384,385,386,387],"em",{},"Next: ",[111,388,390],{"href":389},"\u002Fen\u002Fdocs\u002Fgetting-started\u002Ffirst-steps","First Steps",[392,393,394],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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":125,"searchDepth":216,"depth":216,"links":396},[397,398,399,405],{"id":20,"depth":216,"text":21},{"id":101,"depth":216,"text":102},{"id":156,"depth":216,"text":157,"children":400},[401,403,404],{"id":164,"depth":402,"text":165},3,{"id":191,"depth":402,"text":192},{"id":230,"depth":402,"text":231},{"id":296,"depth":216,"text":297},"Prerequisites and local development overview for the Ecoma monorepo.","md",{},true,"\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation",{"title":5,"description":406},"en\u002Fdocs\u002F1.getting-started\u002Finstallation","OI6vmSIcgRigBBqBjvxZ4XCOM7qe7Qal4NFX2ljCtVc",[415],{"title":416,"path":417,"stem":418,"children":419,"page":461},"En","\u002Fen","en",[420,462],{"title":421,"path":422,"stem":423,"children":424,"page":461},"Blog","\u002Fen\u002Fblog","en\u002Fblog",[425,431,437,443,449,455],{"title":426,"path":427,"stem":428,"children":429},"One URL model for every public page","\u002Fen\u002Fblog\u002Furl-model","en\u002Fblog\u002F1.url-model\u002Findex",[430],{"title":426,"path":427,"stem":428},{"title":432,"path":433,"stem":434,"children":435},"Content is resolved at build time","\u002Fen\u002Fblog\u002Fbuild-time-content","en\u002Fblog\u002F2.build-time-content\u002Findex",[436],{"title":432,"path":433,"stem":434},{"title":438,"path":439,"stem":440,"children":441},"Locale switching that never lies","\u002Fen\u002Fblog\u002Flocale-switching","en\u002Fblog\u002F3.locale-switching\u002Findex",[442],{"title":438,"path":439,"stem":440},{"title":444,"path":445,"stem":446,"children":447},"Deploying a blog as static assets","\u002Fen\u002Fblog\u002Fstatic-deployment","en\u002Fblog\u002F4.static-deployment\u002Findex",[448],{"title":444,"path":445,"stem":446},{"title":450,"path":451,"stem":452,"children":453},"A reading page is not a documentation page","\u002Fen\u002Fblog\u002Freading-first-design","en\u002Fblog\u002F5.reading-first-design\u002Findex",[454],{"title":450,"path":451,"stem":452},{"title":456,"path":457,"stem":458,"children":459},"What this blog is (and is not)","\u002Fen\u002Fblog\u002Fdemo-content-note","en\u002Fblog\u002F6.demo-content-note\u002Findex",[460],{"title":456,"path":457,"stem":458},false,{"title":463,"path":464,"stem":465,"children":466},"Overview","\u002Fen\u002Fdocs","en\u002Fdocs\u002Findex",[467,468,477,491],{"title":463,"path":464,"stem":465},{"title":469,"path":470,"stem":471,"children":472},"Getting Started","\u002Fen\u002Fdocs\u002Fgetting-started","en\u002Fdocs\u002F1.getting-started\u002Findex",[473,474,476],{"title":469,"path":470,"stem":471},{"title":390,"path":389,"stem":475},"en\u002Fdocs\u002F1.getting-started\u002Ffirst-steps",{"title":5,"path":410,"stem":412},{"title":478,"path":479,"stem":480,"children":481},"Concepts","\u002Fen\u002Fdocs\u002Fconcepts","en\u002Fdocs\u002F2.concepts\u002Findex",[482,483,487],{"title":478,"path":479,"stem":480},{"title":484,"path":485,"stem":486},"Content and Locales","\u002Fen\u002Fdocs\u002Fconcepts\u002Fcontent-and-locales","en\u002Fdocs\u002F2.concepts\u002Fcontent-and-locales",{"title":488,"path":489,"stem":490},"Public Web","\u002Fen\u002Fdocs\u002Fconcepts\u002Fpublic-web","en\u002Fdocs\u002F2.concepts\u002Fpublic-web",{"title":492,"path":493,"stem":494,"children":495},"Guides","\u002Fen\u002Fdocs\u002Fguides","en\u002Fdocs\u002F3.guides\u002Findex",[496,497,501],{"title":492,"path":493,"stem":494},{"title":498,"path":499,"stem":500},"Building a Public Page","\u002Fen\u002Fdocs\u002Fguides\u002Fbuilding-a-public-page","en\u002Fdocs\u002F3.guides\u002Fbuilding-a-public-page",{"title":502,"path":503,"stem":504},"Local Development","\u002Fen\u002Fdocs\u002Fguides\u002Flocal-development","en\u002Fdocs\u002F3.guides\u002Flocal-development",{},[418,507],"vi",[509,510],{"title":390,"path":389,"stem":475,"children":-1},{"title":478,"path":479,"stem":480,"children":-1},1791809693960]