[{"data":1,"prerenderedAt":1480},["ShallowReactive",2],{"duxt-navigation-docs-docs":3,"i-lucide:book-open":942,"i-lucide:languages":947,"i-lucide:signpost":949,"i-lucide:thumbs-up":951,"i-lucide:chart-line":953,"i-lucide:rocket":955,"i-lucide:compass":957,"i-lucide:list":959,"i-lucide:puzzle":961,"i-lucide:ruler":963,"i-lucide:gavel":965,"docs-en-US-\u002Fguides\u002Fcache-build-work":967,"i-lucide:folder-git":1424,"i-simple-icons:terraform":1426,"i-lucide:database-zap":1428,"i-lucide:git-compare":1430,"i-lucide:palette":1432,"i-lucide:cloud-upload":1434,"i-lucide:badge-check":1436,"duxt-preferred-missing-\u002Fguides\u002Fcache-build-work":945,"i-lucide:copy":1438,"i-lucide:chevron-down":1440,"i-lucide:thumbs-down":1442,"i-lucide:star":1444,"i-lucide:circle-alert":1446,"i-simple-icons:discord":1448,"i-lucide:book-open-text":1450,"i-lucide:arrow-up-right":1452,"i-lucide:file-code-2":1454,"i-lucide:menu":1456,"i-lucide:search":1458,"i-lucide:keyboard":1460,"i-simple-icons:github":1462,"i-lucide:moon":1464,"i-lucide:arrow-left":1466,"i-lucide:arrow-right":1468,"i-lucide:chevron-right":1470,"duxt-version-missing-\u002Fguides\u002Fcache-build-work":1472,"i-flag:us-4x3":1476,"duxt-code-yaml-- name: Resolve the remote-source cache key\n  id: sources\n  run: duxt-cache-key --root . --github >> \"$GITHUB_OUTPUT\"\n\n- name: Restore the downloaded sources\n  if: steps.sources.outputs.cacheable == 'true'\n  uses: actions\u002Fcache@v6\n  with:\n    path: ${{ steps.sources.outputs.paths }}\n    key: ${{ steps.sources.outputs.key }}\n":13,"duxt-code-bash-duxt-cache-key --root .\n":13,"duxt-code-yaml-- name: Resolve the OG image cache key\n  id: og\n  run: duxt-og-cache --root . --run \"$GITHUB_SHA\" --github >> \"$GITHUB_OUTPUT\"\n\n- name: Restore the rendered OG images\n  uses: actions\u002Fcache@v6\n  with:\n    path: ${{ steps.og.outputs.path }}\n    key: ${{ steps.og.outputs.key }}\n    restore-keys: ${{ steps.og.outputs['restore-keys'] }}\n":13,"duxt-code-bash-duxt-og-cache --root . --report --since \"$STARTED_MS\" --log build.log\n":13},[4,31,111,183,826,845,853,878],{"title":5,"path":6,"stem":7,"children":8},"Introduction","\u002Fgetting-started","1.getting-started",[9,14,20,26],{"title":5,"path":6,"stem":10,"icon":11,"description":12,"subcategory":13},"1.getting-started\u002Findex","lucide:rocket","What duxt is, and what arrives with a single line of config.",null,{"title":15,"path":16,"stem":17,"icon":18,"description":19,"subcategory":13},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","lucide:download","Add the layer, extend it, write Markdown.",{"title":21,"path":22,"stem":23,"icon":24,"description":25,"subcategory":13},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F2.configuration","lucide:settings","One file configures the whole site — what belongs in it, and how it merges.",{"title":27,"path":28,"stem":29,"icon":11,"description":30,"subcategory":13},"Start from the starter","\u002Fgetting-started\u002Ffrom-starter","1.getting-started\u002F3.from-starter","Create a ready-to-run duxt documentation site with Nuxi.",{"title":32,"path":33,"stem":34,"children":35},"Concepts","\u002Fconcepts","2.concepts",[36,40,46,52,58,64,70,76,81,87,93,99,105],{"title":32,"path":33,"stem":37,"icon":38,"description":39,"subcategory":13},"2.concepts\u002Findex","lucide:compass","How the layer works — the sources model, the URL scheme, the collections and the checks.",{"title":41,"path":42,"stem":43,"icon":44,"description":45,"subcategory":13},"Layers and overriding","\u002Fconcepts\u002Flayers","2.concepts\u002F1.layers","lucide:layers","What a Nuxt layer gives you, what it takes away, and which paths do not resolve the way they read.",{"title":47,"path":48,"stem":49,"icon":50,"description":51,"subcategory":13},"Theming","\u002Fconcepts\u002Ftheming","2.concepts\u002F10.theming","lucide:palette","How the theme is put together — owned components, one token layer, and a dark mode that switches on a class.",{"title":53,"path":54,"stem":55,"icon":56,"description":57,"subcategory":13},"Databases","\u002Fconcepts\u002Fdatabases","2.concepts\u002F11.databases","lucide:database","Which Content database adapters a duxt site can deploy on, which of them have been verified, and the one rule that keeps the layer out of the way.",{"title":59,"path":60,"stem":61,"icon":62,"description":63,"subcategory":13},"Keyboard shortcuts","\u002Fconcepts\u002Fkeyboard-shortcuts","2.concepts\u002F12.keyboard-shortcuts","lucide:keyboard","The four keys the theme binds, where each one applies, and where the reader is told about it.",{"title":65,"path":66,"stem":67,"icon":68,"description":69,"subcategory":13},"Sources","\u002Fconcepts\u002Fsources","2.concepts\u002F2.sources","lucide:git-branch","One list of sources becomes every collection, prefix and version the site serves.",{"title":71,"path":72,"stem":73,"icon":74,"description":75,"subcategory":13},"URLs and versions","\u002Fconcepts\u002Furls-and-versions","2.concepts\u002F3.urls-and-versions","lucide:git-compare","How the repository and version segments appear, and what a reader in an old version is told.",{"title":77,"path":78,"stem":79,"icon":56,"description":80,"subcategory":13},"Collections","\u002Fconcepts\u002Fcollections","2.concepts\u002F4.collections","What Content builds from the sources, and the four things the schema adds.",{"title":82,"path":83,"stem":84,"icon":85,"description":86,"subcategory":13},"Generated sections","\u002Fconcepts\u002Fgenerated-sections","2.concepts\u002F5.generated-sections","lucide:file-cog","An artefact plus a type, published as pages — what the registry is, and the two policies a type answers.",{"title":88,"path":89,"stem":90,"icon":91,"description":92,"subcategory":13},"What the build checks","\u002Fconcepts\u002Fbuild-checks","2.concepts\u002F6.build-checks","lucide:shield-check","The silent failures this layer had, turned into messages.",{"title":94,"path":95,"stem":96,"icon":97,"description":98,"subcategory":13},"Machine readers","\u002Fconcepts\u002Fmachine-readers","2.concepts\u002F7.machine-readers","lucide:bot","What a model gets — llms.txt, the raw Markdown of any page, and a real MCP server.",{"title":100,"path":101,"stem":102,"icon":103,"description":104,"subcategory":13},"SEO","\u002Fconcepts\u002Fseo","2.concepts\u002F8.seo","lucide:search","What every page emits for crawlers and social cards, which module writes it, and the one value the layer cannot guess.",{"title":106,"path":107,"stem":108,"icon":109,"description":110,"subcategory":13},"Localisation","\u002Fconcepts\u002Flocalisation","2.concepts\u002F9.localisation","lucide:languages","Seven locales ship with the layer, and every configured string takes three forms.",{"title":112,"path":113,"stem":114,"children":115},"Guides","\u002Fguides","3.guides",[116,120,126,132,138,143,148,153,159,165,171,177],{"title":112,"path":113,"stem":117,"icon":118,"description":119,"subcategory":13},"3.guides\u002Findex","lucide:book-open","One task per page, start to finish — several repositories, several versions, several languages, and a deploy.",{"title":121,"path":122,"stem":123,"icon":124,"description":125,"subcategory":13},"Several repositories","\u002Fguides\u002Fseveral-repositories","3.guides\u002F1.several-repositories","lucide:folder-git","Serve the documentation of several projects from one site.",{"title":127,"path":128,"stem":129,"icon":130,"description":131,"subcategory":13},"Publish Terraform provider docs","\u002Fguides\u002Fpublish-terraform-provider-docs","3.guides\u002F10.publish-terraform-provider-docs","simple-icons:terraform","Turn a tfplugindocs Markdown tree into a versioned provider reference with provider-aware navigation.",{"title":133,"path":134,"stem":135,"icon":136,"description":137,"subcategory":13},"Cache remote sources and OG images","\u002Fguides\u002Fcache-build-work","3.guides\u002F11.cache-build-work","lucide:database-zap","Reuse downloaded public repositories and rendered social cards safely between CI builds.",{"title":139,"path":140,"stem":141,"icon":74,"description":142,"subcategory":13},"Several versions","\u002Fguides\u002Fseveral-versions","3.guides\u002F2.several-versions","Serve the same documentation at several refs, with a switcher and a banner.",{"title":144,"path":145,"stem":146,"icon":109,"description":147,"subcategory":13},"Several languages","\u002Fguides\u002Fseveral-languages","3.guides\u002F3.several-languages","Serve the interface in several languages, and translate the pages themselves.",{"title":149,"path":150,"stem":151,"icon":50,"description":152,"subcategory":13},"Override the theme","\u002Fguides\u002Foverride-the-theme","3.guides\u002F4.override-the-theme","Change a colour, replace a component, add a shadcn-vue primitive.",{"title":154,"path":155,"stem":156,"icon":157,"description":158,"subcategory":13},"Move a page","\u002Fguides\u002Fmove-a-page","3.guides\u002F5.move-a-page","lucide:signpost","redirectFrom in the frontmatter, turned into route rules under every prefix.",{"title":160,"path":161,"stem":162,"icon":163,"description":164,"subcategory":13},"Deploy a site","\u002Fguides\u002Fdeploy-a-site","3.guides\u002F6.deploy-a-site","lucide:cloud-upload","Where a duxt site can run, what it needs there, and why content is not refreshed at runtime.",{"title":166,"path":167,"stem":168,"icon":169,"description":170,"subcategory":13},"Collect page feedback","\u002Fguides\u002Fcollect-page-feedback","3.guides\u002F7.collect-page-feedback","lucide:thumbs-up","Wrap DuxtPageFeedback, keep the answer where your analytics already live.",{"title":172,"path":173,"stem":174,"icon":175,"description":176,"subcategory":13},"Brand your site","\u002Fguides\u002Fbrand-your-site","3.guides\u002F8.brand-your-site","lucide:badge-check","Set the name, the wordmark and the icons, so the site reads as yours rather than as the layer's.",{"title":178,"path":179,"stem":180,"icon":181,"description":182,"subcategory":13},"Send analytics events","\u002Fguides\u002Fsend-analytics-events","3.guides\u002F9.send-analytics-events","lucide:chart-line","One callback, five events, no provider — wire duxt's reader interactions into the analytics you already run.",{"title":184,"path":185,"stem":186,"children":187},"Reference","\u002Freference","4.reference",[188,192,196,228,258,264,268,273,413,570,696,741,801],{"title":184,"path":185,"stem":189,"icon":190,"description":191,"subcategory":13},"4.reference\u002Findex","lucide:list","The layer's public surface — config keys, frontmatter, components, composables and endpoints.",{"title":21,"path":193,"stem":194,"icon":24,"description":195,"subcategory":13},"\u002Freference\u002Fconfiguration","4.reference\u002F1.configuration","Every key under duxt in app.config.ts — what it controls, and when it is read.",{"title":197,"path":198,"stem":199,"children":200,"icon":202,"description":203,"subcategory":13},"Changelog","\u002Freference\u002Fchangelog","4.reference\u002F10.changelog\u002Findex",[201,204,210,216,222],{"title":197,"path":198,"stem":199,"icon":202,"description":203,"subcategory":13},"lucide:tag","A release log, published as pages — a timeline, a page per release, and a feed.",{"title":205,"path":206,"stem":207,"icon":208,"description":209,"subcategory":13},"Declaring the section","\u002Freference\u002Fchangelog\u002Fsection","4.reference\u002F10.changelog\u002F1.section","lucide:file-clock","The `changelog` section type — where the file lives, and the two policies it answers.",{"title":211,"path":212,"stem":213,"icon":214,"description":215,"subcategory":13},"Granularity","\u002Freference\u002Fchangelog\u002Fgranularity","4.reference\u002F10.changelog\u002F2.granularity","lucide:split","A page per release, or the file as the one page it was written as.",{"title":217,"path":218,"stem":219,"icon":220,"description":221,"subcategory":13},"What is read","\u002Freference\u002Fchangelog\u002Fwhat-is-read","4.reference\u002F10.changelog\u002F3.what-is-read","lucide:scan-text","Which headings become releases, which become groups, and what happens to the rest.",{"title":223,"path":224,"stem":225,"icon":226,"description":227,"subcategory":13},"Layout and components","\u002Freference\u002Fchangelog\u002Fcomponents","4.reference\u002F10.changelog\u002F4.components","lucide:box","The layout a split history renders in, and the two MDC components its pages are made of.",{"title":229,"path":230,"stem":231,"children":232,"icon":234,"description":235,"subcategory":13},"Bruno collections","\u002Freference\u002Fbruno","4.reference\u002F11.bruno\u002Findex",[233,236,241,247,253],{"title":229,"path":230,"stem":231,"icon":234,"description":235,"subcategory":13},"lucide:send","A Bruno collection, published as request-centred reference pages with a downloadable archive.",{"title":205,"path":237,"stem":238,"icon":239,"description":240,"subcategory":13},"\u002Freference\u002Fbruno\u002Fsection","4.reference\u002F11.bruno\u002F1.section","lucide:file-code","The `bruno` section type — where the collection lives, and what it becomes.",{"title":242,"path":243,"stem":244,"icon":245,"description":246,"subcategory":13},"What is published","\u002Freference\u002Fbruno\u002Fwhat-is-published","4.reference\u002F11.bruno\u002F2.what-is-published","lucide:shield","Environments, credentials, scripts and tests never reach a page — and what that means for the archive.",{"title":248,"path":249,"stem":250,"icon":251,"description":252,"subcategory":13},"The request client","\u002Freference\u002Fbruno\u002Ftry-it","4.reference\u002F11.bruno\u002F3.try-it","lucide:send-horizontal","Off until a site turns it on, and pointed only at what the site declared public.",{"title":254,"path":255,"stem":256,"icon":18,"description":257,"subcategory":13},"Getting the collection","\u002Freference\u002Fbruno\u002Fgetting-the-collection","4.reference\u002F11.bruno\u002F4.getting-the-collection","The archive is pinned to the page you are on; the Bruno deep link is not.",{"title":259,"path":260,"stem":261,"icon":262,"description":263,"subcategory":13},"Hooks","\u002Freference\u002Fhooks","4.reference\u002F12.hooks","lucide:plug","The one build-time hook duxt emits, what it hands you, and why there is only one.",{"title":65,"path":265,"stem":266,"icon":68,"description":267,"subcategory":13},"\u002Freference\u002Fsources","4.reference\u002F2.sources","The fields of a source entry, its refs, and the options that shape the URLs.",{"title":269,"path":270,"stem":271,"icon":239,"description":272,"subcategory":13},"Frontmatter","\u002Freference\u002Ffrontmatter","4.reference\u002F3.frontmatter","The fields a page may carry beyond title and description, and the two the build fills in.",{"title":274,"path":275,"stem":276,"children":277,"icon":279,"description":280,"subcategory":13},"MDC components","\u002Freference\u002Fmdc-components","4.reference\u002F4.mdc-components\u002Findex",[278,281,287,293,299,305,311,317,323,329,367,373,378,384,390,396,402,408],{"title":274,"path":275,"stem":276,"icon":279,"description":280,"subcategory":13},"lucide:blocks","The blocks a Markdown page can call, one page each, with their props.",{"title":282,"path":283,"stem":284,"icon":285,"description":286,"subcategory":13},"Callout","\u002Freference\u002Fmdc-components\u002Fcallout","4.reference\u002F4.mdc-components\u002F1.callout","lucide:message-square-warning","An aside the reader is meant to stop at — a tip, a warning, a danger.",{"title":288,"path":289,"stem":290,"icon":291,"description":292,"subcategory":13},"Package managers","\u002Freference\u002Fmdc-components\u002Fpackage-managers","4.reference\u002F4.mdc-components\u002F10.package-managers","lucide:package","One command, one tab per package manager, remembered across pages.",{"title":294,"path":295,"stem":296,"icon":297,"description":298,"subcategory":13},"File tree","\u002Freference\u002Fmdc-components\u002Ffile-tree","4.reference\u002F4.mdc-components\u002F11.file-tree","lucide:folder-tree","A folder structure, with icons per file type.",{"title":300,"path":301,"stem":302,"icon":303,"description":304,"subcategory":13},"Preview","\u002Freference\u002Fmdc-components\u002Fpreview","4.reference\u002F4.mdc-components\u002F12.preview","lucide:eye","A component rendered as the page renders it, with its source beside it.",{"title":306,"path":307,"stem":308,"icon":309,"description":310,"subcategory":13},"Page cards","\u002Freference\u002Fmdc-components\u002Fpage-cards","4.reference\u002F4.mdc-components\u002F13.page-cards","lucide:layout-grid","A section's children, as cards.",{"title":312,"path":313,"stem":314,"icon":315,"description":316,"subcategory":13},"Partial","\u002Freference\u002Fmdc-components\u002Fpartial","4.reference\u002F4.mdc-components\u002F14.partial","lucide:puzzle","A block written once and rendered in every source that needs it.",{"title":318,"path":319,"stem":320,"icon":321,"description":322,"subcategory":13},"Since","\u002Freference\u002Fmdc-components\u002Fsince","4.reference\u002F4.mdc-components\u002F15.since","lucide:milestone","The version something arrived in, beside a heading.",{"title":324,"path":325,"stem":326,"icon":327,"description":328,"subcategory":13},"Mermaid","\u002Freference\u002Fmdc-components\u002Fmermaid","4.reference\u002F4.mdc-components\u002F16.mermaid","lucide:workflow","A diagram from a fence or a prop.",{"title":330,"path":331,"stem":332,"children":333,"icon":335,"description":336,"subcategory":13},"Prose overrides","\u002Freference\u002Fmdc-components\u002Fprose","4.reference\u002F4.mdc-components\u002F17.prose\u002Findex",[334,337,343,349,355,361],{"title":330,"path":331,"stem":332,"icon":335,"description":336,"subcategory":13},"lucide:type","What the layer changes about plain Markdown — links, headings, images, code and tables.",{"title":338,"path":339,"stem":340,"icon":341,"description":342,"subcategory":13},"ProseA","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-a","4.reference\u002F4.mdc-components\u002F17.prose\u002F1.prose-a","lucide:link","A link, resolved against the source it was written in.",{"title":344,"path":345,"stem":346,"icon":347,"description":348,"subcategory":13},"ProseH2, ProseH3, ProseH4","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-headings","4.reference\u002F4.mdc-components\u002F17.prose\u002F2.prose-headings","lucide:heading","Headings, each with a permalink anchor.",{"title":350,"path":351,"stem":352,"icon":353,"description":354,"subcategory":13},"ProseImg","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-img","4.reference\u002F4.mdc-components\u002F17.prose\u002F3.prose-img","lucide:image","An image: theme-aware, responsive, and zoomable.",{"title":356,"path":357,"stem":358,"icon":359,"description":360,"subcategory":13},"ProsePre","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-pre","4.reference\u002F4.mdc-components\u002F17.prose\u002F4.prose-pre","lucide:terminal","The code block: filename, language icon, copy button.",{"title":362,"path":363,"stem":364,"icon":365,"description":366,"subcategory":13},"ProseTable","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-table","4.reference\u002F4.mdc-components\u002F17.prose\u002F5.prose-table","lucide:table","A table that scrolls instead of the page.",{"title":368,"path":369,"stem":370,"icon":371,"description":372,"subcategory":13},"Steps","\u002Freference\u002Fmdc-components\u002Fsteps","4.reference\u002F4.mdc-components\u002F2.steps","lucide:list-ordered","An ordered list drawn as numbered steps on a rail.",{"title":374,"path":375,"stem":376,"icon":239,"description":377,"subcategory":13},"Code group","\u002Freference\u002Fmdc-components\u002Fcode-group","4.reference\u002F4.mdc-components\u002F3.code-group","Several fences as one tabbed block, labelled by filename.",{"title":379,"path":380,"stem":381,"icon":382,"description":383,"subcategory":13},"Tab group","\u002Freference\u002Fmdc-components\u002Ftab-group","4.reference\u002F4.mdc-components\u002F4.tab-group","lucide:panels-top-left","Tabs for anything that is not code.",{"title":385,"path":386,"stem":387,"icon":388,"description":389,"subcategory":13},"Tab","\u002Freference\u002Fmdc-components\u002Ftab","4.reference\u002F4.mdc-components\u002F5.tab","lucide:square","One panel of a tab group.",{"title":391,"path":392,"stem":393,"icon":394,"description":395,"subcategory":13},"Accordion","\u002Freference\u002Fmdc-components\u002Faccordion","4.reference\u002F4.mdc-components\u002F6.accordion","lucide:chevrons-up-down","Collapsible sections — a FAQ, or answers a reader picks from.",{"title":397,"path":398,"stem":399,"icon":400,"description":401,"subcategory":13},"Accordion item","\u002Freference\u002Fmdc-components\u002Faccordion-item","4.reference\u002F4.mdc-components\u002F7.accordion-item","lucide:chevron-down","One collapsible section.",{"title":403,"path":404,"stem":405,"icon":406,"description":407,"subcategory":13},"Field group","\u002Freference\u002Fmdc-components\u002Ffield-group","4.reference\u002F4.mdc-components\u002F8.field-group","lucide:list-tree","A list of fields as one block.",{"title":409,"path":410,"stem":411,"icon":202,"description":412,"subcategory":13},"Field","\u002Freference\u002Fmdc-components\u002Ffield","4.reference\u002F4.mdc-components\u002F9.field","One parameter, property or option, with its type and default.",{"title":414,"path":415,"stem":416,"children":417,"icon":419,"description":420,"subcategory":13},"Components","\u002Freference\u002Fcomponents","4.reference\u002F5.components\u002Findex",[418,421,447,488,539],{"title":414,"path":415,"stem":416,"icon":419,"description":420,"subcategory":13},"lucide:component","The layer's own components, one page each — what each is for, and what it takes.",{"title":422,"path":423,"stem":424,"children":425,"icon":427,"description":428,"subcategory":13},"Layout","\u002Freference\u002Fcomponents\u002Flayout","4.reference\u002F5.components\u002F1.layout\u002Findex",[426,429,435,441],{"title":422,"path":423,"stem":424,"icon":427,"description":428,"subcategory":13},"lucide:layout-panel-top","The three components that frame a page — the navbar, the footer and the site notices.",{"title":430,"path":431,"stem":432,"icon":433,"description":434,"subcategory":13},"DuxtHeader","\u002Freference\u002Fcomponents\u002Flayout\u002Fduxt-header","4.reference\u002F5.components\u002F1.layout\u002F1.duxt-header","lucide:panel-top","The navbar: title, navigation, search, and the icon links.",{"title":436,"path":437,"stem":438,"icon":439,"description":440,"subcategory":13},"DuxtFooter","\u002Freference\u002Fcomponents\u002Flayout\u002Fduxt-footer","4.reference\u002F5.components\u002F1.layout\u002F2.duxt-footer","lucide:panel-bottom","The footer: the site's name, its legal links, and the layer's own line.",{"title":442,"path":443,"stem":444,"icon":445,"description":446,"subcategory":13},"DuxtAnnouncements","\u002Freference\u002Fcomponents\u002Flayout\u002Fduxt-announcements","4.reference\u002F5.components\u002F1.layout\u002F3.duxt-announcements","lucide:megaphone","The site's own notices: one strip per placement, drawn only when there is something to say.",{"title":448,"path":449,"stem":450,"children":451,"icon":38,"description":453,"subcategory":13},"Navigation","\u002Freference\u002Fcomponents\u002Fnavigation","4.reference\u002F5.components\u002F2.navigation\u002Findex",[452,454,460,465,471,477,482],{"title":448,"path":449,"stem":450,"icon":38,"description":453,"subcategory":13},"Getting around — the section row, the sidebar, the trail, the contents and prev\u002Fnext.",{"title":455,"path":456,"stem":457,"icon":458,"description":459,"subcategory":13},"DuxtSections","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-sections","4.reference\u002F5.components\u002F2.navigation\u002F1.duxt-sections","lucide:rows-3","The second navbar row — the top-level parts of the documentation.",{"title":461,"path":462,"stem":463,"icon":406,"description":464,"subcategory":13},"DuxtNavigation","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-navigation","4.reference\u002F5.components\u002F2.navigation\u002F2.duxt-navigation","The sidebar tree.",{"title":466,"path":467,"stem":468,"icon":469,"description":470,"subcategory":13},"DuxtNavigationLink","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-navigation-link","4.reference\u002F5.components\u002F2.navigation\u002F3.duxt-navigation-link","lucide:link-2","One entry of the sidebar.",{"title":472,"path":473,"stem":474,"icon":475,"description":476,"subcategory":13},"DuxtBreadcrumb","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-breadcrumb","4.reference\u002F5.components\u002F2.navigation\u002F4.duxt-breadcrumb","lucide:chevrons-right","The trail above the page title.",{"title":478,"path":479,"stem":480,"icon":190,"description":481,"subcategory":13},"DuxtToc","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-toc","4.reference\u002F5.components\u002F2.navigation\u002F5.duxt-toc","The table of contents, and the aside under it.",{"title":483,"path":484,"stem":485,"icon":486,"description":487,"subcategory":13},"DuxtPageNav","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-page-nav","4.reference\u002F5.components\u002F2.navigation\u002F6.duxt-page-nav","lucide:arrow-left-right","Previous and next, bounded by the section.",{"title":489,"path":490,"stem":491,"children":492,"icon":494,"description":495,"subcategory":13},"Controls","\u002Freference\u002Fcomponents\u002Fcontrols","4.reference\u002F5.components\u002F3.controls\u002Findex",[493,496,501,506,512,517,523,528,534],{"title":489,"path":490,"stem":491,"icon":494,"description":495,"subcategory":13},"lucide:sliders-horizontal","What a reader operates — search, the switchers, the shortcut sheet, and two indicators.",{"title":497,"path":498,"stem":499,"icon":103,"description":500,"subcategory":13},"DuxtSearch","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-search","4.reference\u002F5.components\u002F3.controls\u002F1.duxt-search","Search every active source and interleave its locally ranked results.",{"title":502,"path":503,"stem":504,"icon":44,"description":505,"subcategory":13},"DuxtVersion","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-version","4.reference\u002F5.components\u002F3.controls\u002F2.duxt-version","The version badge, and the switcher when there is more than one.",{"title":507,"path":508,"stem":509,"icon":510,"description":511,"subcategory":13},"DuxtVersionBanner","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-version-banner","4.reference\u002F5.components\u002F3.controls\u002F3.duxt-version-banner","lucide:triangle-alert","The bar telling a reader this version is not the current one.",{"title":513,"path":514,"stem":515,"icon":109,"description":516,"subcategory":13},"DuxtLocale","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-locale","4.reference\u002F5.components\u002F3.controls\u002F4.duxt-locale","The language switcher.",{"title":518,"path":519,"stem":520,"icon":521,"description":522,"subcategory":13},"DuxtProgress","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-progress","4.reference\u002F5.components\u002F3.controls\u002F5.duxt-progress","lucide:loader","How far down the page the reader is.",{"title":524,"path":525,"stem":526,"icon":62,"description":527,"subcategory":13},"DuxtShortcuts","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-shortcuts","4.reference\u002F5.components\u002F3.controls\u002F6.duxt-shortcuts","The keyboard shortcut sheet, on ?.",{"title":529,"path":530,"stem":531,"icon":532,"description":533,"subcategory":13},"DuxtSkipLink","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-skip-link","4.reference\u002F5.components\u002F3.controls\u002F7.duxt-skip-link","lucide:skip-forward","The first focusable element on the page.",{"title":535,"path":536,"stem":537,"icon":62,"description":538,"subcategory":13},"DuxtShortcutsTrigger","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-shortcuts-trigger","4.reference\u002F5.components\u002F3.controls\u002F8.duxt-shortcuts-trigger","The button that opens the shortcut sheet.",{"title":540,"path":541,"stem":542,"children":543,"icon":545,"description":546,"subcategory":13},"Page","\u002Freference\u002Fcomponents\u002Fpage","4.reference\u002F5.components\u002F4.page\u002Findex",[544,547,553,559,564],{"title":540,"path":541,"stem":542,"icon":545,"description":546,"subcategory":13},"lucide:file-text","The components that belong to the page itself.",{"title":548,"path":549,"stem":550,"icon":551,"description":552,"subcategory":13},"DuxtPageInfo","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-page-info","4.reference\u002F5.components\u002F4.page\u002F1.duxt-page-info","lucide:git-commit-horizontal","Where the page came from: edit link, last updated, contributors.",{"title":554,"path":555,"stem":556,"icon":557,"description":558,"subcategory":13},"DuxtCopyPage","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-copy-page","4.reference\u002F5.components\u002F4.page\u002F2.duxt-copy-page","lucide:clipboard-copy","Hand this page to a model, or read its source.",{"title":560,"path":561,"stem":562,"icon":169,"description":563,"subcategory":13},"DuxtPageFeedback","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-page-feedback","4.reference\u002F5.components\u002F4.page\u002F3.duxt-page-feedback","Was this page helpful?",{"title":565,"path":566,"stem":567,"icon":568,"description":569,"subcategory":13},"DuxtCodeBlock","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-code-block","4.reference\u002F5.components\u002F4.page\u002F4.duxt-code-block","lucide:code","The card around a code block.",{"title":571,"path":572,"stem":573,"children":574,"icon":576,"description":577,"subcategory":13},"Composables","\u002Freference\u002Fcomposables","4.reference\u002F6.composables\u002Findex",[575,578,612,641],{"title":571,"path":572,"stem":573,"icon":576,"description":577,"subcategory":13},"lucide:function-square","The functions the layer exposes to your own components, one page each.",{"title":579,"path":580,"stem":581,"children":582,"icon":56,"description":584,"subcategory":13},"Config and content","\u002Freference\u002Fcomposables\u002Fconfig-and-content","4.reference\u002F6.composables\u002F1.config-and-content\u002Findex",[583,585,590,596,601,607],{"title":579,"path":580,"stem":581,"icon":56,"description":584,"subcategory":13},"The merged config, and which collection serves the page being read.",{"title":586,"path":587,"stem":588,"icon":24,"description":589,"subcategory":13},"useDuxtConfig()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-config","4.reference\u002F6.composables\u002F1.config-and-content\u002F1.use-duxt-config","The merged config, every text field already resolved.",{"title":591,"path":592,"stem":593,"icon":594,"description":595,"subcategory":13},"useDuxtCollection()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-collection","4.reference\u002F6.composables\u002F1.config-and-content\u002F2.use-duxt-collection","lucide:library","Which collection serves this route.",{"title":597,"path":598,"stem":599,"icon":406,"description":600,"subcategory":13},"useDuxtNavigation()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-navigation","4.reference\u002F6.composables\u002F1.config-and-content\u002F3.use-duxt-navigation","The navigation tree for the collection serving this route.",{"title":602,"path":603,"stem":604,"icon":605,"description":606,"subcategory":13},"useDuxtSection()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-section","4.reference\u002F6.composables\u002F1.config-and-content\u002F4.use-duxt-section","lucide:folder-open","The part of the documentation this page is in.",{"title":608,"path":609,"stem":610,"icon":475,"description":611,"subcategory":13},"useDuxtBreadcrumb()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-breadcrumb","4.reference\u002F6.composables\u002F1.config-and-content\u002F5.use-duxt-breadcrumb","The trail from the section down to a page.",{"title":613,"path":614,"stem":615,"children":616,"icon":618,"description":619,"subcategory":13},"Paths and versions","\u002Freference\u002Fcomposables\u002Fpaths-and-versions","4.reference\u002F6.composables\u002F2.paths-and-versions\u002Findex",[617,620,625,630,635],{"title":613,"path":614,"stem":615,"icon":618,"description":619,"subcategory":13},"lucide:route","Reading a URL, writing one back out, and knowing which version is being read.",{"title":621,"path":622,"stem":623,"icon":321,"description":624,"subcategory":13},"useDuxtPath()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-path","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F1.use-duxt-path","The path the documentation is at, locale stripped.",{"title":626,"path":627,"stem":628,"icon":341,"description":629,"subcategory":13},"useDuxtLink()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-link","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F2.use-duxt-link","A documentation path, written back out as a link.",{"title":631,"path":632,"stem":633,"icon":44,"description":634,"subcategory":13},"useDuxtVersion()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-version","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F3.use-duxt-version","What the switcher shows, what the banner says, whether to index.",{"title":636,"path":637,"stem":638,"icon":639,"description":640,"subcategory":13},"useDuxtSiteUrl()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-site-url","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F4.use-duxt-site-url","lucide:globe","The configured origin, and paths made absolute.",{"title":642,"path":643,"stem":644,"children":645,"icon":118,"description":647,"subcategory":13},"Reading experience","\u002Freference\u002Fcomposables\u002Freading","4.reference\u002F6.composables\u002F3.reading\u002Findex",[646,648,652,658,663,669,675,680,686,691],{"title":642,"path":643,"stem":644,"icon":118,"description":647,"subcategory":13},"Search, headings, focus, history, and the choices a reader makes.",{"title":649,"path":650,"stem":651,"icon":103,"description":500,"subcategory":13},"useDuxtSearch()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-search","4.reference\u002F6.composables\u002F3.reading\u002F1.use-duxt-search",{"title":653,"path":654,"stem":655,"icon":656,"description":657,"subcategory":13},"useFuzzySearch()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-fuzzy-search","4.reference\u002F6.composables\u002F3.reading\u002F2.use-fuzzy-search","lucide:spell-check","Typo tolerance beside the exact index.",{"title":659,"path":660,"stem":661,"icon":347,"description":662,"subcategory":13},"useActiveHeading()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-active-heading","4.reference\u002F6.composables\u002F3.reading\u002F3.use-active-heading","The heading currently in view.",{"title":664,"path":665,"stem":666,"icon":667,"description":668,"subcategory":13},"useDuxtPageFocus()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-page-focus","4.reference\u002F6.composables\u002F3.reading\u002F4.use-duxt-page-focus","lucide:focus","Moves focus to the heading after a client-side navigation.",{"title":670,"path":671,"stem":672,"icon":673,"description":674,"subcategory":13},"useRecentPages()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-recent-pages","4.reference\u002F6.composables\u002F3.reading\u002F5.use-recent-pages","lucide:history","The most recent pages this reader opened, up to the configured limit.",{"title":676,"path":677,"stem":678,"icon":291,"description":679,"subcategory":13},"usePackageManager()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-package-manager","4.reference\u002F6.composables\u002F3.reading\u002F6.use-package-manager","The package manager a reader picked.",{"title":681,"path":682,"stem":683,"icon":684,"description":685,"subcategory":13},"useDuxtToast()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-toast","4.reference\u002F6.composables\u002F3.reading\u002F7.use-duxt-toast","lucide:bell","Notifications, wrapped so no component imports the library.",{"title":687,"path":688,"stem":689,"icon":62,"description":690,"subcategory":13},"useDuxtShortcuts()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-shortcuts","4.reference\u002F6.composables\u002F3.reading\u002F8.use-duxt-shortcuts","The keys the theme listens to.",{"title":692,"path":693,"stem":694,"icon":181,"description":695,"subcategory":13},"useDuxtAnalytics()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-analytics","4.reference\u002F6.composables\u002F3.reading\u002F9.use-duxt-analytics","Report one reader interaction to the site's own callback, or to nobody.",{"title":697,"path":698,"stem":699,"children":700,"icon":618,"description":702,"subcategory":13},"Endpoints","\u002Freference\u002Fendpoints","4.reference\u002F7.endpoints\u002Findex",[701,703,708,714,719,724,729,735],{"title":697,"path":698,"stem":699,"icon":618,"description":702,"subcategory":13},"Everything the site serves besides pages, one page each.",{"title":704,"path":705,"stem":706,"icon":545,"description":707,"subcategory":13},"\u002Fllms.txt","\u002Freference\u002Fendpoints\u002Fllms-txt","4.reference\u002F7.endpoints\u002F1.llms-txt","The documentation as a Markdown index, per llmstxt.org.",{"title":709,"path":710,"stem":711,"icon":712,"description":713,"subcategory":13},"\u002Fllms-full.txt","\u002Freference\u002Fendpoints\u002Fllms-full-txt","4.reference\u002F7.endpoints\u002F2.llms-full-txt","lucide:file-stack","A duxt extension with the same pages in one Markdown file.",{"title":715,"path":716,"stem":717,"icon":239,"description":718,"subcategory":13},"\u003Cpage>.md","\u002Freference\u002Fendpoints\u002Fpage-markdown","4.reference\u002F7.endpoints\u002F3.page-markdown","Any page source, at its own URL plus .md.",{"title":720,"path":721,"stem":722,"icon":97,"description":723,"subcategory":13},"\u002Fmcp","\u002Freference\u002Fendpoints\u002Fmcp","4.reference\u002F7.endpoints\u002F4.mcp","An MCP server over the same content.",{"title":725,"path":726,"stem":727,"icon":103,"description":728,"subcategory":13},"\u002Fsitemap.xml and \u002Frobots.txt","\u002Freference\u002Fendpoints\u002Fsitemap-and-robots","4.reference\u002F7.endpoints\u002F5.sitemap-and-robots","What a crawler is pointed at, and what it is kept out of.",{"title":730,"path":731,"stem":732,"icon":733,"description":734,"subcategory":13},"\u002Frss.xml","\u002Freference\u002Fendpoints\u002Frss-xml","4.reference\u002F7.endpoints\u002F6.rss-xml","lucide:rss","The feed, once a section is named.",{"title":736,"path":737,"stem":738,"icon":739,"description":740,"subcategory":13},"\u002F_duxt\u002Fdevtools","\u002Freference\u002Fendpoints\u002Fdevtools","4.reference\u002F7.endpoints\u002F7.devtools","lucide:wrench","The route the Nuxt Devtools panel is served from. Dev only.",{"title":742,"path":743,"stem":744,"children":745,"icon":739,"description":747,"subcategory":13},"Devtools","\u002Freference\u002Fdevtools","4.reference\u002F8.devtools\u002Findex",[746,748,752,757,762,768,774,780,785,790,795],{"title":742,"path":743,"stem":744,"icon":739,"description":747,"subcategory":13},"Ten panels that show what your sources became. Dev only.",{"title":65,"path":749,"stem":750,"icon":594,"description":751,"subcategory":13},"\u002Freference\u002Fdevtools\u002Fsources","4.reference\u002F8.devtools\u002F1.sources","What `duxt.sources` became — one collection per source, version and language.",{"title":753,"path":754,"stem":755,"icon":157,"description":756,"subcategory":13},"Redirects","\u002Freference\u002Fdevtools\u002Fredirects","4.reference\u002F8.devtools\u002F10.redirects","Every redirect the server ships, and which of them the layer wrote.",{"title":758,"path":759,"stem":760,"icon":618,"description":761,"subcategory":13},"Paths","\u002Freference\u002Fdevtools\u002Fpaths","4.reference\u002F8.devtools\u002F2.paths","Paste a URL, see which source claims it and what it finds there.",{"title":763,"path":764,"stem":765,"icon":766,"description":767,"subcategory":13},"Pages","\u002Freference\u002Fdevtools\u002Fpages","4.reference\u002F8.devtools\u002F3.pages","lucide:files","Every page of every collection, with its frontmatter and git metadata.",{"title":769,"path":770,"stem":771,"icon":772,"description":773,"subcategory":13},"Versions","\u002Freference\u002Fdevtools\u002Fversions","4.reference\u002F8.devtools\u002F4.versions","lucide:columns-3","Which version — and which language — carries which page.",{"title":775,"path":776,"stem":777,"icon":778,"description":779,"subcategory":13},"Checks","\u002Freference\u002Fdevtools\u002Fchecks","4.reference\u002F8.devtools\u002F5.checks","lucide:check-check","The build validator, run against what the site is serving now.",{"title":781,"path":782,"stem":783,"icon":103,"description":784,"subcategory":13},"Search","\u002Freference\u002Fdevtools\u002Fsearch","4.reference\u002F8.devtools\u002F6.search","What the search index holds, through the same query the dialog runs.",{"title":786,"path":787,"stem":788,"icon":494,"description":789,"subcategory":13},"Config","\u002Freference\u002Fdevtools\u002Fconfig","4.reference\u002F8.devtools\u002F7.config","The merged `duxt` config, and which side of the merge each value came from.",{"title":791,"path":792,"stem":793,"icon":109,"description":794,"subcategory":13},"i18n","\u002Freference\u002Fdevtools\u002Fi18n","4.reference\u002F8.devtools\u002F8.i18n","Message keys per locale, against the base language.",{"title":796,"path":797,"stem":798,"icon":799,"description":800,"subcategory":13},"Cache","\u002Freference\u002Fdevtools\u002Fcache","4.reference\u002F8.devtools\u002F9.cache","lucide:hard-drive","Content's download cache, and a way to drop one entry.",{"title":802,"path":803,"stem":804,"children":805,"icon":262,"description":807,"subcategory":13},"API reference","\u002Freference\u002Fopenapi","4.reference\u002F9.openapi\u002Findex",[806,808,812,816,821],{"title":802,"path":803,"stem":804,"icon":262,"description":807,"subcategory":13},"An OpenAPI document, published as reference pages with a client that sends real requests.",{"title":205,"path":809,"stem":810,"icon":239,"description":811,"subcategory":13},"\u002Freference\u002Fopenapi\u002Fsection","4.reference\u002F9.openapi\u002F1.section","The `openapi` section type — where the document lives, and what it becomes.",{"title":414,"path":813,"stem":814,"icon":226,"description":815,"subcategory":13},"\u002Freference\u002Fopenapi\u002Fcomponents","4.reference\u002F9.openapi\u002F2.components","The three MDC components a generated reference page is made of.",{"title":817,"path":818,"stem":819,"icon":234,"description":820,"subcategory":13},"The try-it client","\u002Freference\u002Fopenapi\u002Ftry-it","4.reference\u002F9.openapi\u002F3.try-it","A real request, sent by the reader's own browser.",{"title":822,"path":823,"stem":824,"icon":568,"description":825,"subcategory":13},"Request samples","\u002Freference\u002Fopenapi\u002Frequest-samples","4.reference\u002F9.openapi\u002F4.request-samples","The same request in twelve clients, and how to add your own.",{"title":827,"path":828,"stem":829,"children":830},"Add-ons","\u002Fadd-ons","5.add-ons",[831,834,839],{"title":827,"path":828,"stem":832,"icon":315,"description":833,"subcategory":13},"5.add-ons\u002Findex","Companion layers that extend a duxt site — each one its own package, added with one more entry in extends.",{"title":835,"path":836,"stem":837,"icon":103,"description":838,"subcategory":13},"Typesense","\u002Fadd-ons\u002Ftypesense","5.add-ons\u002F1.typesense","Consume duxt's one build hook into a Typesense collection — every source, version and language, upserted by a stable id.",{"title":840,"path":841,"stem":842,"icon":843,"description":844,"subcategory":13},"Meilisearch","\u002Fadd-ons\u002Fmeilisearch","5.add-ons\u002F2.meilisearch","simple-icons:meilisearch","Add the official companion layer for atomic build-time indexing and optional browser search.",{"title":846,"path":847,"stem":848,"children":849,"icon":851,"description":852,"subcategory":13},"Credits","\u002Fcredits","6.credits\u002Findex",[850],{"title":846,"path":847,"stem":848,"icon":851,"description":852,"subcategory":13},"lucide:heart","What duxt is built on, and what it was built after.",{"title":854,"path":855,"stem":856,"children":857},"Conventions","\u002Fconventions","7.conventions",[858,862,868,873],{"title":854,"path":855,"stem":859,"icon":860,"description":861,"subcategory":13},"7.conventions\u002Findex","lucide:ruler","Project-specific rules — the ones a reader could not infer from the code.",{"title":863,"path":864,"stem":865,"icon":866,"description":867,"subcategory":13},"Branding","\u002Fconventions\u002Fbranding","7.conventions\u002F1.branding","lucide:shapes","The [d]uxt mark — where each asset is used, why the icon's brackets are redrawn, and the colours that are fixed.",{"title":869,"path":870,"stem":871,"icon":353,"description":872,"subcategory":13},"Icons","\u002Fconventions\u002Ficons","7.conventions\u002F2.icons","Four icon sets, and the one question that decides which of them draws a given mark.",{"title":874,"path":875,"stem":876,"icon":91,"description":877,"subcategory":13},"Dependency security","\u002Fconventions\u002Fdependency-security","7.conventions\u002F3.dependency-security","Review dependency advisories without hiding affected paths.",{"title":879,"path":880,"stem":881,"children":882},"Architecture decisions","\u002Fadr","99.adr",[883,887,892,897,902,907,912,917,922,927,932,937],{"title":879,"path":880,"stem":884,"icon":885,"description":886,"subcategory":13},"99.adr\u002Findex","lucide:gavel","The decision log — every architecture decision recorded for duxt.",{"title":888,"path":889,"stem":890,"icon":13,"description":891,"subcategory":13},"Build duxt as a layer carrying a module","\u002Fadr\u002F0001-build-duxt-as-a-layer-carrying-a-module","99.adr\u002F0001-build-duxt-as-a-layer-carrying-a-module","Distribute the theme as a Nuxt layer whose root is the package, rather than as a starter template.",{"title":893,"path":894,"stem":895,"icon":13,"description":896,"subcategory":13},"Generate the collections from one source list","\u002Fadr\u002F0002-generate-the-collections-from-one-source-list","99.adr\u002F0002-generate-the-collections-from-one-source-list","Compute Content collections from a compact sources list at config load time instead of having consumers declare them.",{"title":898,"path":899,"stem":900,"icon":13,"description":901,"subcategory":13},"Decide the URL prefixes at build time","\u002Fadr\u002F0003-decide-the-url-prefixes-at-build-time","99.adr\u002F0003-decide-the-url-prefixes-at-build-time","Whether a repository or version segment appears is settled by the source list before the first request, never per request.",{"title":903,"path":904,"stem":905,"icon":13,"description":906,"subcategory":13},"Render Markdown components with MDC","\u002Fadr\u002F0004-render-markdown-components-with-mdc","99.adr\u002F0004-render-markdown-components-with-mdc","Use Content's own MDC syntax for components inside Markdown rather than adopting MDX.",{"title":908,"path":909,"stem":910,"icon":13,"description":911,"subcategory":13},"Ship the layer without owner-specific links","\u002Fadr\u002F0005-ship-the-layer-without-owner-specific-links","99.adr\u002F0005-ship-the-layer-without-owner-specific-links","Every default that would name a specific project — repository, issue tracker, community, imprint — ships empty.",{"title":913,"path":914,"stem":915,"icon":13,"description":916,"subcategory":13},"Rebuild on a schedule rather than refresh at runtime","\u002Fadr\u002F0006-rebuild-on-a-schedule-rather-than-refresh-at-runtime","99.adr\u002F0006-rebuild-on-a-schedule-rather-than-refresh-at-runtime","A site reading another repository picks up its changes when it builds, and no runtime refresh is offered.",{"title":918,"path":919,"stem":920,"icon":13,"description":921,"subcategory":13},"Serve translations as collections of their own","\u002Fadr\u002F0007-serve-translations-as-collections-of-their-own","99.adr\u002F0007-serve-translations-as-collections-of-their-own","Add a locale dimension to a source rather than a locale segment to the content path.",{"title":923,"path":924,"stem":925,"icon":13,"description":926,"subcategory":13},"Build the theme on owned shadcn-vue components","\u002Fadr\u002F0008-build-the-theme-on-owned-shadcn-vue-components","99.adr\u002F0008-build-the-theme-on-owned-shadcn-vue-components","The layer holds the source of its interface components rather than importing them from a component library or a ready-made documentation theme.",{"title":928,"path":929,"stem":930,"icon":13,"description":931,"subcategory":13},"Take the SEO stack from the Nuxt SEO bundle","\u002Fadr\u002F0009-take-the-seo-stack-from-the-nuxt-seo-bundle","99.adr\u002F0009-take-the-seo-stack-from-the-nuxt-seo-bundle","The layer installs @nuxtjs\u002Fseo and hands it the head tags and structured data it used to write by hand, keeping only the rules that depend on versions and translations.",{"title":933,"path":934,"stem":935,"icon":13,"description":936,"subcategory":13},"Keep Content's per-collection search as the default","\u002Fadr\u002F0010-keep-contents-per-collection-search-as-the-default","99.adr\u002F0010-keep-contents-per-collection-search-as-the-default","One index across every source was measured against Content's one-index-per-collection search and is not the layer's default; the build-time hook makes it a provider layer instead.",{"title":938,"path":939,"stem":940,"icon":13,"description":941,"subcategory":13},"Host the provider layers in a Turborepo monorepo","\u002Fadr\u002F0011-host-the-provider-layers-in-a-turborepo-monorepo","99.adr\u002F0011-host-the-provider-layers-in-a-turborepo-monorepo","The layer moves to packages\u002Fduxt and the site to apps\u002Fwww, every published package versions and tags on its own as \u003Cname>@vX.Y.Z, and the own-repository decision recorded in",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":946},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m8.001-2A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":948},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m5 8l6 6m-7 0l6-6l2-3M2 5h12M7 2h1m14 20l-5-10l-5 10m2-4h6\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":950},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 13v8m0-18v3m-9.646 4.354a1.207 1.207 0 0 1 0-1.708l2.06-2.06A2 2 0 0 1 5.828 6h12.344a2 2 0 0 1 1.414.586l2.06 2.06a1.207 1.207 0 0 1 0 1.708l-2.06 2.06a2 2 0 0 1-1.414.586H5.828a2 2 0 0 1-1.414-.586z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":952},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 5.88L14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88M7 10v12\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":954},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M3 3v16a2 2 0 0 0 2 2h16\"\u002F>\u003Cpath d=\"m19 9l-5 5l-4-4l-3 3\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":956},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09\"\u002F>\u003Cpath d=\"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z\"\u002F>\u003Cpath d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":958},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"m16.24 7.76l-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":960},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 5h.01M3 12h.01M3 19h.01M8 5h13M8 12h13M8 19h13\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":962},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.39 4.39a1 1 0 0 0 1.68-.474a2.5 2.5 0 1 1 3.014 3.015a1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474a2.5 2.5 0 1 0-3.014 3.015a1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474a2.5 2.5 0 1 1-3.014-3.015a1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474a2.5 2.5 0 1 0 3.014-3.015a1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":964},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Zm-6.8-2.8l2-2m-5-1l2-2m-5-1l2-2m7 11l2-2\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":966},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m14 13l-8.381 8.38a1 1 0 0 1-3.001-3l8.384-8.381M16 16l6-6m-.5.5l-8-8M8 8l6-6M8.5 7.5l8 8\"\u002F>",{"page":968,"from":1422,"asked":1423},{"id":969,"title":133,"body":970,"breadcrumb":1050,"category":13,"compare":13,"contributors":13,"copyPage":1050,"date":13,"description":137,"extension":1416,"feedback":1050,"fullWidth":945,"icon":136,"lastUpdated":13,"layout":13,"meta":1417,"navigation":1050,"pageInfo":1050,"page_title":13,"path":134,"prevNext":1050,"rawbody":1418,"redirectFrom":13,"release":13,"search":1050,"seo":1419,"sitemap":1420,"stem":135,"subcategory":13,"toc":13,"__hash__":1421},"docs\u002F3.guides\u002F11.cache-build-work.md",{"type":971,"value":972,"toc":1411},"minimark",[973,977,982,993,1117,1128,1135,1147,1154,1173,1177,1183,1274,1281,1284,1319,1332,1336,1407],[974,975,976],"p",{},"Two expensive build inputs can outlive an ephemeral CI runner without becoming\npart of the deployed site: Content's downloaded public repositories and the\nrendered OG-image cache. They have different invalidation rules, so duxt exposes\none command for each instead of sharing a key.",[978,979,981],"h2",{"id":980},"cache-downloaded-public-sources","Cache downloaded public sources",[974,983,984,988,989,992],{},[985,986,987],"code",{},"duxt-cache-key"," loads the resolved source list, after ",[985,990,991],{},"latest"," and release\nselection have become concrete refs, and emits the exact cache path and key.",[994,995,1001],"pre",{"className":996,"code":997,"filename":998,"language":999,"meta":1000,"style":1000},"language-yaml shiki shiki-themes github-light github-dark","- name: Resolve the remote-source cache key\n  id: sources\n  run: duxt-cache-key --root . --github >> \"$GITHUB_OUTPUT\"\n\n- name: Restore the downloaded sources\n  if: steps.sources.outputs.cacheable == 'true'\n  uses: actions\u002Fcache@v6\n  with:\n    path: ${{ steps.sources.outputs.paths }}\n    key: ${{ steps.sources.outputs.key }}\n",".github\u002Fworkflows\u002Fdeploy.yml","yaml","",[985,1002,1003,1023,1034,1045,1052,1064,1075,1086,1095,1106],{"__ignoreMap":1000},[1004,1005,1008,1012,1016,1019],"span",{"class":1006,"line":1007},"line",1,[1004,1009,1011],{"class":1010},"sVt8B","- ",[1004,1013,1015],{"class":1014},"s9eBZ","name",[1004,1017,1018],{"class":1010},": ",[1004,1020,1022],{"class":1021},"sZZnC","Resolve the remote-source cache key\n",[1004,1024,1026,1029,1031],{"class":1006,"line":1025},2,[1004,1027,1028],{"class":1014},"  id",[1004,1030,1018],{"class":1010},[1004,1032,1033],{"class":1021},"sources\n",[1004,1035,1037,1040,1042],{"class":1006,"line":1036},3,[1004,1038,1039],{"class":1014},"  run",[1004,1041,1018],{"class":1010},[1004,1043,1044],{"class":1021},"duxt-cache-key --root . --github >> \"$GITHUB_OUTPUT\"\n",[1004,1046,1048],{"class":1006,"line":1047},4,[1004,1049,1051],{"emptyLinePlaceholder":1050},true,"\n",[1004,1053,1055,1057,1059,1061],{"class":1006,"line":1054},5,[1004,1056,1011],{"class":1010},[1004,1058,1015],{"class":1014},[1004,1060,1018],{"class":1010},[1004,1062,1063],{"class":1021},"Restore the downloaded sources\n",[1004,1065,1067,1070,1072],{"class":1006,"line":1066},6,[1004,1068,1069],{"class":1014},"  if",[1004,1071,1018],{"class":1010},[1004,1073,1074],{"class":1021},"steps.sources.outputs.cacheable == 'true'\n",[1004,1076,1078,1081,1083],{"class":1006,"line":1077},7,[1004,1079,1080],{"class":1014},"  uses",[1004,1082,1018],{"class":1010},[1004,1084,1085],{"class":1021},"actions\u002Fcache@v6\n",[1004,1087,1089,1092],{"class":1006,"line":1088},8,[1004,1090,1091],{"class":1014},"  with",[1004,1093,1094],{"class":1010},":\n",[1004,1096,1098,1101,1103],{"class":1006,"line":1097},9,[1004,1099,1100],{"class":1014},"    path",[1004,1102,1018],{"class":1010},[1004,1104,1105],{"class":1021},"${{ steps.sources.outputs.paths }}\n",[1004,1107,1109,1112,1114],{"class":1006,"line":1108},10,[1004,1110,1111],{"class":1014},"    key",[1004,1113,1018],{"class":1010},[1004,1115,1116],{"class":1021},"${{ steps.sources.outputs.key }}\n",[974,1118,1119,1120,1123,1124,1127],{},"Use the directory containing the consuming Nuxt app as ",[985,1121,1122],{},"--root","; use ",[985,1125,1126],{},"."," when\nthe app is the repository root. Run the command after installing dependencies\nand before the Nuxt build.",[974,1129,1130,1131,1134],{},"The emitted paths include Content's downloaded checkouts and exclude\n",[985,1132,1133],{},"contents.sqlite*",". That database is a parse result, not a download: restoring\nit could hide an authored content change behind stale parsed rows.",[974,1136,1137,1138,1142,1143,1146],{},"The cache is ",[1139,1140,1141],"strong",{},"public sources only",". A cache produced on a protected branch can\nbe restored by a pull request, so one private, SSH or credential-bearing remote\nsets ",[985,1144,1145],{},"cacheable=false"," for the whole list. The workflow then skips the cache;\nduxt never mixes an unsafe remote with an otherwise public cache.",[974,1148,1149,1150,1153],{},"Run the command without ",[985,1151,1152],{},"--github"," to see the redacted inputs and the reason a\nsite is or is not cacheable:",[994,1155,1159],{"className":1156,"code":1157,"language":1158,"meta":1000,"style":1000},"language-bash shiki shiki-themes github-light github-dark","duxt-cache-key --root .\n","bash",[985,1160,1161],{"__ignoreMap":1000},[1004,1162,1163,1166,1170],{"class":1006,"line":1007},[1004,1164,987],{"class":1165},"sScJk",[1004,1167,1169],{"class":1168},"sj4cs"," --root",[1004,1171,1172],{"class":1021}," .\n",[978,1174,1176],{"id":1175},"cache-rendered-og-images","Cache rendered OG images",[974,1178,1179,1182],{},[985,1180,1181],{},"duxt-og-cache"," emits a rolling Actions key. The renderer dependency versions\nform its namespace, while the source revision lets a successful build save the\nnew images it added instead of freezing the first exact hit forever.",[994,1184,1186],{"className":996,"code":1185,"filename":998,"language":999,"meta":1000,"style":1000},"- name: Resolve the OG image cache key\n  id: og\n  run: duxt-og-cache --root . --run \"$GITHUB_SHA\" --github >> \"$GITHUB_OUTPUT\"\n\n- name: Restore the rendered OG images\n  uses: actions\u002Fcache@v6\n  with:\n    path: ${{ steps.og.outputs.path }}\n    key: ${{ steps.og.outputs.key }}\n    restore-keys: ${{ steps.og.outputs['restore-keys'] }}\n",[985,1187,1188,1199,1208,1217,1221,1232,1240,1246,1255,1264],{"__ignoreMap":1000},[1004,1189,1190,1192,1194,1196],{"class":1006,"line":1007},[1004,1191,1011],{"class":1010},[1004,1193,1015],{"class":1014},[1004,1195,1018],{"class":1010},[1004,1197,1198],{"class":1021},"Resolve the OG image cache key\n",[1004,1200,1201,1203,1205],{"class":1006,"line":1025},[1004,1202,1028],{"class":1014},[1004,1204,1018],{"class":1010},[1004,1206,1207],{"class":1021},"og\n",[1004,1209,1210,1212,1214],{"class":1006,"line":1036},[1004,1211,1039],{"class":1014},[1004,1213,1018],{"class":1010},[1004,1215,1216],{"class":1021},"duxt-og-cache --root . --run \"$GITHUB_SHA\" --github >> \"$GITHUB_OUTPUT\"\n",[1004,1218,1219],{"class":1006,"line":1047},[1004,1220,1051],{"emptyLinePlaceholder":1050},[1004,1222,1223,1225,1227,1229],{"class":1006,"line":1054},[1004,1224,1011],{"class":1010},[1004,1226,1015],{"class":1014},[1004,1228,1018],{"class":1010},[1004,1230,1231],{"class":1021},"Restore the rendered OG images\n",[1004,1233,1234,1236,1238],{"class":1006,"line":1066},[1004,1235,1080],{"class":1014},[1004,1237,1018],{"class":1010},[1004,1239,1085],{"class":1021},[1004,1241,1242,1244],{"class":1006,"line":1077},[1004,1243,1091],{"class":1014},[1004,1245,1094],{"class":1010},[1004,1247,1248,1250,1252],{"class":1006,"line":1088},[1004,1249,1100],{"class":1014},[1004,1251,1018],{"class":1010},[1004,1253,1254],{"class":1021},"${{ steps.og.outputs.path }}\n",[1004,1256,1257,1259,1261],{"class":1006,"line":1097},[1004,1258,1111],{"class":1014},[1004,1260,1018],{"class":1010},[1004,1262,1263],{"class":1021},"${{ steps.og.outputs.key }}\n",[1004,1265,1266,1269,1271],{"class":1006,"line":1108},[1004,1267,1268],{"class":1014},"    restore-keys",[1004,1270,1018],{"class":1010},[1004,1272,1273],{"class":1021},"${{ steps.og.outputs['restore-keys'] }}\n",[974,1275,1276,1277,1280],{},"The consuming site's Nuxt config must also register the OG cache integration\nexported by ",[985,1278,1279],{},"@kirchdev\u002Fduxt\u002Fog-image-cache",". That build-side fingerprint covers\nthe site-owned inputs the pre-build CLI cannot safely load, such as template\noptions and fonts. When they move, the integration empties the restored\ndirectory before any stale image can be served.",[974,1282,1283],{},"After the build, report what the cache actually reused:",[994,1285,1287],{"className":1156,"code":1286,"language":1158,"meta":1000,"style":1000},"duxt-og-cache --root . --report --since \"$STARTED_MS\" --log build.log\n",[985,1288,1289],{"__ignoreMap":1000},[1004,1290,1291,1293,1295,1298,1301,1304,1307,1310,1313,1316],{"class":1006,"line":1007},[1004,1292,1181],{"class":1165},[1004,1294,1169],{"class":1168},[1004,1296,1297],{"class":1021}," .",[1004,1299,1300],{"class":1168}," --report",[1004,1302,1303],{"class":1168}," --since",[1004,1305,1306],{"class":1021}," \"",[1004,1308,1309],{"class":1010},"$STARTED_MS",[1004,1311,1312],{"class":1021},"\"",[1004,1314,1315],{"class":1168}," --log",[1004,1317,1318],{"class":1021}," build.log\n",[974,1320,1321,1322,1324,1325,1328,1329,1126],{},"Add ",[985,1323,1152],{}," when the report is written to ",[985,1326,1327],{},"$GITHUB_OUTPUT","; its plain form is\nsuited to a terminal or ",[985,1330,1331],{},"$GITHUB_STEP_SUMMARY",[978,1333,1335],{"id":1334},"checklist","Checklist",[1337,1338,1341,1351,1360,1369,1375,1383,1389,1395,1401],"ul",{"className":1339},[1340],"contains-task-list",[1342,1343,1346,1350],"li",{"className":1344},[1345],"task-list-item",[1347,1348],"input",{"disabled":1050,"type":1349},"checkbox"," Dependencies are installed before either key command runs.",[1342,1352,1354,1356,1357,1359],{"className":1353},[1345],[1347,1355],{"disabled":1050,"type":1349}," ",[985,1358,1122],{}," names the consuming Nuxt application.",[1342,1361,1363,1365,1366,1126],{"className":1362},[1345],[1347,1364],{"disabled":1050,"type":1349}," The source cache step is conditional on ",[985,1367,1368],{},"cacheable == 'true'",[1342,1370,1372,1374],{"className":1371},[1345],[1347,1373],{"disabled":1050,"type":1349}," The source cache uses no broad restore key.",[1342,1376,1378,1356,1380,1382],{"className":1377},[1345],[1347,1379],{"disabled":1050,"type":1349},[985,1381,1133],{}," remains excluded from the source cache.",[1342,1384,1386,1388],{"className":1385},[1345],[1347,1387],{"disabled":1050,"type":1349}," No private or authenticated source is forced into an Actions cache.",[1342,1390,1392,1394],{"className":1391},[1345],[1347,1393],{"disabled":1050,"type":1349}," The OG cache uses the emitted rolling restore keys.",[1342,1396,1398,1400],{"className":1397},[1345],[1347,1399],{"disabled":1050,"type":1349}," The consuming Nuxt config fingerprints site-owned rendering inputs.",[1342,1402,1404,1406],{"className":1403},[1345],[1347,1405],{"disabled":1050,"type":1349}," The post-build report uses the same cache directory as the build.",[1408,1409,1410],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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}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 .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":1000,"searchDepth":1025,"depth":1054,"links":1412},[1413,1414,1415],{"id":980,"depth":1025,"text":981},{"id":1175,"depth":1025,"text":1176},{"id":1334,"depth":1025,"text":1335},"md",{},"---\ntitle: Cache remote sources and OG images\ndescription: Reuse downloaded public repositories and rendered social cards safely between CI builds.\nicon: lucide:database-zap\n---\n\nTwo expensive build inputs can outlive an ephemeral CI runner without becoming\npart of the deployed site: Content's downloaded public repositories and the\nrendered OG-image cache. They have different invalidation rules, so duxt exposes\none command for each instead of sharing a key.\n\n## Cache downloaded public sources\n\n`duxt-cache-key` loads the resolved source list, after `latest` and release\nselection have become concrete refs, and emits the exact cache path and key.\n\n```yaml [.github\u002Fworkflows\u002Fdeploy.yml]\n- name: Resolve the remote-source cache key\n  id: sources\n  run: duxt-cache-key --root . --github >> \"$GITHUB_OUTPUT\"\n\n- name: Restore the downloaded sources\n  if: steps.sources.outputs.cacheable == 'true'\n  uses: actions\u002Fcache@v6\n  with:\n    path: ${{ steps.sources.outputs.paths }}\n    key: ${{ steps.sources.outputs.key }}\n```\n\nUse the directory containing the consuming Nuxt app as `--root`; use `.` when\nthe app is the repository root. Run the command after installing dependencies\nand before the Nuxt build.\n\nThe emitted paths include Content's downloaded checkouts and exclude\n`contents.sqlite*`. That database is a parse result, not a download: restoring\nit could hide an authored content change behind stale parsed rows.\n\nThe cache is **public sources only**. A cache produced on a protected branch can\nbe restored by a pull request, so one private, SSH or credential-bearing remote\nsets `cacheable=false` for the whole list. The workflow then skips the cache;\nduxt never mixes an unsafe remote with an otherwise public cache.\n\nRun the command without `--github` to see the redacted inputs and the reason a\nsite is or is not cacheable:\n\n```bash\nduxt-cache-key --root .\n```\n\n## Cache rendered OG images\n\n`duxt-og-cache` emits a rolling Actions key. The renderer dependency versions\nform its namespace, while the source revision lets a successful build save the\nnew images it added instead of freezing the first exact hit forever.\n\n```yaml [.github\u002Fworkflows\u002Fdeploy.yml]\n- name: Resolve the OG image cache key\n  id: og\n  run: duxt-og-cache --root . --run \"$GITHUB_SHA\" --github >> \"$GITHUB_OUTPUT\"\n\n- name: Restore the rendered OG images\n  uses: actions\u002Fcache@v6\n  with:\n    path: ${{ steps.og.outputs.path }}\n    key: ${{ steps.og.outputs.key }}\n    restore-keys: ${{ steps.og.outputs['restore-keys'] }}\n```\n\nThe consuming site's Nuxt config must also register the OG cache integration\nexported by `@kirchdev\u002Fduxt\u002Fog-image-cache`. That build-side fingerprint covers\nthe site-owned inputs the pre-build CLI cannot safely load, such as template\noptions and fonts. When they move, the integration empties the restored\ndirectory before any stale image can be served.\n\nAfter the build, report what the cache actually reused:\n\n```bash\nduxt-og-cache --root . --report --since \"$STARTED_MS\" --log build.log\n```\n\nAdd `--github` when the report is written to `$GITHUB_OUTPUT`; its plain form is\nsuited to a terminal or `$GITHUB_STEP_SUMMARY`.\n\n## Checklist\n\n- [ ] Dependencies are installed before either key command runs.\n- [ ] `--root` names the consuming Nuxt application.\n- [ ] The source cache step is conditional on `cacheable == 'true'`.\n- [ ] The source cache uses no broad restore key.\n- [ ] `contents.sqlite*` remains excluded from the source cache.\n- [ ] No private or authenticated source is forced into an Actions cache.\n- [ ] The OG cache uses the emitted rolling restore keys.\n- [ ] The consuming Nuxt config fingerprints site-owned rendering inputs.\n- [ ] The post-build report uses the same cache directory as the build.\n",{"title":133,"description":137},{"loc":134},"5KVK9VNHXowgdggVujJNtPrZSU-1OJsHb2Fx5RtifAY","en-GB","en-US",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1425},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"13\" r=\"2\"\u002F>\u003Cpath d=\"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Zm-6-7h3M7 13h3\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1427},"\u003Cpath fill=\"currentColor\" d=\"M1.44 0v7.575l6.561 3.79V3.787zm21.12 4.227l-6.561 3.791v7.574l6.56-3.787zM8.72 4.23v7.575l6.561 3.787V8.018zm0 8.405v7.575L15.28 24v-7.578z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1429},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"\u002F>\u003Cpath d=\"M3 5v14a9 3 0 0 0 12 2.84M21 5v3m0 4l-3 5h4l-3 5\"\u002F>\u003Cpath d=\"M3 12a9 3 0 0 0 11.59 2.87\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1431},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"18\" cy=\"18\" r=\"3\"\u002F>\u003Ccircle cx=\"6\" cy=\"6\" r=\"3\"\u002F>\u003Cpath d=\"M13 6h3a2 2 0 0 1 2 2v7m-7 3H8a2 2 0 0 1-2-2V9\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1433},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12 22a1 1 0 0 1 0-20a10 9 0 0 1 10 9a5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z\"\u002F>\u003Ccircle cx=\"13.5\" cy=\"6.5\" r=\".5\" fill=\"currentColor\"\u002F>\u003Ccircle cx=\"17.5\" cy=\"10.5\" r=\".5\" fill=\"currentColor\"\u002F>\u003Ccircle cx=\"6.5\" cy=\"12.5\" r=\".5\" fill=\"currentColor\"\u002F>\u003Ccircle cx=\"8.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1435},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12 13v8m-8-6.101A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\"\u002F>\u003Cpath d=\"m8 17l4-4l4 4\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1437},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M3.85 8.62a4 4 0 0 1 4.78-4.77a4 4 0 0 1 6.74 0a4 4 0 0 1 4.78 4.78a4 4 0 0 1 0 6.74a4 4 0 0 1-4.77 4.78a4 4 0 0 1-6.75 0a4 4 0 0 1-4.78-4.77a4 4 0 0 1 0-6.76\"\u002F>\u003Cpath d=\"m16 9l-5.5 5.5L8 12\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1439},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1441},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1443},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 18.12L10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88M17 14V2\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1445},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.12 2.12 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.12 2.12 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.12 2.12 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.12 2.12 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.12 2.12 0 0 0 1.597-1.16z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1447},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 8v4m0 4h.01\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1449},"\u003Cpath fill=\"currentColor\" d=\"M20.317 4.37a19.8 19.8 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.3 18.3 0 0 0-5.487 0a13 13 0 0 0-.617-1.25a.08.08 0 0 0-.079-.037A19.7 19.7 0 0 0 3.677 4.37a.1.1 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.08.08 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.08.08 0 0 0 .084-.028a14 14 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13 13 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10 10 0 0 0 .372-.292a.07.07 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.07.07 0 0 1 .078.01q.181.149.373.292a.077.077 0 0 1-.006.127a12.3 12.3 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.08.08 0 0 0 .084.028a19.8 19.8 0 0 0 6.002-3.03a.08.08 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.06.06 0 0 0-.031-.03M8.02 15.33c-1.182 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418m7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1451},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m4-8h2m-2-4h2m2.001 10A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2zM6 13h2M6 9h2\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1453},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h10v10M7 17L17 7\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1455,"hidden":1050},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4\"\u002F>\u003Cpath d=\"M14 2v4a2 2 0 0 0 2 2h4M5 12l-3 3l3 3m4 0l3-3l-3-3\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1457},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1459},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1461},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 8h.01M12 12h.01M14 8h.01M16 12h.01M18 8h.01M6 8h.01M7 16h10m-9-4h.01\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1463},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1465},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1467},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 19l-7-7l7-7m7 7H5\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1469},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":1471},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",[1473,1474,1475],"\u002Fv0.3.4\u002Fguides\u002Fcache-build-work","\u002Fv0.2.0\u002Fguides\u002Fcache-build-work","\u002Fv0.1.0\u002Fguides\u002Fcache-build-work",{"left":943,"top":943,"width":1477,"height":1478,"rotate":943,"vFlip":945,"hFlip":945,"body":1479},640,480,"\u003Cpath fill=\"#bd3d44\" d=\"M0 0h640v480H0\"\u002F>\u003Cpath stroke=\"#fff\" stroke-width=\"37\" d=\"M0 55.3h640M0 129h640M0 203h640M0 277h640M0 351h640M0 425h640\"\u002F>\u003Cpath fill=\"#192f5d\" d=\"M0 0h364.8v258.5H0\"\u002F>\u003Cmarker id=\"SVGEq3dreKJ\" markerHeight=\"30\" markerWidth=\"30\">\u003Cpath fill=\"#fff\" d=\"m14 0l9 27L0 10h28L5 27z\"\u002F>\u003C\u002Fmarker>\u003Cpath fill=\"none\" marker-mid=\"url(#SVGEq3dreKJ)\" d=\"m0 0l16 11h61h61h61h61h60L47 37h61h61h60h61L16 63h61h61h61h61h60L47 89h61h61h60h61L16 115h61h61h61h61h60L47 141h61h61h60h61L16 166h61h61h61h61h60L47 192h61h61h60h61L16 218h61h61h61h61h60z\"\u002F>",1792683264867]