<!--
Sitemap:
- [What is Vocs](/introduction/what-is-vocs): Learn why Vocs exists and when to use it
- [Getting Started](/introduction/getting-started): Install Vocs and create your first documentation site
- [Project Structure](/introduction/project-structure): Overview of the structure of a Vocs project
- [Writing Docs with AI](/introduction/writing-docs-with-ai): Use an AI agent to create and maintain Vocs documentation
- [Markdown Extensions](/writing/markdown-extensions): Features and syntax of Markdown in Vocs
- [Code & Syntax Highlighting](/writing/syntax-highlighting): Rich markup and annotations for code
- [Twoslash](/writing/twoslash): Add type-aware annotations to code examples
- [Code Snippets](/writing/code-snippets): Include and reuse code in Markdown
- [Markdown Snippets](/writing/markdown-snippets): Include other Markdown files in MDX
- [React in Markdown](/writing/react): Compose MDX pages with React components
- [Mermaid Diagrams](/writing/mermaid): Render diagrams from text using Mermaid
- [Assets](/writing/assets): Manage images, fonts, icons, and other docs assets
- [Frontmatter](/writing/frontmatter): Configure page metadata, layouts, search, and UI visibility
- [Agent Support](/features/agent-support): Serve documentation in machine-readable form for AI agents
- [API Routes](/features/api-routes): Add server-rendered endpoints to your docs site
- [Ask AI](/features/ask-ai): Built-in AI assistant menu on every page
- [Changelog Generation](/features/changelog-generation): Fetch release notes and render a changelog page
- [Dynamic OG Images](/features/dynamic-og-images): Generate social preview images from page metadata
- [Layouts](/features/layouts): Choose and customize page shells for your docs
- [MCP Server](/features/mcp-server): Expose your docs and source code to AI assistants
- [Navigation](/features/navigation): Keep docs navigation synced with routes
- [Page Feedback](/features/feedback): Collect page-level feedback from readers
- [Redirects](/features/redirects): Preserve old URLs and route legacy paths to new locations
- [Rehype & Remark](/features/rehype-and-remark): Customize the Markdown and HTML pipeline
- [Search](/features/search): Built-in client-side search powered by MiniSearch
- [Slots](/features/slots): Inject custom components into the docs shell
- [SSG or SSR](/features/render-strategies): Choose a render strategy for your docs site
- [Tailwind CSS](/features/tailwind): Use Tailwind utilities in Vocs pages and components
- [Theming](/features/theming): Customize colors, typography, spacing, logos, and code themes
- [Vite](/features/vite): Customize the Vite config that powers Vocs
- [Vercel](/deployment/vercel): Deploy your Vocs site to Vercel
- [Netlify](/deployment/netlify): Deploy your Vocs site to Netlify
- [Node.js](/deployment/node): Self-host your Vocs site on Node.js
- [Site Configuration](/reference/site-config): Reference for options accepted by defineConfig
- [Frontmatter Reference](/reference/frontmatter): All frontmatter fields accepted by a Vocs MDX page
- [Components](/reference/components): Reference for the public React components exported from Vocs
- [Hooks](/reference/hooks): Reference for the React hooks exported from Vocs
- [Changelog](/changelog): Release history for Vocs
-->

# Site Configuration \[Reference for options accepted by defineConfig]

Reference for the options accepted by `defineConfig()` in your Vocs config file.

Vocs looks for a config file at your project root using one of these names:

* `vocs.config.ts`
* `vocs.config.js`
* `vocs.config.mjs`
* `vocs.config.mts`

## Basic Usage

```ts [vocs.config.ts]
import { defineConfig } from 'vocs/config'

export default defineConfig({
  title: 'Acme Docs',
  description: 'Documentation for Acme'
})
```

## Configure With AI

When asking an AI agent to update Vocs configuration, point it at this reference and name the outcome you want.

```txt
Read https://vocs.dev/reference/site-config and update vocs.config.ts for this project.

Preserve the existing config, add only the options needed, and run the docs build when you are done.
```

For a config-only change, give the agent the exact behavior and any production URLs or service names it needs:

```txt
Update vocs.config.ts so this docs site uses https://docs.acme.dev as its canonical URL, shows the Acme light and dark logos from public/, enables the MCP server, and exposes the acme/sdk GitHub repository as a source.
```

## Metadata

### `title`

* **Type:** `string`
* **Default:** `'Docs'`

The site title. Vocs uses it in navigation UI and as the base for the document title.

```ts
export default defineConfig({
  title: 'Acme Docs'
})
```

### `description`

* **Type:** `string`

General site description used for metadata and SEO.

```ts
export default defineConfig({
  description: 'Documentation for the Acme SDK'
})
```

### `titleTemplate`

* **Type:** `string`
* **Default:** `%s – ${title}`

Template used to build each page's `<title>`. Use `%s` as a placeholder for the page title.

```ts
export default defineConfig({
  title: 'Acme Docs',
  titleTemplate: '%s · Acme Docs'
})
```

## URLs And Deployment

### `basePath`

* **Type:** `string`
* **Default:** `'/'`

The subpath your docs site is deployed under. Use this when your site is not served from the domain root.

```ts
export default defineConfig({
  basePath: '/docs'
})
```

If your production URL is `https://example.com/docs`, set `basePath` to `'/docs'`.

### `baseUrl`

* **Type:** `string`

The canonical base URL for your docs site. Vocs uses this to populate the page `<base>` tag and to resolve the `%logo` variable in `ogImageUrl` templates.

```ts
export default defineConfig({
  baseUrl: 'https://docs.acme.dev'
})
```

If you omit the protocol, Vocs normalizes it to `https://`.

### `redirects`

* **Type:** `Array<{ source: string; destination: string; status?: 301 | 302 | 307 | 308 }>`

Redirect incoming paths to new destinations. Redirects support named parameters such as `:slug` and wildcards such as `:path*`.

```ts
export default defineConfig({
  redirects: [
    { source: '/docs', destination: '/introduction/getting-started' },
    { source: '/old/:path*', destination: '/new/:path*', status: 301 }
  ]
})
```

If you omit `status`, Vocs uses `307`.

:::tip
See [Redirects](/features/redirects) for the full guide.
:::

### `renderStrategy`

* **Type:** `'full-static' | 'partial-static' | 'dynamic'`
* **Default:** `'dynamic'`

Controls how Vocs renders the site.

* `full-static` generates a fully static site.
* `partial-static` statically generates pages while leaving other routes dynamic.
* `dynamic` renders routes dynamically.

```ts
export default defineConfig({
  renderStrategy: 'full-static'
})
```

:::tip
See [Render Strategies](/features/render-strategies) for trade-offs and use cases.
:::

### `checkDeadlinks`

* **Type:** `boolean | 'warn'`
* **Default:** `true`

Controls dead link validation.

* `true` throws on dead links.
* `false` disables checking.
* `'warn'` reports dead links without failing the build.

```ts
export default defineConfig({
  checkDeadlinks: 'warn'
})
```

## Branding And Theme

### `logoUrl`

* **Type:** `string | { light: string; dark: string }`

Logo displayed in the site navigation.

```ts
export default defineConfig({
  logoUrl: {
    light: '/logo-light.svg',
    dark: '/logo-dark.svg'
  }
})
```

:::tip
See [Theming](/features/theming) for branding, colors, and theme tokens.
:::

### `iconUrl`

* **Type:** `string | { light: string; dark: string }`

Icon used for site metadata such as the favicon.

```ts
export default defineConfig({
  iconUrl: '/icon.svg'
})
```

### `accentColor`

* **Type:** `string`
* **Default:** `'light-dark(black, white)'`

Accent color used throughout the UI. You can pass any CSS color value, including `light-dark()` for different light and dark theme values.

```ts
export default defineConfig({
  accentColor: 'light-dark(#2563eb, #60a5fa)'
})
```

:::tip
See [Theming](/features/theming) for the accent token and dark-mode pairing.
:::

### `colorScheme`

* **Type:** `'light' | 'dark' | 'light dark'`
* **Default:** `'light dark'`

Controls whether your site is locked to light mode, locked to dark mode, or follows the user's system preference.

```ts
export default defineConfig({
  colorScheme: 'dark'
})
```

:::tip
See [Theming](/features/theming) for theme toggle behavior.
:::

### `banner`

* **Type:**

```ts
type Banner =
  | string
  | {
      /** Markdown content rendered inside the banner. */
      content: string
      /** CSS color for the banner background. Overrides the variant default. */
      backgroundColor?: string
      /** Show a dismiss button. Defaults to `true`. */
      dismissable?: boolean
      /** Stable id used to remember dismissal in localStorage. Change to re-show. */
      dismissId?: string
      /** CSS height of the banner (e.g. `'40px'`). */
      height?: string
      /** Wrap the banner content in a link. */
      href?: string
      /** CSS color for the banner text. Overrides the variant default. */
      textColor?: string
      /** Visual style preset. Defaults to `'info'`. */
      variant?: 'note' | 'info' | 'warning' | 'danger' | 'tip' | 'success'
    }
```

Displays a banner fixed to the top of the page. A string value is treated as the banner's Markdown content.

When you pass an object, `dismissable` defaults to `true` and `variant` defaults to `'info'`.

```ts
export default defineConfig({
  banner: {
    content: 'Vocs v2 is now available.',
    href: '/changelog',
    variant: 'tip'
  }
})
```

## Navigation

### `sidebar`

* **Type:**

```ts
type Sidebar =
  | SidebarItem[]
  | {
      /**
       * Path-scoped sidebars. Vocs picks the deepest matching prefix for the
       * current route.
       */
      [path: string]:
        | SidebarItem[]
        | {
            /** Show a "Back" link at the top of the scoped sidebar section. */
            backLink?: boolean
            /** Items shown under this path scope. */
            items: SidebarItem[]
          }
    }
```

Configures sidebar navigation. Use the array form when the whole site shares one sidebar. Use the object form when different route sections need different sidebars.

Each sidebar item supports these fields:

```ts
type SidebarItem = {
  /** Display text for the item. */
  text?: string
  /** Destination URL (absolute or root-relative). */
  link?: string
  /** Nested items rendered as a collapsible group. */
  items?: SidebarItem[]
  /** Start the group collapsed. Has no effect on leaf items. */
  collapsed?: boolean
  /** Render the item as non-interactive (greyed out, no link). */
  disabled?: boolean
  /** Mark the link as external (opens in a new tab with an icon). */
  external?: boolean
}
```

```ts
export default defineConfig({
  sidebar: [
    { text: 'Getting Started', link: '/introduction/getting-started' },
    {
      text: 'Writing',
      collapsed: false,
      items: [
        { text: 'Code & Syntax Highlighting', link: '/writing/syntax-highlighting' },
        { text: 'Code Snippets', link: '/writing/code-snippets' },
        { text: 'Markdown Snippets', link: '/writing/markdown-snippets' },
        { text: 'Markdown Extensions', link: '/writing/markdown-extensions' },
        { text: 'Twoslash', link: '/writing/twoslash' }
      ]
    }
  ]
})
```

```ts
export default defineConfig({
  sidebar: {
    '/guide': [
      { text: 'Getting Started', link: '/introduction/getting-started' },
      { text: 'Theming', link: '/features/theming' }
    ],
    '/reference': {
      backLink: true,
      items: [
        { text: 'Site Configuration', link: '/reference/site-config' },
        { text: 'Components', link: '/reference/components' }
      ]
    }
  }
})
```

When you use the object form, Vocs picks the deepest matching path prefix for the current route.

:::tip
See [Navigation](/features/navigation) for sidebar scoping, back links, and collapsing recipes.
:::

### `topNav`

* **Type:**

```ts
type TopNav = TopNavItem[]

type TopNavItem = {
  /** Display text for the item. */
  text: string
  /** Mark the link as external (opens in a new tab with an icon). */
  external?: boolean
  /**
   * Controls the item's active state. Either a path prefix string or a
   * function that returns `true` for paths the item should match. Use when
   * the active state should be driven by a broader prefix than the item's
   * own `link`.
   */
  match?: string | ((path: string | undefined) => boolean)
} & (
  | {
      /** Destination URL (absolute or root-relative). */
      link: string
    }
  | {
      /** Dropdown menu items shown when the user hovers the top nav entry. */
      items: Array<{
        /** Display text for the menu item. */
        text: string
        /** Destination URL (absolute or root-relative). */
        link: string
        /** Mark the link as external. */
        external?: boolean
        /** Path-prefix string or matcher function for active state. */
        match?: string | ((path: string | undefined) => boolean)
      }>
    }
)
```

Configures the top navigation bar. Each item is either a direct link or a dropdown with nested items.

```ts
export default defineConfig({
  topNav: [
    {
      text: 'Guide',
      link: '/introduction/getting-started',
      match: '/guide'
    },
    {
      text: 'Resources',
      items: [
        { text: 'API', link: '/reference/site-config' },
        { text: 'GitHub', link: 'https://github.com/acme/docs', external: true }
      ]
    }
  ]
})
```

Use `match` when the active state should be driven by a broader route prefix than the item's own `link`.

:::tip
See [Navigation](/features/navigation) for top nav match logic and external links.
:::

### `socials`

* **Type:** `Array<{ icon: 'bluesky' | 'discord' | 'farcaster' | 'github' | 'telegram' | 'x'; link: string }>`

Social links displayed in the sidebar footer.

```ts
export default defineConfig({
  socials: [
    { icon: 'github', link: 'https://github.com/wevm/vocs' },
    { icon: 'x', link: 'https://x.com/wevm_dev' },
    { icon: 'discord', link: 'https://discord.gg/JUrRkGweXV' }
  ]
})
```

### `editLink`

* **Type:**

```ts
type EditLink = {
  /**
   * URL template or function. In string templates, `:path` is replaced with
   * the page's file path (relative to the project root).
   */
  link: string | ((filePath: string) => string)
  /** Link label. Defaults to `'Suggest changes to this page'`. */
  text?: string
}
```

Adds a "Suggest changes to this page" link to the page footer.

```ts
export default defineConfig({
  editLink: {
    link: 'https://github.com/acme/docs/edit/main/src/pages/:path'
  }
})
```

## Content Pipeline

### `markdown`

* **Type:** `@mdx-js/rollup` options

Extends the underlying MDX compilation pipeline. Use this when you need to add custom remark, rehype, or recma plugins.

```ts
import rehypeExternalLinks from 'rehype-external-links'

export default defineConfig({
  markdown: {
    rehypePlugins: [[rehypeExternalLinks, { target: '_blank' }]]
  }
})
```

Vocs already includes its own MDX plugins for features such as callouts, code groups, frontmatter handling, and syntax highlighting, so `markdown` is usually only needed for custom behavior.

:::tip
See [Rehype & Remark Plugins](/features/rehype-and-remark) for examples of adding custom MDX plugins.
:::

### `codeHighlight`

* **Type:** Vocs' Shiki configuration

Configures syntax highlighting for fenced code blocks. This is the main place to customize Shiki themes, languages, aliases, and transformers.

Useful fields include:

```ts
{
  themes?: { light: string; dark: string }
  langs?: string[]
  langAlias?: Record<string, string>
  transformers?: unknown[]
}
```

By default, Vocs uses `github-light` for light mode and `github-dark-dimmed` for dark mode, and automatically adds a `sol -> solidity` language alias.

```ts
export default defineConfig({
  codeHighlight: {
    themes: {
      light: 'github-light',
      dark: 'tokyo-night'
    },
    langAlias: {
      shell: 'bash'
    }
  }
})
```

:::tip
See [Code & Syntax Highlighting](/writing/syntax-highlighting) for themes, transformers, and language aliases.
:::

### `twoslash`

* **Type:** `false | Twoslash config`

Configures [Twoslash](/writing/twoslash) for type-aware code examples. Set it to `false` to disable Twoslash entirely.

```ts
import { Twoslash, defineConfig } from 'vocs/config'

export default defineConfig({
  twoslash: {
    transformers: [Twoslash.experimental_rust({ cargoToml: './Cargo.toml' })]
  }
})
```

:::tip
See [Twoslash](/writing/twoslash) for type-aware code examples and the Rust transformer.
:::

### `groupIcons`

* **Type:** `{ customIcons?: Record<string, string> }`

Adds custom icon mappings for code block labels in code groups.

```ts
export default defineConfig({
  groupIcons: {
    customIcons: {
      '.mdx': 'vscode-icons:file-type-mdx',
      'bun.lock': 'vscode-icons:file-type-bun'
    }
  }
})
```

:::tip
See [Code & Syntax Highlighting](/writing/syntax-highlighting) for code group icon usage.
:::

### `search`

* **Type:**

```ts
type Search = {
  /**
   * Per-field weight multipliers applied during scoring. Higher values rank
   * matches in that field higher.
   *
   * Defaults to `{ title: 4, subtitle: 3, text: 2, category: 1, titles: 1 }`.
   */
  boost?: Record<string, number>
  /**
   * Per-document boost function. Return a multiplier to amplify or suppress
   * results from specific pages (pair with the page-level `searchPriority`
   * frontmatter field).
   */
  boostDocument?: (
    id: string,
    term: string,
    storedFields?: Record<string, unknown>,
  ) => number
  /**
   * How multi-term queries are combined. `'AND'` requires every term to
   * match, `'OR'` matches any. Defaults to `'AND'`.
   */
  combineWith?: 'AND' | 'OR'
  /**
   * Fuzzy matching tolerance. A number between `0` and `1` is the fraction
   * of edit distance allowed; `true` is `0.2`; `false` disables fuzziness.
   * Defaults to `0.2`.
   */
  fuzzy?: number | boolean
  /**
   * Match queries against the start of indexed terms (so typing "comp"
   * matches "component"). Defaults to `true`.
   */
  prefix?: boolean
}
```

Customizes built-in documentation search.

```ts
export default defineConfig({
  search: {
    combineWith: 'OR',
    fuzzy: 0.1,
    boost: {
      title: 6,
      text: 1
    }
  }
})
```

:::tip
See [Search](/features/search) for recipes covering fuzzy matching, prefix matching, and field weighting.
:::

## Integrations

### `feedback`

* **Type:** `Feedback.Adapter`

Enables the built-in feedback widget by providing a feedback adapter.

```ts
import { Feedback, defineConfig } from 'vocs/config'

export default defineConfig({
  feedback: Feedback.slack()
})
```

You can provide your own adapter with `Feedback.from()`.

:::tip
See [Feedback](/features/feedback) for adapter setup and custom integrations.
:::

### `mcp`

* **Type:**

```ts
{
  enabled?: boolean
  sources?: readonly McpSource.Adapter[]
}
```

Configures Vocs' built-in MCP server. When enabled, Vocs serves the endpoint at `/api/mcp`.

```ts
import { McpSource, defineConfig } from 'vocs/config'

export default defineConfig({
  mcp: {
    enabled: true,
    sources: [McpSource.github({ repo: 'wevm/vocs', paths: ['src', 'site'] })]
  }
})
```

Use `McpSource.github()` for GitHub-backed repositories or `McpSource.from()` for custom sources.

:::tip
See [MCP Server](/features/mcp-server) for the full guide on exposing docs and sources to AI clients.
:::

### `changelog`

* **Type:** `Changelog.Adapter`

Configures the source used for changelog data.

```ts
import { Changelog, defineConfig } from 'vocs/config'

export default defineConfig({
  changelog: Changelog.github({ repo: 'wevm/vocs' })
})
```

Use `Changelog.github()` to read GitHub releases or `Changelog.from()` to provide your own adapter.

:::tip
See [Changelog Generation](/features/changelog-generation) for the full guide.
:::

### `ogImageUrl`

* **Type:** `string | ((path: string, context: { baseUrl?: string }) => string)`

Configures the Open Graph image URL used for page metadata.

String templates can use these placeholders:

* `%logo`
* `%title`
* `%description`

```ts
export default defineConfig({
  ogImageUrl: '/api/og?logo=%logo&title=%title&description=%description'
})
```

You can also compute the URL dynamically:

```ts
export default defineConfig({
  ogImageUrl: (path, { baseUrl }) => {
    return `${baseUrl ?? ''}/api/og?title=%title&path=${path}`
  }
})
```

:::tip
See [Dynamic OG Images](/features/dynamic-og-images) for the full guide on rendering OG previews.
:::

## Filesystem And Output

### `rootDir`

* **Type:** `string`
* **Default:** `process.cwd()`

Root directory used to resolve the rest of the config's filesystem paths.

```ts
export default defineConfig({
  rootDir: './packages/docs'
})
```

:::tip
See [Project Structure](/introduction/project-structure) for how Vocs resolves filesystem paths.
:::

### `srcDir`

* **Type:** `string`
* **Default:** `'src'`

Source directory relative to `rootDir`. Vocs reads your pages from `srcDir/pages`.

```ts
export default defineConfig({
  srcDir: 'docs'
})
```

With this config, Vocs will look for pages in `docs/pages`.

:::tip
See [Project Structure](/introduction/project-structure) for the conventional layout of a Vocs project.
:::

### `cacheDir`

* **Type:** `string`
* **Default:** `'.vocs/cache'`

Directory used for cached build artifacts, resolved relative to `rootDir`.

```ts
export default defineConfig({
  cacheDir: '.cache/vocs'
})
```

### `outDir`

* **Type:** `string`
* **Default:** `'dist'`

Output directory for the built site, relative to `rootDir`.

```ts
export default defineConfig({
  outDir: 'build'
})
```
