Skip to content
Guide

Configuration

Every option accepted by defineConfig, with defaults and types.

docvia is configured with a single docvia.config.ts file at your project root. The CLI loads it (via loadConfig), the Vite plugin imports it directly, and the Next.js wrapper reads it on config evaluation.

defineConfig

defineConfig is re-exported from both @docvia/cli and @docvia/plugins. It takes a Partial<docviaConfig>, fills in defaults, and returns a fully resolved docviaConfig.

import { defineConfig } from "@docvia/cli";

export default defineConfig({
  /* ... */
});

Authoring the config through defineConfig is what gives you type-checking and editor completion on every field.

Top-level options

OptionTypeDefaultDescription
sourceDirstring"docs"Directory of Markdown source files.
outDirstring".docvia"Where the generated module graph is written.
rendererRendererAdapternoneRequired at build time. Use createReactRenderer(...) or createSvelteRenderer(...).
pluginsdocviaPlugin[][]Pipeline plugins, sorted by phase then priority.
componentsRecord<string, ComponentConfig>noneComponents referenced by :::name directives.
collectionsCollectionConfig[]one default docs collectionOne or more named source roots.
frontmatterz.ZodObjectnoneExtends the built-in frontmatter schema.
markdown.remarkPluginsunknown[][]Extra remark plugins inserted into the parse pipeline.
theme.namestring"default"UI theme name.
theme.optionsRecord<string, unknown>{}Theme-specific options.

Syntax highlighting is a plugin. Add @docvia/plugin-shiki to plugins as shiki({ theme, langs }). It highlights every code block at build time and bakes the HTML into the IR, so no highlighter ships to the browser. Highlighting is no longer a renderer option.

A syntax config block (syntax.highlighter / syntax.theme / syntax.langs) still exists in the config schema for backward compatibility, but it no longer drives highlighting. Configure the shiki() plugin instead.

Renderers

The renderer field is required for docvia build to succeed; a build with no renderer throws a CONFIG_ERROR. Choose the adapter that matches your app:

// React
import { createReactRenderer } from "@docvia/renderer-react";

renderer: createReactRenderer();
// Svelte: use the /node subpath, the build-time entry
import { createSvelteRenderer } from "@docvia/renderer-svelte/node";

renderer: createSvelteRenderer();

Syntax highlighting is no longer a renderer option. Add the shiki() plugin to plugins instead.

See @docvia/renderer-react and @docvia/renderer-svelte for the full adapter API.

Collections

By default docvia compiles a single collection named docs, rooted at sourceDir and served from /. Define collections to compile several named source roots, for example separate guides and an API reference:

collections: [
  { name: "docs", sourceDir: "src/docs", baseUrl: "/" },
  { name: "api", sourceDir: "src/api", baseUrl: "/api" },
];

Each CollectionConfig has a name, a sourceDir, and an optional baseUrl prefix. The generated source.ts exports one collection helper per entry.

Built-in frontmatter

Every Markdown file may carry a YAML frontmatter block. docvia validates it against this base schema:

FieldTypeDefaultRequired
titlestringnoneyes
descriptionstring""no
tagsstring[][]no
draftbooleanfalseno
ordernumbernoneno
slugstringderived from pathno

The base schema uses .passthrough(), so any additional keys you write are preserved and available on page.data. They are untyped unless you extend the schema.

Extending the frontmatter schema

Pass a Zod object as frontmatter to add typed fields. docvia merges it with the base schema, validates every file against the result, and generates a typed Frontmatter interface for the collection.

import { defineConfig } from "@docvia/cli";
import { z } from "zod";

export default defineConfig({
  frontmatter: z.object({
    author: z.string(),
    publishedAt: z.string().optional(),
  }),
  // ...
});

A file that omits a required custom field now fails the build with a SCHEMA_ERROR pointing at the offending file. See @docvia/schema for the validation and codegen details.

Components

Register components once under components and docvia generates the runtime registry, so you do not repeat the wiring in every route.

components: {
  counter: {
    path: "./src/lib/components/Counter.svelte",
    hydrate: true,
    defaultProps: { initial: 0 },
  },
};

Each ComponentConfig has a path, an optional hydrate flag, and optional defaultProps. A registered component is referenced from Markdown with a :::counter directive.

A complete example

import { defineConfig } from "@docvia/cli";
import { createSvelteRenderer } from "@docvia/renderer-svelte/node";
import { shiki } from "@docvia/plugin-shiki";

export default defineConfig({
  sourceDir: "src/docs",
  outDir: ".docvia",
  collections: [{ name: "docs", sourceDir: "src/docs", baseUrl: "/" }],
  renderer: createSvelteRenderer(),
  plugins: [
    shiki({ theme: "github-dark", langs: ["typescript", "svelte", "bash", "json"] }),
  ],
});