Versioned docs, from the repositories you already have
duxt is a Nuxt layer: extend it and your docs/ folder becomes a site — theme, search, API reference and llms.txt included. Point it at other repositories, or at tags of the same one, and each becomes a version.
- line of config
- 1
- locales shipped
- 7
- licensed, open source
- MIT
Live demo
Setup
One line, and the folder is a site
duxt is a Nuxt layer, so extending it brings the theme, the pages, the components and the build steps at once — and leaves every one of them replaceable.
- No generator and nothing to eject — your repository keeps its own files.
- Override a component by putting your own at the same path.
- Builds to a static site — deploy it anywhere Nuxt goes.
export default defineNuxtConfig({
extends: ['@kirchdev/duxt']
})
Sources
Several repositories, several versions, one list
A source is a repository and the refs to publish from it. duxt turns the list into one collection per version and repo, and into the URL prefixes that keep them apart — decided at build time, so nothing is resolved while a reader waits.
- Cloning, private-repo auth and caching are Content v3’s own, not a rebuild.
- A single source needs no prefix at all — a segment with one value distinguishes nothing.
- The switcher stays on the page you are reading, and says when it does not exist there.
sources: [
// The repository you are standing in.
{ path: 'docs' },
// Another one, at three of its tags.
{
repo: 'acme/api',
path: 'docs',
refs: [
{ branch: 'main', status: 'upcoming' },
{ tag: 'v2.0.0' },
{ tag: 'v1.4.0', status: 'eol' }
]
}
],
sourceOptions: { defaultRef: 'v2.0.0' }
API reference
An OpenAPI document, published as pages
Point a source at the file and duxt builds an overview, a page per tag and a page per operation — with the schemas expanded, the security named and the examples derived. They are an ordinary collection, which is the whole point.
- Search finds them, llms.txt lists them, the sitemap carries them.
- Versioned like the prose: the switcher moves between two versions of one endpoint.
- Written next to your Markdown — an operation page can carry prose of its own.
Try it
A client that sends the real request
Every operation page carries a client. Fill in the parameters, edit the body against its schema, send it from your own browser — and read the response beside the sample that would have produced it.
- Seven samples out of the box, twelve shipped, or one of your own — rewritten as you type.
- The body editor is CodeMirror, loaded on demand: a page without an endpoint downloads none of it.
- Your token stays in your browser — there is no server in this to send it to.
Send a request
In your stack
The same request, in your own language
Not an example of a request like the one above — that request. The server you picked, the token you typed and the body you edited, rewritten on every keystroke into whichever client you are going to paste it in.
- One component, so the sample and the button can never disagree.
- Add your own with `requestSamples`, or drop the ones your readers do not use.
Request sample
curl '/demo/echo' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer demo-token' \
-d '{
"reference": "HB-1042",
"mode": "sea"
}'Machine readers
Written for the model reading it too
The same content, published a second time in the shapes a machine reads: an index at llms.txt, the whole site at llms-full.txt, every page available as its own Markdown, and an MCP route an assistant can search.
- Build output, not a runtime service — the files are on the CDN with the pages.
- Every page has a "copy as Markdown", and a link that opens it in an assistant.
- The MCP route serves the same collections the site queries — one source, two readers.
Features
Extend, don't scaffold
One line of config brings theme, pages and components — override any file.
Sources as a list
One declaration per source instead of one collection per version and repo.
Versions that switch
A tag becomes a version, and the switcher stays on the page you are reading.
Localised out of the box
The interface is translated; your pages carry a locale prefix and an hreflang.
Git-native, not reinvented
Branches, tags, private repos and caching come from Content v3 itself.
shadcn-vue
Components are copied in, not imported. Restyling one is editing a file.
Components in Markdown
MDC ships with Content — call a Vue component with block syntax.
Machine-readable
llms.txt and an MCP route over the same content, planned as build output.