Combine guides + API
This is the theme's signature capability: hand-written guides and a generated API reference in one site — one sidebar, one search index, one URL space. No second site to deploy, no context-switch for your readers.
You've seen the two halves already:
- Build a guides site — prose pages from a
docsfolder. - Build an API reference — generated pages from your source.
Turn both on at once and they merge. This page is the mental model for how.
The whole picture in one config
{
source: { include: ["./src", "./README.md"] },
plugins: ["plugins/markdown"],
opts: {
destination: "dist",
recurse: true,
template: "node_modules/clean-jsdoc-theme/dist",
readme: "./README.md", // → home page
docs: "./docs", // → prose guide pages
// src above → generated API pages
sectionOrder: ["Getting Started", "Guides", "Classes", "Modules"],
},
}{
entryPoints: ["src/index.ts"],
readme: "README.md", // → home page
plugin: ["@clean-jsdoc-theme/typedoc"],
outputs: [{ name: "clean-jsdoc-theme", path: "dist" }],
cleanJsdocTheme: {
docs: "./docs", // → prose guide pages
sectionOrder: ["Getting Started", "Guides", "Classes", "Modules"],
},
}That single build produces guide pages, API pages, the home page, and (for JSDoc, by default) the source viewer — all stitched into one nav.
The mental model
Everything funnels into one flat list of pages and one call to assembleNav (in packages/setu/src/generate-site.ts). The sources are different, but the sidebar treats them uniformly:
-
Home — always first, always ungrouped. The README home page, unless a docs-root
index.mdexists, which overrides it. -
Sections, in the effective order (below). Each top-level group is a bold sidebar title:
- API kind sections — Classes, Modules, Namespaces, … for untagged symbols; or your own
@categorygroup names. - Doc groups — the groups your guide pages declare (frontmatter or directory).
- Tutorials — if you use the JSDoc
--tutorialsdirectory.
- API kind sections — Classes, Modules, Namespaces, … for untagged symbols; or your own
-
Source Files — always last, always ungrouped (JSDoc, when
outputSourceFilesis on).
The crucial insight: a guide page's group and an API symbol's @category are the same kind of thing. Both end up as frontmatter.group, both feed the same ordering machinery. A guide and a class can sit in the same sidebar group if they share a group name.
README / index.md ──▶ Home
docs/ folder ───────▶ Doc groups ┐
source code ────────▶ API kind sections │
/ @category groups ├─▶ assembleNav ──▶ one sidebar
tutorials/ ─────────▶ Tutorials │
source files ───────▶ Source Files ┘The merge model below — API kind sections +
@categorygroups sitting alongside doc groups — is the JSDoc flavor. For TypeDoc, the API portion is instead a module/folder hierarchy (doc groups, tutorials, andmenustill merge in as described). See The TypeDoc sidebar and TypeDoc flavor.
How the two are ordered together
This is the part worth getting right. The effective top-level order is built in assembleNav:
sectionOrdercomes first, in the order you list. It's one unified list — it can name API kind labels (Classes),@categorygroup names, and doc-group names, interleaved however you like.- For kind labels,
sectionOrderis both a filter and an order — a kind label you omit is dropped from the sidebar. - Category and doc groups are never dropped by omission. Any not named in
sectionOrderare appended after the listed sections — doc groups indocGroupsorder first, then the rest alphabetically. - Home is always first and Source Files always last, regardless of
sectionOrder.
Because
sectionOrdermixes doc groups and kind labels in one list, it's the tool for true interleaving — e.g. Getting Started (a guide group), then Classes (API), then Guides (more prose), then Modules. That's exactly what this site does; see itsjsdoc.json. UsedocGroupsonly when you want to order doc groups but leave the API sections at their defaults.
Within a group
- API symbols sort by their
@order/@category … order=then alphabetically — an untagged kind section stays purely alphabetical. - Guide pages sort by their frontmatter
orderthen title. - Tutorials keep their resolved tree order.
The deeper mechanics — nested /-path groups, clubSidebarItems, leaf-vs-branch ordering — are covered in Structure your sidebar.
The home page, settled once
When you combine sources, more than one thing could be the home page. The precedence (see generateSite in index.ts):
- A docs-root
index.md(slug"",kind: 'index') — wins if present. - Otherwise the
readmeHTML.
So a docs/index.md lets you write a bespoke landing page while still using your README.md for the npm/GitHub readme.
Collisions are resolved, never fatal
All pages share one URL space, so slugs must be unique. setu claims slugs in a fixed order — API pages first, then docs, then tutorials, then source pages — and any later page whose slug is already claimed (or that would shadow the home) is skipped with a warning, never a crash. So if a guide's slug happens to collide with a generated class page, the API page wins and the guide is dropped (rename it or set a frontmatter slug). Verified in the collision handling in index.ts.
Cross-linking between the halves
Because it's one site, links just work. From a guide, link to a generated page by its slug; from a doc comment, use @link / @tutorial and setu resolves it to the right page (doc pages are keyed by slug, tutorials by name — see the resolvers in guide-view.ts).
Where to go next
- Fine-tune the merged sidebar: Structure your sidebar.
- The group/order tags on symbols: Custom tags.
- Every option in detail: Configuration.