[{"data":1,"prerenderedAt":327},["ShallowReactive",2],{"docs:page:\u002Fen\u002Fdocs\u002Fguides\u002Fbuilding-a-public-page":3,"docs:navigation:en":230,"docs:section-descriptions:\u002Fen\u002Fdocs\u002Fguides\u002Fbuilding-a-public-page":321,"docs:translations:\u002Fen\u002Fdocs\u002Fguides\u002Fbuilding-a-public-page":322,"docs:surroundings:\u002Fen\u002Fdocs\u002Fguides\u002Fbuilding-a-public-page":324},{"id":4,"title":5,"body":6,"description":222,"extension":223,"meta":224,"navigation":225,"path":226,"seo":227,"stem":228,"__hash__":229},"docs\u002Fen\u002Fdocs\u002F3.guides\u002Fbuilding-a-public-page.md","Building a Public Page",{"type":7,"value":8,"toc":214},"minimark",[9,13,17,28,33,36,80,83,91,94,145,148,156,166,172,175,179,190,196,199,210],[10,11,5],"h1",{"id":12},"building-a-public-page",[14,15,16],"p",{},"A public page on Ecoma is a composition of four layers:",[18,19,25],"pre",{"className":20,"code":22,"language":23,"meta":24},[21],"language-text","app\u002Flayout      →  PublicShell, global navigation, mount topology\n        ↓\napp\u002Fi18n        →  locale dimension: registry, parse, switch\n        ↓\ncontent         →  localized markdown rendered from the content tree\n","text","",[26,27,22],"code",{"__ignoreMap":24},[29,30,32],"h2",{"id":31},"_1-the-application-owns-routing-and-content","1. The application owns routing and content",[14,34,35],{},"The app defines one file-based route for all documentation content. The\nroute validates the pathname against the shared topology contract and then\nresolves a document from the content collection:",[18,37,41],{"className":38,"code":39,"language":40,"meta":24,"style":24},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F pseudo-code for the docs route\nconst layout = parsePublicLayoutPath(route.path);\n\u002F\u002F accept only kind === 'localized' && mount === 'docs'\n","ts",[26,42,43,52,74],{"__ignoreMap":24},[44,45,48],"span",{"class":46,"line":47},"line",1,[44,49,51],{"class":50},"sJ8bj","\u002F\u002F pseudo-code for the docs route\n",[44,53,55,59,63,66,70],{"class":46,"line":54},2,[44,56,58],{"class":57},"szBVR","const",[44,60,62],{"class":61},"sj4cs"," layout",[44,64,65],{"class":57}," =",[44,67,69],{"class":68},"sScJk"," parsePublicLayoutPath",[44,71,73],{"class":72},"sVt8B","(route.path);\n",[44,75,77],{"class":46,"line":76},3,[44,78,79],{"class":50},"\u002F\u002F accept only kind === 'localized' && mount === 'docs'\n",[14,81,82],{},"If the topology is invalid, the route is rejected before any content lookup; if\nthe content does not exist, the page is a 404.",[29,84,86,87,90],{"id":85},"_2-applayout-provides-the-shell","2. ",[26,88,89],{},"app\u002Flayout"," provides the shell",[14,92,93],{},"Every docs page renders the shared shell instead of its own header and footer:",[18,95,99],{"className":96,"code":97,"language":98,"meta":24,"style":24},"language-vue shiki shiki-themes github-light github-dark","\u003CPublicShell :path=\"route.path\">\n  \u003C!-- docs content -->\n\u003C\u002FPublicShell>\n","vue",[26,100,101,131,136],{"__ignoreMap":24},[44,102,103,106,110,113,116,119,123,126,128],{"class":46,"line":47},[44,104,105],{"class":72},"\u003C",[44,107,109],{"class":108},"s9eBZ","PublicShell",[44,111,112],{"class":72}," :",[44,114,115],{"class":68},"path",[44,117,118],{"class":72},"=",[44,120,122],{"class":121},"sZZnC","\"",[44,124,125],{"class":72},"route.path",[44,127,122],{"class":121},[44,129,130],{"class":72},">\n",[44,132,133],{"class":46,"line":54},[44,134,135],{"class":72},"  \u003C!-- docs content -->\n",[44,137,138,141,143],{"class":46,"line":76},[44,139,140],{"class":72},"\u003C\u002F",[44,142,109],{"class":108},[44,144,130],{"class":72},[14,146,147],{},"The shell parses the pathname once, renders the header (brand, global\nnavigation, locale switcher) and the footer, and never needs reimplementing per\napp.",[29,149,151,152,155],{"id":150},"_3-appi18n-owns-the-locale","3. ",[26,153,154],{},"app\u002Fi18n"," owns the locale",[14,157,158,159,161,162,165],{},"Locales, their metadata, and switching between them all come from ",[26,160,154],{},".\nWhen you switch language on a docs page, the shell calls ",[26,163,164],{},"switchLocale()"," to\nkeep the same document and change only the locale segment:",[18,167,170],{"className":168,"code":169,"language":23,"meta":24},[21],"\u002Fen\u002Fdocs\u002Fconcepts\u002Fpublic-web\n        ↓\n\u002Fvi\u002Fdocs\u002Fconcepts\u002Fpublic-web\n",[26,171,169],{"__ignoreMap":24},[14,173,174],{},"The app never reimplements locale parsing or path rewriting.",[29,176,178],{"id":177},"_4-content-renders-locally","4. Content renders locally",[14,180,181,182,185,186,189],{},"The page queries the ",[26,183,184],{},"docs"," collection by the exact pathname and renders the\ndocument with ",[26,187,188],{},"ContentRenderer",", so the typography you see — headings, code\nblocks, tables, blockquotes — is the app-local rendering, not a global\nrendering service.",[191,192,193],"blockquote",{},[14,194,195],{},"This page is an illustration of the composition, not a specification of a\ngeneric page-builder framework. The actual contracts live in the repository.",[197,198],"hr",{},[14,200,201],{},[202,203,204,205],"em",{},"Previous: ",[206,207,209],"a",{"href":208},"\u002Fen\u002Fdocs\u002Fguides\u002Flocal-development","Local Development",[211,212,213],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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 .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":24,"searchDepth":54,"depth":54,"links":215},[216,217,219,221],{"id":31,"depth":54,"text":32},{"id":85,"depth":54,"text":218},"2. app\u002Flayout provides the shell",{"id":150,"depth":54,"text":220},"3. app\u002Fi18n owns the locale",{"id":177,"depth":54,"text":178},"How a public page combines the app modules and content.","md",{},true,"\u002Fen\u002Fdocs\u002Fguides\u002Fbuilding-a-public-page",{"title":5,"description":222},"en\u002Fdocs\u002F3.guides\u002Fbuilding-a-public-page","Y9406hV4nmbhw_ybgwfx-ps3mAOCT7zuKaQLGDjHqgI",[231],{"title":232,"path":233,"stem":234,"children":235,"page":277},"En","\u002Fen","en",[236,278],{"title":237,"path":238,"stem":239,"children":240,"page":277},"Blog","\u002Fen\u002Fblog","en\u002Fblog",[241,247,253,259,265,271],{"title":242,"path":243,"stem":244,"children":245},"One URL model for every public page","\u002Fen\u002Fblog\u002Furl-model","en\u002Fblog\u002F1.url-model\u002Findex",[246],{"title":242,"path":243,"stem":244},{"title":248,"path":249,"stem":250,"children":251},"Content is resolved at build time","\u002Fen\u002Fblog\u002Fbuild-time-content","en\u002Fblog\u002F2.build-time-content\u002Findex",[252],{"title":248,"path":249,"stem":250},{"title":254,"path":255,"stem":256,"children":257},"Locale switching that never lies","\u002Fen\u002Fblog\u002Flocale-switching","en\u002Fblog\u002F3.locale-switching\u002Findex",[258],{"title":254,"path":255,"stem":256},{"title":260,"path":261,"stem":262,"children":263},"Deploying a blog as static assets","\u002Fen\u002Fblog\u002Fstatic-deployment","en\u002Fblog\u002F4.static-deployment\u002Findex",[264],{"title":260,"path":261,"stem":262},{"title":266,"path":267,"stem":268,"children":269},"A reading page is not a documentation page","\u002Fen\u002Fblog\u002Freading-first-design","en\u002Fblog\u002F5.reading-first-design\u002Findex",[270],{"title":266,"path":267,"stem":268},{"title":272,"path":273,"stem":274,"children":275},"What this blog is (and is not)","\u002Fen\u002Fblog\u002Fdemo-content-note","en\u002Fblog\u002F6.demo-content-note\u002Findex",[276],{"title":272,"path":273,"stem":274},false,{"title":279,"path":280,"stem":281,"children":282},"Overview","\u002Fen\u002Fdocs","en\u002Fdocs\u002Findex",[283,284,298,312],{"title":279,"path":280,"stem":281},{"title":285,"path":286,"stem":287,"children":288},"Getting Started","\u002Fen\u002Fdocs\u002Fgetting-started","en\u002Fdocs\u002F1.getting-started\u002Findex",[289,290,294],{"title":285,"path":286,"stem":287},{"title":291,"path":292,"stem":293},"First Steps","\u002Fen\u002Fdocs\u002Fgetting-started\u002Ffirst-steps","en\u002Fdocs\u002F1.getting-started\u002Ffirst-steps",{"title":295,"path":296,"stem":297},"Installation","\u002Fen\u002Fdocs\u002Fgetting-started\u002Finstallation","en\u002Fdocs\u002F1.getting-started\u002Finstallation",{"title":299,"path":300,"stem":301,"children":302},"Concepts","\u002Fen\u002Fdocs\u002Fconcepts","en\u002Fdocs\u002F2.concepts\u002Findex",[303,304,308],{"title":299,"path":300,"stem":301},{"title":305,"path":306,"stem":307},"Content and Locales","\u002Fen\u002Fdocs\u002Fconcepts\u002Fcontent-and-locales","en\u002Fdocs\u002F2.concepts\u002Fcontent-and-locales",{"title":309,"path":310,"stem":311},"Public Web","\u002Fen\u002Fdocs\u002Fconcepts\u002Fpublic-web","en\u002Fdocs\u002F2.concepts\u002Fpublic-web",{"title":313,"path":314,"stem":315,"children":316},"Guides","\u002Fen\u002Fdocs\u002Fguides","en\u002Fdocs\u002F3.guides\u002Findex",[317,318,319],{"title":313,"path":314,"stem":315},{"title":5,"path":226,"stem":228},{"title":209,"path":208,"stem":320},"en\u002Fdocs\u002F3.guides\u002Flocal-development",{},[234,323],"vi",[325,326],{"title":313,"path":314,"stem":315,"children":-1},{"title":209,"path":208,"stem":320,"children":-1},1791809693960]