Skip to content
duxt

Configuration

Every key under duxt in app.config.ts — what it controls, and when it is read.

Everything below lives under duxt in your app/app.config.ts. How the merge works, and why arrays replace rather than append, is in Configuration.

Site

KeyDefaultWhat it controls
titlenoneThe name in the navbar and in the SEO title
logononeA wordmark replacing the icon-and-name pair — see below
versionnoneThe badge beside it
organizationnoneWho publishes the site, for schema.org — see below
localesall sevenWhich of the layer's languages this site serves
breadcrumbtruefalse drops the trail above the page title
pageIconnoneIcon for any page whose frontmatter sets none — a section's own wins
packageManagerspnpm, npm, yarn, bunWhich managers a command block offers, in that order
requestSamplesseven of twelveWhich code samples the try-it client offers — see Request samples
sampleLanguagesnoneExtra Shiki grammars, for x-codeSamples in a language no sample names
poweredByonfalse drops the "Powered by duxt" line from the footer
FieldTypeNotes
srcstringThe mark. Unset leaves the generic icon beside title
srcDarkstringSwapped in by CSS under the dark class, not by script
alttextFalls back to title

Setting one is Brand your site.

organization

The Organization node search engines and AI summaries read to name a source. Absent until you set it: duxt renders somebody else's documentation and does not guess whose.

FieldTypeNotes
nametextThe publisher's name. Nothing is published without it
urlstringTheir site. Falls back to site.url
logostringAbsolute, or a path from the site root; square and 112px or more

A section entry is a link plus one field of its own:

FieldTypeNotes
pageIconstringIcon for pages in this section that set none. Overrides duxt.pageIcon; a page's own frontmatter still wins

Useful where pages cannot carry an icon at all — an ADR's frontmatter is fixed at title, description, status and date, so the decision log otherwise renders without one.

KeyDefaultWhat it controls
navigationone entryNavbar links; an entry with children becomes a dropdown
sectionsemptyThe second navbar row — the top-level parts of the docs
linksemptyIcon links on the right of the navbar
asidetitle onlytitle and links under the table of contents
footeremptycopyright and legal
landingone actionThe page at /

Most of these ship empty, for two different reasons. links, aside.links, footer.legal, title, version and the landing copy name a specific project — a repository, a community, a name, a release, a sentence about what it does — and belong to whoever runs the site. sections names the parts of a documentation tree, and the tree is yours: four tabs pointing at folder names the layer guessed would lead nowhere. Until you set it, the row does not render and the sidebar shows the whole tree, which is the right shape for docs that are not split into sections.

One row per source. An entry belongs to the source whose URL prefix it lies under, and the row shows the entries of the source the reader is in — so a site with documentation at the root and something else at /demo writes one sections list and each area draws its own part of it. A generated section under an area (/demo/api) belongs to that area rather than being one of its own. A site with a single source has one area, every entry is inside it, and the row is exactly the list as written.

Landing

The page at / draws three bands, and each one is absent until its key is set.

KeyDefaultWhat it draws
badgenoneThe pill above the headline — text, or a badge object
headlinenoneThe h1; falls back to title
descriptionnoneThe paragraph under it, and the page's meta description
actionsone, "Read the docs"The hero buttons; an action with no to resolves to the first section
commandnoneA copyable install command under the buttons
previewnoneA page of this site, embedded in a browser window
featuresemptyThe card grid

command is a plain string, not text: a shell command is the same in every language, and one translated by mistake is one that does not run. The layer ships none — it does not know what your project is called, the same reason links is empty.

There is no closing call to action, deliberately. The hero's buttons are the call; repeating them under a card grid asks a reader who has just arrived to decide twice.

badge ships empty for the same reason as links: a pill above the headline says something about the state of a project — "beta", "v2 is out" — and the layer knows nothing about the state of yours. A string is the short form; the object adds an icon, a colour and a destination.

badge fieldTypeNotes
labeltextRequired. {version} is replaced with the site's version
iconstringAny Iconify name
variantstringdefault, secondary, outline, success, destructive
tostringMakes the whole pill a link
externalbooleanThe new tab
badge: {
  label: '{version} released',
  icon: 'lucide:rocket',
  variant: 'success',
  to: 'https://github.com/acme/sdk/releases/latest',
  external: true
}

preview is a live window, not a picture. It embeds a page of this site in a browser frame the reader can scroll, navigate and switch the theme of without leaving the landing page. The frame mounts only once the band scrolls into view, and never during server rendering — an iframe in the initial HTML is a second full page load competing with the first.

preview fieldTypeNotes
tostringThe page to embed; defaults to the first section
heightstringAny CSS length. Default 32rem, 24rem under sm
srcstringA screenshot INSTEAD of the live page
srcDarkstringServes dark mode; without it src serves both
alttextThe image's alt text, and the frame's accessible name
FieldTypeNotes
labeltextRequired
tostringA documentation path is localised; a URL is not
iconstringAny Iconify name, e.g. lucide:rocket
descriptiontextShown in a navbar dropdown
externalbooleanThe new tab and the arrow — never the routing
childrenDuxtLink[]Turns a navbar entry into a dropdown
variantbutton variantlanding.actions only

Every field marked text takes a literal, an i18n key or a per-locale record — see Localisation.

Sources

KeyRead atWhat it controls
sourcesbuild timeThe documentation sources
sourceOptionsbuild timeHow those sources become URL prefixes
versionsruntimeOverrides the derived versions, when they need labels or descriptions

Both source keys have their own page. locales is the third build-time key: changing any of the three needs a rebuild.

The feed

/rss.xml is empty until feed.path names a section:

feed: { path: '/changelog', title: 'my project — releases' }

Off by default on purpose. A feed is a list of things that happened, and a reference page being edited is not an event — a site publishing every page edit as an item teaches its readers to unsubscribe. Items are ordered by a page's own date, falling back to the last commit that touched it, and only the default version of each source contributes, so a versioned changelog does not repeat every entry once per version.

The section it is usually pointed at is a release history, whose pages carry a date each.

Generated, not written

KeyWritten byHolds
resolvedSourcesthe buildThe manifest: which collection serves which prefix
layerVersionthe buildduxt's own version, for the footer
layerRepositorythe buildduxt's own repository, for the footer

Setting any of the three by hand is overwritten on the next build.

Was this page helpful?