---
title: docs.json Reference
description: "Complete reference for every field in docs.json \u2014 themes, colors, navigation, tabs, OpenAPI integration, branding, SEO, analytics, and AI chat settings."
---

The `docs.json` file is the central configuration for your Jamdesk documentation site.

<Tip>
  Key settings from your docs.json are displayed in the Dashboard under
  **Project Settings → Configuration Highlights**. This view is read-only
  and updates automatically after each successful build.
</Tip>

## Required Fields

### name

**Type:** `string` (required)

Your documentation site's name. Displayed in the header and browser tab.

```json
{ "name": "Acme API Docs" }
```

### theme

**Type:** `"jam" | "nebula" | "pulsar"` (required)

<Tabs>
  <Tab title="jam">
    Clean, modern design with Inter font. Header-based navigation.

    **Best for:** Most documentation sites, API references
  </Tab>
  <Tab title="nebula">
    Airy, relaxed feel with JetBrains Mono.

    **Best for:** Narrative documentation, guides
  </Tab>
  <Tab title="pulsar">
    Sharp, high-contrast with sidebar navigation.

    **Best for:** Dense technical reference
  </Tab>
</Tabs>

### colors

**Type:** `object` (required)

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `primary` | string (hex) | Yes | Main brand color |
| `light` | string (hex) | No | Light theme accent |
| `dark` | string (hex) | No | Dark theme accent |

```json
{
  "colors": {
    "primary": "#635BFF",
    "light": "#7C75FF",
    "dark": "#4F46E5"
  }
}
```

## Branding

### favicon

**Type:** `string` or `object`

Path to your favicon file (SVG recommended). Provide a single image for both modes, or separate `light` / `dark` variants.

| Field | Type | Description |
|-------|------|-------------|
| `light` | string | Favicon for light mode (required when using the object form) |
| `dark` | string | Favicon for dark mode (optional — falls back to `light`) |

```json
{ "favicon": "/images/favicon.svg" }
```

```json
{
  "favicon": {
    "light": "/images/favicon.svg",
    "dark": "/images/favicon-dark.svg"
  }
}
```

### logo

**Type:** `object`

| Field | Type | Description |
|-------|------|-------------|
| `light` | string | Logo for light mode |
| `dark` | string | Logo for dark mode |
| `href` | string | URL when logo is clicked |

```json
{
  "logo": {
    "light": "/images/logo-light.webp",
    "dark": "/images/logo-dark.webp",
    "href": "https://yoursite.com"
  }
}
```

## Typography

### fonts

**Type:** `object` (optional)

Override the theme's default font for body text and headings. Each theme ships with a tuned default — only set `fonts` when you need a different look.

Use the same font everywhere:

```json
{
  "fonts": {
    "family": "Lora"
  }
}
```

Split heading and body:

```json
{
  "fonts": {
    "heading": { "family": "Space Grotesk" },
    "body": { "family": "Inter" }
  }
}
```

| Field | Type | Description |
|-------|------|-------------|
| `family` | string | Font family name. Any Google Font works — the build fetches it automatically |
| `weight` | number | Single weight to load (e.g. `400`). Omit to load `400, 500, 600, 700` |
| `source` | string | URL or `/`-relative path to a self-hosted font file. Skips Google Fonts |
| `format` | `"woff"` \| `"woff2"` | Required when `source` is set |

Both `heading` and `body` accept the same fields. See [Theming → Typography](/customization/theming#typography) for guidance on picking fonts.

## Appearance

### appearance

**Type:** `object` (optional)

Control the default dark-mode behavior of your site.

```json
{
  "appearance": {
    "default": "dark",
    "strict": true
  }
}
```

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `default` | `"system"` \| `"light"` \| `"dark"` | `"system"` | Initial mode for first-time visitors |
| `strict` | boolean | `false` | When `true`, hides the navbar toggle so visitors stay on `default` |

See [Theming → Dark Mode](/customization/theming#dark-mode) for how the toggle behaves.

## OpenAPI

### api.openapi

**Type:** `string | string[]`

List the OpenAPI 3.x spec files you want Jamdesk to validate and use for endpoint pages. Use paths relative to your `docs.json`.

```json docs.json
{
  "api": {
    "openapi": ["/openapi/api.yaml"]
  }
}
```

Once configured, you can generate endpoint pages by adding an `openapi` field in a page’s frontmatter:

```mdx
---
title: Create Ticket
openapi: /openapi/api.yaml POST /tickets
---
```

If you only have one spec listed, you can also use the short format:

```mdx
---
title: Create Ticket
openapi: POST /tickets
---
```

See [OpenAPI Example](/api-reference/openapi-example) for a live endpoint page and [Directory Structure](/setup/directory-structure) for file placement.

If your site is multilingual, drop a `<spec>.<lang>.<ext>` file next to each source spec (e.g., `openapi/api.fr.yaml`) and Jamdesk serves it on that language's URLs. See [Translating OpenAPI Specs](/setup/languages#translating-openapi-specs).

### api.examples.languages

**Type:** `string[]`
**Default:** `["curl", "python", "javascript"]`

Choose which programming languages appear in auto-generated API code examples on `openapi:` pages. The array order determines tab display order, and the first language is selected by default.

**Supported values:** `curl`, `bash`, `python`, `javascript`, `go`, `ruby`, `csharp`, `java`, `rust`, `php`

<Note>`bash` is an alias for `curl`; both produce the same output. Use whichever label you prefer.</Note>

```json All supported languages
{
  "api": {
    "examples": {
      "languages": ["curl", "python", "javascript", "go", "ruby", "csharp", "java", "rust", "php"]
    }
  }
}
```

```json Custom subset
{
  "api": {
    "examples": {
      "languages": ["python", "javascript", "go"]
    }
  }
}
```

### api.examples.defaults

**Type:** `"required" | "all"`
**Default:** `"all"`

Control which parameters appear in auto-generated code examples.

| Value | Behavior |
|-------|----------|
| `"all"` | Examples include all parameters with placeholder values |
| `"required"` | Examples only include parameters marked as `required` in the spec |

```json
{
  "api": {
    "examples": {
      "defaults": "required"
    }
  }
}
```

### api.examples.prefill

**Type:** `boolean`
**Default:** `false`

When `true`, the [API Playground](/api-reference/playground) pre-fills parameter fields with `example` values from your OpenAPI spec.

```json
{
  "api": {
    "examples": {
      "prefill": true
    }
  }
}
```

### api.playground.display

**Type:** `"interactive" | "simple" | "none"`
**Default:** `"interactive"`

Controls the [API Playground](/api-reference/playground) on endpoint pages. A "Try it" button appears on every `openapi:` and `api:` page by default.

| Value | Behavior |
|-------|----------|
| `"interactive"` | Full playground: fill params, generate code, send requests (default) |
| `"simple"` | Fill params and copy code, but no Send button |
| `"none"` | Playground disabled |

```json
{
  "api": {
    "playground": {
      "display": "interactive"
    }
  }
}
```

See [API Playground](/api-reference/playground) for usage details and per-page overrides.

### api.mdx.auth.method

**Type:** `"bearer" | "basic" | "key" | "cobo"`

Authentication method used in auto-generated code examples. When set, examples include the appropriate authentication header.

| Value | Header format |
|-------|--------------|
| `"bearer"` | `Authorization: Bearer <token>` |
| `"basic"` | `Authorization: Basic <base64>` |
| `"key"` | Custom header (see `api.mdx.auth.name`) |
| `"cobo"` | Cobo-specific authentication |

```json
{
  "api": {
    "mdx": {
      "auth": {
        "method": "bearer"
      }
    }
  }
}
```

### api.mdx.auth.name

**Type:** `string`

Custom header name for key-based authentication. Only used when `api.mdx.auth.method` is `"key"`.

```json
{
  "api": {
    "mdx": {
      "auth": {
        "method": "key",
        "name": "X-API-Key"
      }
    }
  }
}
```

## Navigation

### tabsPosition

**Type:** `"top" | "left"`

Controls where navigation tabs are displayed.

| Value | Description |
|-------|-------------|
| `"top"` | Tabs appear in the header tab bar |
| `"left"` | Tabs appear at the top of the sidebar |

Default value depends on your theme:

| Theme | Default |
|-------|---------|
| jam | `"left"` |
| nebula | `"left"` |
| pulsar | `"top"` |

```json
{ "tabsPosition": "left" }
```

### anchors

**Type:** `array`

External links that appear at the top of the sidebar on all pages.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Display text |
| `href` | string | Yes | URL (external link) |
| `icon` | string | No | Font Awesome icon name |

```json
{
  "anchors": [
    { "name": "Blog", "href": "https://blog.example.com", "icon": "newspaper" }
  ]
}
```

### navigation (structure)

**Type:** `object`

The navigation structure for your documentation. See [Navigation](/navigation/overview) for detailed documentation.

Pages can be strings (title auto-generated from filename) or objects with a custom title:

```json
"pages": [
  "introduction",
  { "page": "content/mdx-basics", "title": "MDX Basics" }
]
```

<Accordion title="Basic navigation example">
```json
{
  "navigation": {
    "tabs": [
      {
        "tab": "Docs",
        "icon": "book-open",
        "groups": [
          {
            "group": "Getting Started",
            "pages": ["introduction", "quickstart"]
          }
        ]
      }
    ]
  }
}
```
</Accordion>

## Navbar & Footer

### navbar

**Type:** `object`

| Field | Type | Description |
|-------|------|-------------|
| `links` | array | Navigation links |
| `links[].label` | string | Default button text |
| `links[].labels` | object | Optional per-language overrides keyed by language code (e.g. `fr`, `es`). Falls back to `label` |
| `links[].icon` | icon | Optional icon to display next to the label |
| `links[].href` | string | Destination URL |
| `primary` | object | Primary CTA button |
| `primary.label` | string | Default button text |
| `primary.labels` | object | Optional per-language overrides keyed by language code. Falls back to `label` |

```json
{
  "navbar": {
    "links": [
      {
        "label": "Blog",
        "labels": { "fr": "Blog", "es": "Blog" },
        "href": "/blog"
      },
      {
        "label": "Pricing",
        "labels": { "fr": "Tarifs", "es": "Precios" },
        "href": "/pricing"
      }
    ],
    "primary": {
      "type": "button",
      "label": "Dashboard",
      "labels": { "fr": "Tableau de bord", "es": "Panel" },
      "href": "https://app.example.com"
    }
  }
}
```

<Note>
  `labels` is optional — single-language docs can omit it. When set, the current URL language (e.g. `/fr/...`) selects the matching override.
</Note>

### footer

**Type:** `object`

Configure the page footer with social links and custom link columns.

```json
{
  "footer": {
    "socials": {
      "github": "https://github.com/yourorg",
      "x": "https://x.com/yourhandle",
      "discord": "https://discord.gg/yourserver"
    },
    "links": [
      {
        "header": "Resources",
        "items": [
          { "label": "Blog", "href": "https://example.com/blog" },
          { "label": "Changelog", "href": "/changelog" }
        ]
      }
    ]
  }
}
```

| Field | Type | Description |
|-------|------|-------------|
| `socials` | object | Social media platform URLs |
| `links` | array | Link column configurations |
| `links[].header` | string | Column heading |
| `links[].items` | array | Array of `{ label, href }` objects |

**Supported social platforms:** `github`, `x`, `twitter`, `linkedin`, `discord`, `slack`, `youtube`, `instagram`, `facebook`, `reddit`, `telegram`, `bluesky`, `threads`, `medium`, `hacker-news`, `website`

## Styling

### styling.latex

**Type:** `boolean`

Enable LaTeX math rendering with KaTeX. When enabled, you can use `$...$` for inline math and `$$...$$` for block equations.

```json
{
  "styling": {
    "latex": true
  }
}
```

See [Math & LaTeX](/content/math) for usage details.

### styling.js

**Type:** `string | string[]`

Custom JavaScript file(s) to include on every page. Paths are relative to your docs directory and must start with `/`.

```json
{
  "styling": {
    "js": "/script.js"
  }
}
```

Pass an array for multiple files:

```json
{
  "styling": {
    "js": ["/chat.js", "/analytics.js"]
  }
}
```

Without this field, Jamdesk auto-detects `.js` files in your project root. See [Custom JavaScript](/customization/custom-javascript) for details.

## Chat

### chat

**Type:** `object` (optional)

Configure the built-in AI chat assistant. Chat is enabled by default on all sites; you only need this field to customize starter questions or disable it.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `enabled` | boolean | `true` | Set `false` to remove the chat panel from your site |
| `starterQuestions` | string[] | auto-generated | Up to 4 questions shown when chat opens (5-200 chars each). Auto-generated during builds when omitted. Set to `[]` for none |

```json
{
  "chat": {
    "starterQuestions": [
      "How do I get started?",
      "What API endpoints are available?"
    ]
  }
}
```

See [AI Chat](/ai/chat) for details on how chat works and what visitors see.

## AI Actions Menu

### contextual

**Type:** `object` (optional)

Configure the AI Actions dropdown that appears on every page. Enabled by default with all options; you only need this field to customize which options appear or disable it.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `enabled` | boolean | `true` | Set `false` to remove the AI Actions menu from your site |
| `options` | array | all built-in | List of option keys and/or custom option objects |

**Built-in option keys:** `copy`, `view`, `chatgpt`, `claude`, `perplexity`, `gemini`, `mcp`, `cursor`, `vscode`

```json
{
  "contextual": {
    "options": ["copy", "claude", "mcp", "cursor"]
  }
}
```

Add custom options alongside built-in ones:

```json
{
  "contextual": {
    "options": [
      "copy",
      "claude",
      {
        "title": "Ask on Discord",
        "description": "Get help from the community",
        "icon": "discord",
        "href": "https://discord.gg/your-server"
      }
    ]
  }
}
```

See [AI Actions Menu](/ai/ai-actions) for the full list of options and custom option format.

## Spellcheck

### spellcheck

**Type:** `object` (optional)

Configure the `jamdesk spellcheck` CLI command. You only need this field to add project-specific words to the ignore list.

| Field | Type | Description |
|-------|------|-------------|
| `ignore` | string[] | Words to skip during spellcheck (product names, technical terms, etc.) |

```json
{
  "spellcheck": {
    "ignore": ["Acme", "kubectl", "Terraform"]
  }
}
```

The CLI includes 180+ built-in tech terms (API, GraphQL, Kubernetes, React, etc.) and automatically ignores your project name from the `name` field. Only add words specific to your project.

See [CLI Overview: Spellcheck](/cli/overview) for usage details and interactive fix mode.

## Images

### images.convertToWebp

**Type:** `boolean` (optional, default `false`)

Enable automatic WebP conversion for PNG and JPG assets during builds. Converted files are usually 60-80% smaller than the originals with no visible quality loss. References in your MDX, custom CSS, custom JS, and `docs.json` are rewritten automatically, so you don't change any paths.

Favicons, `og:image`, and `twitter:image` stay in their original format. Not every social crawler or email client renders WebP reliably, and a broken preview card is worse than a slightly larger JPG.

```json
{
  "images": {
    "convertToWebp": true
  }
}
```

See [Automatic Image Conversion](/builds/image-optimization) for what gets converted, how caching works, and the build progress indicator.

## Access Control

### auth.password

**Type:** `object` (optional)

Opt in to shared-password protection for your site. Declarative config only. You still set the actual passphrase in the [dashboard](/setup/password-protection#rotating-and-revoking-sessions) after the next build runs.

Set `auth.password.enabled: true` to lock the whole site, or list paths under `auth.password.private[]` to protect just those pages. Both trigger the same dashboard password prompt on the next build.

```json
{
  "auth": {
    "password": {
      "enabled": true,
      "hint": "Ask your account manager",
      "public": ["/marketing/**", "/changelog"]
    }
  }
}
```

| Field | Type | Description |
|-------|------|-------------|
| `enabled` | `boolean` | Whole-site mode. When `true`, every page needs the password (except anything marked public). |
| `hint` | `string` (max 200 chars) | Plain-text hint shown on the unlock screen. No HTML. |
| `public` | `string[]` | Path globs that bypass the password. Supports `*` (one segment) and `**` (recursive). A bare `/` is rejected. |
| `private` | `string[]` | Exact paths that require the password. Setting this without `enabled` activates specific-pages mode. |

See [Password Protection](/setup/password-protection) for the full walkthrough, including the dashboard flow and how frontmatter `public: true` / `private: true` interact with these arrays.

## Full Example

<Accordion title="Complete docs.json example" defaultOpen>
```json
{
  "$schema": "https://jamdesk.com/docs.json",
  "name": "Acme Documentation",
  "description": "Learn how to use Acme",
  "theme": "jam",
  "colors": {
    "primary": "#635BFF"
  },
  "favicon": "/images/favicon.svg",
  "logo": {
    "light": "/images/logo-light.webp",
    "dark": "/images/logo-dark.webp"
  },
  "api": {
    "openapi": ["/openapi/api.yaml"],
    "playground": {
      "display": "interactive"
    },
    "examples": {
      "languages": ["curl", "python", "javascript"],
      "prefill": true
    }
  },
  "styling": {
    "latex": true,
    "js": "/script.js"
  },
  "chat": {
    "starterQuestions": ["How do I get started?", "What endpoints are available?"]
  },
  "contextual": {
    "options": ["copy", "claude", "chatgpt", "mcp", "cursor"]
  },
  "spellcheck": {
    "ignore": ["Acme"]
  },
  "anchors": [
    { "name": "Blog", "href": "https://blog.acme.com", "icon": "newspaper" }
  ],
  "navbar": {
    "links": [
      { "label": "Support", "href": "/support" }
    ],
    "primary": {
      "type": "button",
      "label": "Dashboard",
      "href": "https://app.acme.com"
    }
  },
  "navigation": {
    "tabs": [
      {
        "tab": "Docs",
        "icon": "book-open",
        "groups": [
          {
            "group": "Get Started",
            "pages": ["introduction", "quickstart"]
          }
        ]
      },
      {
        "tab": "API Reference",
        "icon": "code",
        "groups": [
          {
            "group": "Endpoints",
            "pages": ["api/users", "api/posts"]
          }
        ]
      }
    ]
  }
}
```
</Accordion>

## What's Next?

<Columns cols={2}>
  <Card title="Navigation Overview" icon="sitemap" href="/navigation/overview">
    Structure your docs navigation
  </Card>
  <Card title="AI Actions Menu" icon="wand-magic-sparkles" href="/ai/ai-actions">
    Customize the AI dropdown on every page
  </Card>
</Columns>
