@graphglue/dokka-vitepress
v1.0.0
Published
Turns Dokka HTML output into a VitePress API reference: markdown pages, a sidebar, and scoped Dokka styles.
Maintainers
Readme
dokka-vitepress
Turns Dokka HTML output into a VitePress API reference: one markdown page per declaration, a nested sidebar, and a stylesheet derived from Dokka's own CSS.
Replaces the older dokka-html-mdx-transform GitHub Action and dokka-docusaurus component: the transform is a plain CLI you can run anywhere, and the runtime component ships in the same package.
Tested against Dokka 2.2.0.
How it works
Dokka already produces a complete HTML site. This package takes that output apart and puts the useful half back together for VitePress:
- Pages. The
#contentelement of every Dokka page becomes a markdown page. The heading and breadcrumb trail are lifted out into real markdown so they end up in the page outline, the navigation and the local search index. The body is written to a.dokka.htmlsidecar and pulled in through Vite's?rawimport, keeping Dokka's markup away from the Vue template compiler. - Styles. Dokka's stylesheets are read from the output being transformed and rewritten so every selector is scoped to the wrapper element. Nothing is vendored into this package, so the styling follows whichever Dokka version produced the input. Selectors that only match page chrome - the navigation bar, sidebar and footer - are dropped.
- Links.
foo.htmlbecomesfooandfoo/index.htmlbecomesfoo/, which keeps Dokka's relative links resolving correctly on a site served withcleanUrls: true. Because the links stay plain anchors, VitePress' router turns them into client-side navigation on its own. - Sidebar. Packages are nested by their dot-separated name, and every entry is tagged with the kind of declaration it documents so it can carry the matching Dokka icon.
The generated pages are server-rendered, so the API reference is in the static HTML and readable without JavaScript.
Usage
npm install --save-dev @graphglue/dokka-vitepressGenerate the Dokka output, then transform it:
./gradlew dokkaGenerate
npx dokka-vitepress \
--src build/dokka/html \
--out website/docs/api \
--assets website/.vitepress/dokka \
--link-prefix /api/Register the component and the stylesheets in the VitePress theme:
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import { useDokka } from '@graphglue/dokka-vitepress/client'
// These three are a cascade and have to stay in this order, see "Stylesheets" below.
import '@graphglue/dokka-vitepress/base.css'
import '../dokka/dokka.css'
import '@graphglue/dokka-vitepress/theme.css'
// Order-independent: styles the generated entries in VitePress' own sidebar.
import '@graphglue/dokka-vitepress/sidebar.css'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
useDokka(app)
}
}Wire up the sidebar and turn on clean URLs:
// .vitepress/config.ts
import sidebar from './dokka/sidebar.json' with { type: 'json' }
export default defineConfig({
cleanUrls: true,
themeConfig: {
sidebar: { '/api/': [{ text: 'API Reference', link: '/api/', items: sidebar }] }
}
})Both --out and --assets are wiped and rewritten on every run, so add them to .gitignore.
Stylesheets
The styling is split into named exports so a site can place each part at the right point in its cascade. Three of them form one cascade and must be imported in this order:
| Import | Role |
| --- | --- |
| @graphglue/dokka-vitepress/base.css | The page frame: the heading, breadcrumb trail and wrapper that surround the embedded content. Deliberately low-specificity so Dokka's own rules win over it |
| <assets>/dokka.css | Generated. Dokka's own stylesheets, scoped to the wrapper |
| @graphglue/dokka-vitepress/theme.css | Re-skins the result in VitePress' design tokens: colours, fonts, radii, spacing. Mirrors Dokka's selectors and wins on cascade order, so it has to come last |
@graphglue/dokka-vitepress/sidebar.css is independent of that order and styles the generated
entries in VitePress' sidebar.
Because theme.css works mostly by pointing Dokka's custom properties at --vp-* tokens, a site
that sets its own --vp-c-brand-* re-brands the API reference along with the rest of the site; no
Dokka-specific overrides needed. To restyle further, add rules after theme.css.
Only want Dokka's original look? Import base.css and dokka.css and skip theme.css.
Options
| Option | Default | Description |
| --- | --- | --- |
| --src | required | Dokka HTML output, i.e. the directory holding index.html and styles/ |
| --out | required | Where the markdown pages go. Must be inside the VitePress srcDir |
| --assets | required | Where the stylesheet, fonts, images, sidebar and search index go. Put this inside .vitepress so the files are not treated as pages |
| --link-prefix | /<out basename>/ | Site-absolute prefix the pages are served under |
| --modules | all | Comma-separated list of Dokka modules to transform |
| --nested-members | off | Also list class members in the sidebar. Off by default: it is the difference between a few hundred and a few thousand entries, and members stay reachable from their class page, the breadcrumb trail and search |
| --scope | dokka | CSS class the content is wrapped in |
| --dark-selector | html.dark | Selector that marks dark mode on the site |
| --page-class | api-page | pageClass frontmatter value set on generated pages |
| --quiet | off | Only report errors |
Generated files
Inside --assets:
| File | Contents |
| --- | --- |
| dokka.css | Dokka's stylesheets, scoped to the wrapper, plus the sidebar kind icons. The icons are generated rather than shipped so they follow the Dokka version that produced the input |
| sidebar.json | Sidebar items in VitePress' format. Entry labels are HTML, which VitePress renders with v-html |
| symbols.json | Every documented symbol with its name, qualified name, kind, module and link - a ready-made index for a custom API search |
| images/, ui-kit/fonts/ | The assets dokka.css refers to |
Programmatic use
import { transform } from '@graphglue/dokka-vitepress'
const { pages, sidebar, symbols } = await transform({
src: 'build/dokka/html',
out: 'website/docs/api',
assets: 'website/.vitepress/dokka',
linkPrefix: '/api/'
})scopeDokkaCss and parseDokkaPage are exported as well, if you only need one half of the work.
Releasing
Published to npm by .github/workflows/publish.yml when a GitHub
release is published, using npm trusted publishing -
OIDC instead of a long-lived NPM_TOKEN, with a provenance attestation attached automatically.
One-time setup on npmjs.com, under the package's Settings -> Trusted publishers:
| Field | Value |
| --- | --- |
| Organization or user | graphglue |
| Repository | dokka-vitepress |
| Workflow filename | publish.yml |
| Environment | (leave empty) |
The workflow filename is part of what npm verifies, so renaming publish.yml means updating the
trusted publisher configuration to match.
To cut a release:
- Bump
versioninpackage.jsonand merge it tomain. - Publish a GitHub release whose tag is that version (
1.2.3orv1.2.3).
The workflow refuses to publish when the tag and package.json disagree, so a forgotten version
bump fails loudly instead of republishing the previous version.
Notes and limitations
- The source-set filter in Dokka's header is not carried over, so multiplatform projects show every source set at once. Per-signature platform switches do work.
- Images referenced from KDoc comments are not rewritten; only the assets Dokka's own stylesheets reference are copied.
- Anchors are Dokka's percent-encoded ids rather than readable slugs, because they have to keep matching the links Dokka generates between pages.
License
Apache-2.0. The generated stylesheet and the copied icons and fonts are derived from Dokka and remain under Dokka's Apache 2.0 license.
