URL: /guides/customization/configuration

---
title: Configuration
description: Configure your project via docs.json.
icon: "settings"
---

# Configuration

Tangly reads a single `docs.json` at your project root. The full reference is at [`docs.json`](/reference/schema/docs-json) — this guide covers the shape and the fields you'll touch most.

## Minimal example

```json
{
  "$schema": "./node_modules/tangly/schema/docs.json",
  "name": "My Docs",
  "theme": "tang",
  "colors": { "primary": "#0ea5e9" },
  "navigation": {
    "groups": [{ "group": "Get Started", "pages": ["introduction"] }]
  }
}
```

That's enough to render. Add fields as you need them.

## Common fields

<ParamField path="name" type="string" required>
  Display name. Shown in the title bar, sitemap, and `llms.txt`.
</ParamField>

<ParamField path="description" type="string">
  Default meta description for pages that don't override it in frontmatter.
</ParamField>

<ParamField path="theme" type="string" default="tang">
  `tang`, `pith`, `pip`, or any Mintlify theme alias. See [Themes](/reference/schema/themes).
</ParamField>

<ParamField path="colors" type="object">
  `{ primary, light, dark, background, anchors }`. Hex format only. See [Colors](/reference/schema/colors).
</ParamField>

<ParamField path="logo" type="string | object">
  Either a single path or `{ light, dark, href }`.
</ParamField>

<ParamField path="favicon" type="string | object">
  Path to a favicon. Object form supports `light` and `dark` variants.
</ParamField>

<ParamField path="navigation" type="object" required>
  Tabs, groups, anchors, dropdowns. See [Navigation](/guides/navigation).
</ParamField>

<ParamField path="navbar" type="object">
  Top-bar links and primary CTA. See [`docs.json` reference](/reference/schema/docs-json#navbar).
</ParamField>

<ParamField path="footer" type="object">
  Footer socials and link groups. See [`docs.json` reference](/reference/schema/docs-json#footer).
</ParamField>

<ParamField path="api" type="object">
  OpenAPI configuration. See [OpenAPI](/guides/openapi).
</ParamField>

<ParamField path="search" type="object">
  Search modal customization. `prompt` is the placeholder text. See [Search](/guides/search).
</ParamField>

<ParamField path="redirects" type="array">
  `[{ source, destination, permanent? }]`. Implemented as static HTML redirects.
</ParamField>

<ParamField path="seo" type="object">
  Custom meta tags + indexing controls.
</ParamField>

<ParamField path="analytics" type="object">
  PostHog, Plausible, Fathom, GA4, GTM, Amplitude, Hotjar, Mixpanel, Segment, Pirsch, LogRocket, Heap. Configure as many as you want.
</ParamField>

For the complete field-by-field reference (every nested object, every enum value), see [`docs.json` reference](/reference/schema/docs-json).

## Code blocks

`code` controls Shiki theming and the per-block copy button. See [Code](/reference/components/code) for the rendering surface.

```json
{
  "code": {
    "copyButton": true,
    "theme": { "light": "github-light", "dark": "github-dark" }
  }
}
```

`copyButton: false` hides the button globally (per-block opt-out: add `noCopy` to the fence meta). `theme` accepts a string (same theme for both modes) or an object split.

## Appearance

`appearance` toggles page chrome — color-scheme default plus the new reading-time stamp and reading-progress bar.

```json
{
  "appearance": {
    "default": "system",
    "readingTime": true,
    "readingProgress": true
  }
}
```

`readingTime: true` shows estimated minutes in the page header (computed from word count). `readingProgress: true` paints a 2px progress bar across the top of every page as the reader scrolls.

## Footer

Beyond the existing `socials` and `links`, the footer now drives last-updated stamps and edit-on-source links.

```json
{
  "footer": {
    "lastUpdated": true,
    "repo": "https://github.com/owner/repo",
    "editUrl": "https://github.com/owner/repo/edit/main/{path}"
  }
}
```

`lastUpdated: true` reads each page's last commit date from git and shows it in the footer. `editUrl` is a template — `{path}` is replaced with the page's path relative to the project root. If `editUrl` is omitted but `repo` is set, Tangly derives `editUrl` from the repo URL. If neither is set, the link is hidden.

## Banner

Top-of-page announcement strip. Add `id` to make dismissals stick across reloads (the id is the localStorage key — change it to re-show the banner). `type` controls tone.

```json
{
  "banner": {
    "id": "v02-launch",
    "type": "info",
    "dismissible": true,
    "content": "Tangly v0.2 ships richer code blocks — <a href=\"/changelog\">see what's new</a>"
  }
}
```

`type` is one of `info`, `warning`, `success`. See [Announcement banner](/guides/announcement) for the full guide.

## Section defaults

Cascade frontmatter through a directory subtree by dropping `_section.mdx` (or `_meta.json`) at the directory root:

```md
---
# guides/wip/_section.mdx
draft: true
mode: wide
icon: pencil-line
---
```

Every page under `guides/wip/` inherits these fields unless it overrides them in its own frontmatter. Section defaults bubble outward — closer overrides further.

## Validation

Run `tangly check` to validate `docs.json` against the schema and resolve every page reference:

```bash
bun x tangly check --strict
```

`--strict` exits non-zero on any warning (use this in CI). See [`tangly check`](/reference/cli/check) for the full surface.

## Editor support

Add `$schema` for autocomplete + inline validation in VS Code, Cursor, JetBrains:

```json
{
  "$schema": "./node_modules/tangly/schema/docs.json"
}
```

`tangly migrate` rewrites this for you when migrating from Mintlify.
