npm package: @karaoke-cms/module-docs
Description: Docs module for karaoke-cms — documentation pages with sidebar navigation
Latest version: 0.20.10

# @karaoke-cms/module-docs

Docs module for karaoke-cms — documentation pages with a left-sidebar navigation showing all published docs in alphabetical order.

## Installation

```bash
npm install @karaoke-cms/module-docs
```

## Usage

Single section:

```ts
// karaoke.config.ts
import { defineConfig } from '@karaoke-cms/astro';
import { loadEnv } from '@karaoke-cms/astro/env';
import { blog } from '@karaoke-cms/module-blog';
import { docs } from '@karaoke-cms/module-docs';
import { themeDefault } from '@karaoke-cms/theme-default';

const env = loadEnv(new URL('.', import.meta.url));

export default defineConfig({
  vault: env.KARAOKE_VAULT,
  theme: themeDefault(),
  modules: [blog({ mount: '/blog' }), docs({ mount: '/docs' })],
});
```

Multiple sections (array form):

```ts
export default defineConfig({
  vault: env.KARAOKE_VAULT,
  theme: themeDefault(),
  modules: [
    blog({ mount: '/blog' }),
    docs([
      { id: 'docs',     mount: '/docs',     label: 'Docs',          weight: 20 },
      { id: 'api-docs', mount: '/api-docs', folder: 'api-reference', label: 'API Reference', weight: 25, parent: 'docs' },
    ]),
  ],
});
```

## Configuration

### Single-form options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `mount` | `string` | `'/docs'` | URL prefix for all docs routes |
| `folder` | `string` | mount path without leading `/` | Vault subfolder to read docs from |
| `id` | `string` | folder with `/` replaced by `-` | Astro collection name |
| `label` | `string` | id in Title Case | Display label in nav and page titles |
| `enabled` | `boolean` | `true` | Set `false` to disable the module entirely |
| `comments` | `boolean` | `false` | Default comments state for all docs pages. Per-page frontmatter overrides this. |

### Array-form options (`DocsSection`)

Each object in `docs([...])` accepts the same fields as the single-form plus:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `weight` | `number` | `20` | Menu ordering weight (Blog = 10, Tags = 30) |
| `parent` | `string` | — | Id of a root nav entry to nest this section under as a submenu |

## Routes

All routes are relative to `mount`:

| Pattern | Description |
|---------|-------------|
| `{mount}` | Docs home — lists all published doc titles |
| `{mount}/list` | Standalone full-list view |
| `{mount}/[...slug]` | Individual doc page with left-sidebar navigation |

## Frontmatter

```yaml
---
title: "Getting Started"              # required
publish: true                         # required to appear on site
date: 2026-01-15                      # optional — YYYY-MM-DD
author: "Name"                        # optional — string or array
featured_image: "img/hero.jpg"        # optional — relative path, absolute path, URL,
                                      #   or Obsidian wiki link: "[[hero.jpg]]"
description: "..."                    # optional — OG tags, AI-enriched
tags: [setup, guide]                  # optional — AI-enriched
reading_time: 3                       # optional — AI-enriched, minutes
related: [slug-a, slug-b]             # optional — AI-enriched, slugs
comments: false                       # optional — per-doc Giscus override (off by default)
---
```

### `featured_image` formats

All of the following work in `featured_image`:

```yaml
featured_image: "./images/hero.jpg"          # relative to the note
featured_image: "/docs/hero.jpg"             # vault-absolute path
featured_image: "https://example.com/x.jpg"  # remote URL
featured_image: "[[hero.jpg]]"               # Obsidian wiki link — resolved via vault lookup
```

When using a wiki link, the image is served from `/media/` during dev and copied to `dist/media/` at build.

## What's new in 0.18.2

- **Variant-aware layouts** -- the docs module now declares three page variants (`root`, `list`, `doc`) with default layouts. All three render `body` in the `main` region. Themes and users can override these per-variant layouts in `layout.config.ts` or `karaoke.config.ts`.
- **Dead page files removed** -- the static `.astro` page files previously shipped in the module package have been deleted. All docs routes are now fully handled by the codegen system (`generateDocsInstancePages`), which writes per-instance pages to `.astro/generated/`. This eliminates the possibility of stale entrypoints and ensures each docs section gets unique generated files.

## What's new in 0.18.0

- **Subdirectory page routing** — route pattern changed from `[slug]` to `[...slug]`, so pages inside nested vault folders now resolve correctly (e.g. `docs/guides/setup` renders at `{mount}/guides/setup`).
- **Section switcher on home and list pages** — the docs section switcher is now visible on the home and list pages, not just individual doc pages.
- **Sidebar hides `index.md`** — `index.md` files no longer appear as separate items in the sidebar tree; their content is hoisted to the parent directory node instead.

## What's new in 0.17.0

- **`comments` option** — `docs({ comments: true })` enables Giscus comments by default on all pages in this section. Defaults to `false`. Individual pages can override with `comments: true` or `comments: false` in frontmatter.
- **Array-form `docs([...])`** — pass a `DocsSection[]` array to create multiple independent docs sections in one call. Each section gets its own collection, routes, and menu entry. Sections with `enabled: false` are skipped.
- **`weight` in array-form** — control where each docs section appears in the nav (Blog = 10, Tags = 30; use 11–29 for docs sections between them).
- **`parent` in array-form** — nest a docs section as a submenu under a root nav entry by setting `parent: '<id>'`.

## What's new in 0.10.3

- **Warning for `mount: '/'`** — calling `docs({ mount: '/' })` without an explicit `folder` now prints a warning, because the folder silently defaults to `"docs"` in this case. Pass `folder` explicitly to suppress it: `docs({ mount: '/', folder: 'docs' })`.

## What's new in 0.10.2

- **Multiple named docs sections** — call `docs()` multiple times with different `mount`, `folder`, and `label` values to create independent docs areas from separate vault folders.
- **`folder` option** — map a docs instance to any vault subfolder (defaults to the mount path without the leading slash).
- **`id` option** — override the Astro collection name (defaults to folder path, slashes replaced with hyphens).
- **`label` option** — set a human-readable section title shown in navigation and page headings (defaults to id in Title Case).
- **Section switcher** — when two or more sections are active, a nav row appears above the sidebar so readers can jump between sections.
- **Auto-registered collections** — pass your full karaoke config to `makeCollections({ config })` in `content.config.ts` and every docs instance registers automatically. No manual changes needed when adding a second section.

## What's new in 0.10.0

- **`[[wiki link]]` in `featured_image`** — `featured_image: "[[hero.jpg]]"` now works on doc pages; images are resolved via vault path lookup and served from `/media/`

## What's new in 0.9.5

- **`featured_image` support** added to the docs schema
- **`enabled` flag** — `docs({ mount: '/docs', enabled: false })` disables the module without removing it from config
- Fixed workspace symlink registration — `@karaoke-cms/module-docs` is now correctly wired in the website app