Modules Reference
All modules are passed to defineConfig({ modules: [...] }) in karaoke.config.ts. The karaoke() integration flattens nested arrays, so docs([...]) (which returns ModuleInstance[]) can be passed directly.
blog
Package: @karaoke-cms/module-blog
import { blog } from '@karaoke-cms/module-blog';
Signature
function blog(config?: {
mount?: string;
id?: string;
enabled?: boolean;
comments?: boolean;
}): ModuleInstance
Options
| Name | Type | Default | Description |
|---|---|---|---|
mount | string | '' (root) | URL prefix for all blog routes. |
id | string | 'blog' | Module identifier. |
enabled | boolean | true | When false, routes and menu entries are skipped. |
comments | boolean | true | Default comments state for all posts. Per-post frontmatter overrides this. |
Routes injected
| Pattern | Entrypoint |
|---|---|
{mount} | @karaoke-cms/module-blog/pages/list |
{mount}/[slug] | @karaoke-cms/module-blog/pages/post |
{mount}/page/[page] | @karaoke-cms/module-blog/pages/page |
Menu entries registered
| Menu section | Text | Path | Weight |
|---|---|---|---|
main | Blog | {mount} or / | 10 |
footer | RSS | /rss.xml | 10 |
docs
Package: @karaoke-cms/module-docs
import { docs } from '@karaoke-cms/module-docs';
Signature (overloaded)
// Single section — returns one ModuleInstance
function docs(config?: DocsConfig): ModuleInstance
// Multiple sections — returns one ModuleInstance per active section
function docs(sections: DocsSection[]): ModuleInstance[]
DocsConfig options (single form)
| Name | Type | Default | Description |
|---|---|---|---|
mount | string | '/docs' | URL prefix for this docs section. |
folder | string | mount without / | Vault subfolder containing markdown files. |
id | string | folder with / → - | Astro collection name. Must be unique. |
label | string | id in Title Case | Nav label and page heading. |
enabled | boolean | true | When false, excluded from build. |
comments | boolean | false | Default comments state for pages in this section. |
layout | string | 'default' | Layout component override. |
sidebarStyle | string | 'tree' | Sidebar style. Values: 'flat', 'grouped'. |
DocsSection fields (array form)
Extends DocsConfig with:
| Name | Type | Default | Description |
|---|---|---|---|
weight | number | 20 | Menu weight. Blog = 10, Tags = 30. Use 11–29 to appear between them. |
parent | string | — | Id of a root-level nav entry to nest under. Single-level only. Falls back to root with a warning if not found. |
Sections with enabled: false are excluded from the returned array.
Routes injected (per instance, via codegen)
Routes are code-generated into .astro/generated/karaoke-cms/{id}/ at build time. Each instance gets:
| Pattern | Description |
|---|---|
{mount} | Docs home — list of all doc titles |
{mount}/list | Full docs list |
{mount}/[slug] | Individual doc with sidebar |
Menu entries registered
| Menu section | Text | Path | Weight |
|---|---|---|---|
main | {label} | {mount} | weight (default 20) |
Multiple sections example
modules: [
docs([
{ id: 'docs', mount: '/docs', label: 'Docs', weight: 20 },
{ id: 'api', mount: '/api-docs', folder: 'api-reference', label: 'API Reference', weight: 25, parent: 'docs' },
]),
]
tags
Package: @karaoke-cms/module-tags
import { tags } from '@karaoke-cms/module-tags';
Signature
function tags(config?: {
mount?: string;
enabled?: boolean;
}): ModuleInstance
Options
| Name | Type | Default | Description |
|---|---|---|---|
mount | string | '/tags' | URL prefix for tags routes. Cannot be '/' or empty. |
enabled | boolean | true | When false, routes are not injected. |
Routes injected
| Pattern | Entrypoint |
|---|---|
{mount} | @karaoke-cms/module-tags/pages/index |
{mount}/[tag] | @karaoke-cms/module-tags/pages/tag |
{mount}/[tag]/rss.xml | @karaoke-cms/module-tags/pages/tag-rss |
Menu entries registered
| Menu section | Text | Path | Weight |
|---|---|---|---|
main | Tags | {mount} | 30 |
Notes
Aggregates tags from the blog collection and all active docs sections automatically. No explicit sources config needed.
search
Package: @karaoke-cms/module-search
import { search } from '@karaoke-cms/module-search';
Signature
const search: (config?: {
mount?: string;
enabled?: boolean;
}) => ModuleInstance
search is a module instance factory produced by defineModule(). Call it like a function.
Options
| Name | Type | Default | Description |
|---|---|---|---|
mount | string | '/search' | URL for the search page. |
enabled | boolean | true | When false, routes are not injected. |
Routes injected
| Pattern | Entrypoint |
|---|---|
{mount} | @karaoke-cms/module-search/pages/search |
Menu entries registered
| Menu section | Text | Path | Weight |
|---|---|---|---|
main | Search | {mount} | 90 |
Build behavior
- Production: Runs
npx pagefind --site dist/afterastro:build:doneto generate the full-text search index. - Dev mode: Serves the pre-built index from
dist/pagefind/at/pagefind/. Runpnpm buildonce first to generate the index; after that, search works in dev without a rebuild.
comments
Package: @karaoke-cms/module-comments
import { comments } from '@karaoke-cms/module-comments';
Signature
function comments(config: {
repo: string;
repoId: string;
category?: string;
categoryId?: string;
enabled?: boolean;
}): ModuleInstance
Options
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
repo | string | Yes | — | GitHub repo in "owner/repo" format. Must have Discussions enabled. |
repoId | string | Yes | — | GitHub repo node ID. Get from giscus.app. |
category | string | No | 'General' | GitHub Discussions category name. |
categoryId | string | No | '' | GitHub Discussions category node ID. Get from giscus.app. |
enabled | boolean | No | true | When false, module is excluded from the build. |
Routes injected
None. The Giscus widget is embedded by the theme on post and doc pages.
Menu entries registered
None.
Notes
Whether comments appear on a specific page is controlled by:
blog({ comments: true/false })ordocs({ comments: true/false })— module-level defaultcomments: true/falsein page frontmatter — per-page override
seo
Package: @karaoke-cms/module-seo
import { seo } from '@karaoke-cms/module-seo';
Signature
function seo(config?: {
disallow?: string[];
llmsTxt?: boolean;
llmsSiteTitle?: string;
llmsTxtExtra?: string;
contentManifest?: boolean;
}): ModuleInstance
Options
| Name | Type | Default | Description |
|---|---|---|---|
disallow | string[] | ['/karaoke-cms/'] | URL path prefixes to block in robots.txt. |
llmsTxt | boolean | true (when site is set) | When false, skip /llms.txt. |
llmsSiteTitle | string | hostname | # title in llms.txt. |
llmsTxtExtra | string | — | Extra Markdown appended to llms.txt. |
contentManifest | boolean | true (when site is set) | When false, skip karaoke-public-content.json. |
Routes injected
None.
Menu entries registered
None.
Build behavior
Runs after astro:build:done:
- Generates OG social card images for all published blog posts and docs pages.
- Ensures
<link rel="canonical" href="{og:url}">on every built HTML page that hasog:urland no existing canonical link. - Writes
robots.txtwith the configureddisallowpaths and aSitemap:line whensiteis set and a sitemap XML exists indist/. - Writes
llms.txtwhensiteis set andllmsTxtis notfalse. - Writes
karaoke-public-content.jsonwhensiteis set andcontentManifestis notfalse. - Injects JSON-LD structured data into pages.