doc-kit generate writes a fully static site, so publishing
is as simple as hosting the output directory.
npx @doc-kit/cli generate
Everything lands in your configured output directory (out/ by
convention). Two things to know about the result:
-
The
htmlsite must be served over HTTP. Its pages use import maps and client-side hydration, so opening the files withfile://may show unstyled or inert pages. Preview a production build the same way you'd host it:npx serve out -
Search requires its index. If your site uses search, generate the index alongside the pages by targeting both generators —
target: ['html', 'orama-db'], so the search box has data to query.
Every file the html generator writes to assets/ (scripts, stylesheets,
fonts) is named after a hash of its content, so a changed file always gets a
new name. Serve that directory with a long-lived, immutable cache, and let
everything else (the pages, the search index) revalidate:
/assets/* Cache-Control: public, max-age=31536000, immutable
Most hosts default to revalidating every file on every load instead, which costs a request per asset each time a new tab opens the site. On Vercel:
{ "headers": [ { "source": "/assets/(.*)", "headers": [ { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" } ] } ] }
Within a visit, moving between pages loads no assets at all: the site navigates client-side, swapping in the next page's content.
doc-kit doesn't minify its output by default: compressed (gzip or brotli), as hosts serve it, it is far smaller than minifying would make it.
Cloudflare, Vercel, Netlify, and GitHub Pages compress on their own, and so
does npx serve out. If you serve the output yourself, turn compression on:
- nginx:
gzip on;compresses HTML; add the other types withgzip_types text/css application/javascript application/json;. - Caddy:
encode zstd gzip. - Apache: with
mod_deflate,AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json. - Amazon S3: serve the bucket through CloudFront, with Compress objects automatically on.
Set baseURL to where the site will live. Generators that emit absolute
URLs (e.g., sitemap, llms-txt) will need it in order to generate their
output.
export default { global: { baseURL: 'https://example.com/docs', }, html: { // Where a page's canonical URL lives; {path} is filled per page pageURL: 'https://example.com/docs{path}.html', }, };
Search engines and language models each get their own artifact — add the generators and they share the same parse:
target: ['html', 'orama-db', 'sitemap', 'llms-txt'],
sitemap emits sitemap.xml; llms-txt emits an
llms.txt index of your pages.
The version selector in the sidebar is built from your changelog — a
release history the generators parse into selectable versions. Point
global.changelog at a CHANGELOG.md (URL or path) that lists your
releases, and each build renders its version with links to the others. A
project without release history simply gets no selector. See the
configuration reference for the accepted formats.