Agent Skills

scalar-docs

Skill for writing and updating scalar.config.json — Scalar Docs configuration reference for users and LLMs.

Install

npx skills add https://github.com/scalar/scalar --skill scalar-docs
SKILL.md

Scalar Docs Configuration Skill — scalar.config.json

Reference for writing and updating scalar.config.json, the central configuration file for Scalar Docs. Use this when creating, editing, or validating Docs configuration for any project.

Overview

  • File: scalar.config.json (or scalar.config.json5)
  • Location: Repository root by default; path can be overridden in Scalar Dashboard
  • Schema: https://registry.scalar.com/@scalar/schemas/config — enables autocomplete in VS Code/Cursor when json.schemaDownload.enable is true
  • Version: Use "scalar": "2.0.0" for the latest format

Quick Start

Create a minimal config:

npx @scalar/cli project init

Minimal structure:

{
  "$schema": "https://registry.scalar.com/@scalar/schemas/config",
  "scalar": "2.0.0",
  "info": {
    "title": "My Documentation",
    "description": "The best documentation you've read today"
  },
  "navigation": {
    "routes": {
      "/": {
        "title": "Introduction",
        "type": "page",
        "filepath": "docs/introduction.md"
      }
    }
  }
}

Validate config: npx @scalar/cli project check-config


Root Properties

Property Type Description
$schema string JSON Schema URL for editor autocomplete and validation
scalar string Configuration version. Use "2.0.0"
info object Project metadata (title, description)
navigation object Navigation structure (header, routes, sidebar, tabs)
versions object Multi-version navigation. Use instead of navigation for versioned docs
siteConfig object Site-level settings (domain, theme, head, logo, routing)
assetsDir string Relative path to assets folder from config root

info

Project metadata displayed across the site:

{
  "info": {
    "title": "My Documentation",
    "description": "Comprehensive guides for our API"
  }
}

navigation

All navigation is in navigation.routes. Each route key is the URL path; the value is a config object.

navigation.header

Links in the top bar. Use type: "spacer" to push items before it left and after it right.

"header": [
  { "type": "link", "title": "Home", "to": "/" },
  { "type": "spacer" },
  { "type": "link", "title": "Log in", "to": "https://dashboard.example.com/login", "newTab": true },
  { "type": "link", "title": "Register", "style": "button", "icon": "phosphor/regular/user-plus", "to": "https://...", "newTab": true }
]

Properties: title, type ("link" | "spacer"), to, style ("button" | "link"), icon, newTab

The header only renders when this array has at least one item, and it is where the logo goes. A lone { "type": "spacer" } is enough to get a header with just the logo.

navigation.sidebar

Links at the bottom of the sidebar:

"sidebar": [
  { "title": "Log in", "to": "https://...", "newTab": true }
]

navigation.tabs

Tabs for quick access to sections:

"tabs": [
  { "title": "API", "to": "/api", "icon": "phosphor/regular/plug" }
]

Tabs and a header work together, and neither requires the other. With tabs but no header, the logo renders in the tab bar.

Route Types

Page (type: "page")

Markdown/MDX content from a file:

"/getting-started": {
  "type": "page",
  "title": "Getting Started",
  "filepath": "docs/getting-started.md",
  "description": "Optional SEO description",
  "icon": "phosphor/regular/rocket",
  "showInSidebar": true,
  "layout": { "toc": true, "sidebar": true }
}

Layout: toc (default true), sidebar (default true).

Hidden pages: Set showInSidebar: false to hide a page from the sidebar while keeping it accessible via its direct URL.

OpenAPI (type: "openapi")

API reference from file, Registry, or URL:

File:

"/api": {
  "type": "openapi",
  "title": "My API",
  "filepath": "docs/api-reference/openapi.yaml",
  "icon": "phosphor/regular/plug"
}

Registry:

"/api": {
  "type": "openapi",
  "title": "My API",
  "namespace": "my-organization",
  "slug": "your-api"
}

URL:

"/api": {
  "type": "openapi",
  "title": "My API",
  "url": "https://example.com/openapi.json"
}

Display modes: folder (default), flat, nested.

Single page mode: Set singlePage: true to render all operations on a single page instead of creating separate pages for each operation:

"/api": {
  "type": "openapi",
  "title": "My API",
  "filepath": "docs/api-reference/openapi.yaml",
  "singlePage": true
}

API Reference options (authentication, theme, etc.) go in a config object — same options as the API Reference configuration.

Group (type: "group")

Collapsible section with children:

"/products": {
  "type": "group",
  "title": "Products",
  "mode": "flat",
  "icon": "phosphor/regular/package",
  "children": {
    "/docs": { "type": "page", "title": "Documentation", "filepath": "docs/documentation.md" },
    "/api": { "type": "openapi", "title": "API Reference", "filepath": "openapi.yaml" }
  }
}

Modes: flat, nested, folder (default).

Folder landing pages: Add a page property to make clicking the folder navigate to a page:

"/company": {
  "type": "group",
  "title": "Company",
  "mode": "folder",
  "page": { "type": "page", "title": "About Us", "filepath": "docs/company/index.md" },
  "children": {
    "/team": { "type": "page", "title": "Our Team", "filepath": "docs/company/team.md" }
  }
}

Default open state: Use open: true to expand a folder by default.

Link (type: "link")

External URL:

"/github": {
  "type": "link",
  "title": "GitHub",
  "url": "https://github.com/org/repo",
  "icon": "phosphor/regular/github-logo"
}

siteConfig

branding

Logo — single URL or per mode:

"logo": "https://example.com/logo.svg"
// or
"logo": {
  "darkMode": "https://example.com/logo-dark.svg",
  "lightMode": "https://example.com/logo-light.svg"
}

The logo renders on the first surface the site has: header (if navigation.header has items) → tabs (if navigation.tabs but no header) → sidebar (if neither). A page that hides all three via layout does not render it at all. With no logo set, info.title renders in the same place.

Theme — one of: default, alternate, moon, purple, solarized, bluePlanet, deepSpace, saturn, kepler, mars, laserwave, none

"theme": "purple"

Social card — point og.imageTemplate at a TSX/JSX template in the project to replace the generated share image. The path is relative to the config file and must stay inside the project.

"og": {
  "imageTemplate": "./og/card.tsx"
}

The template default-exports a pure function taking { title, description?, breadcrumb?, path, colors, logo, mode } and returning JSX. It is drawn by Satori: flexbox only, inline styles only, no packages imported. An og:image in siteConfig.head.meta overrides it site-wide.

domain

Subdomain (free): https://<subdomain>.apidocumentation.com

"subdomain": "your-docs"

Custom domain (Pro): https://docs.example.com

"customDomain": "docs.example.com"

Subpath — for multiple projects on same domain:

"subpath": "/guides"

layout

"layout": {
  "toc": true,
  "header": true
}

head

Inject scripts, styles, meta tags, and links:

"head": {
  "title": "My Documentation",
  "meta": [
    { "name": "description", "content": "API documentation" },
    { "property": "og:image", "content": "https://example.com/og.png" }
  ],
  "styles": [{ "path": "docs/assets/custom.css", "tagPosition": "head" }],
  "scripts": [{ "path": "docs/assets/analytics.js", "tagPosition": "bodyClose" }],
  "links": [{ "rel": "icon", "href": "/favicon.png" }]
}

For scripts and styles: path relative to config root. For links (favicon): root-relative (/favicon.png).

tagPosition: "head" | "bodyOpen" | "bodyClose".

footer

"footer": {
  "filepath": "docs/footer.html"
}

rss

Publishes an RSS feed for your changelog or blog so readers can subscribe. Written to <path>/rss.xml — a changelog at /changelog publishes its feed at /changelog/rss.xml.

"rss": {
  "path": "/changelog",
  "title": "Scalar Changelog",
  "description": "Every Scalar release, as a feed"
}
Property Type Required Description
path string Yes Changelog route, e.g. /changelog. No .. segments
title string No Feed title. Defaults to your site title plus Changelog
description string No Feed description
entries string No headings (default) or pages — see below

To publish several feeds, set rss to a list of these objects. Each needs its own unique path and is written to <path>/rss.xml:

"rss": [
  { "path": "/changelog", "title": "Scalar Changelog" },
  { "path": "/blog", "title": "Scalar Blog" }
]

Entries come from dated headings (## 1.2.0 (2026-07-24)) on the page at path or any page beneath it, merged newest-first. Only the top-most dated heading level starts entries; deeper headings (dated or not) fold into the release above them. Hidden pages are skipped. Every page advertises the feed with a <link rel="alternate" type="application/rss+xml"> tag, and pages under path show a subscribe button in the page header.

Set entries to pages for a blog instead: every page under path with a date in its frontmatter (date: 2026-07-24) becomes one item, titled by the page. Pages without a date (an index, a draft) are skipped. Use the default headings for a changelog.

routing

Redirects:

"routing": {
  "redirects": [
    { "from": "/old-path", "to": "/new-path" },
    { "from": "/old-path/:wildcard", "to": "/new-path" },
    { "from": "/old-path/:pathMatch(.*)*", "to": "/new-path" }
  ]
}

Path patterns:

"routing": {
  "guidePathPattern": "/docs/:slug",
  "referencePathPattern": "/api/:slug"
}

assetsDir

Relative path to assets folder. Assets are served from site root.

"assetsDir": "docs/assets"

In Markdown: ![Image](/screenshot.png) or ![Image](../assets/screenshot.png).

In siteConfig.head: use full path relative to config root for scripts/styles; root-relative for links.


Migration from Docs 1.0

Docs 1.0 used guides and references arrays. Docs 2.0 uses navigation.routes.

Upgrade:

npx @scalar/cli project upgrade

Check result:

npx @scalar/cli project preview

CLI Commands

Command Description
npx @scalar/cli project init Create scalar.config.json
npx @scalar/cli project check-config Validate config
npx @scalar/cli project preview Local preview (port 7970)
npx @scalar/cli project publish Publish from local files
npx @scalar/cli project publish --github Publish from linked GitHub repo
npx @scalar/cli project upgrade Migrate from Docs 1.0

Versions

Use versions instead of navigation to create multi-version documentation.

A version with the key default is required — it is the version shown by default. Additional versions (for example v1) can use any identifier and appear in the version selector. Inside each version's routes, wrap pages in a top-level group so they render correctly in the sidebar.

{
  "scalar": "2.0.0",
  "versions": {
    "default": {
      "title": "Version 2.0",
      "routes": {
        "/": {
          "type": "group",
          "title": "Documentation",
          "children": {
            "/": { "type": "page", "title": "Intro", "filepath": "docs/v2/intro.md" },
            "/api": { "type": "openapi", "title": "API", "filepath": "docs/v2/openapi.yaml" }
          }
        }
      }
    },
    "v1": {
      "title": "Version 1.0",
      "routes": {
        "/": {
          "type": "group",
          "title": "Documentation",
          "children": {
            "/": { "type": "page", "title": "Intro", "filepath": "docs/v1/intro.md" },
            "/api": { "type": "openapi", "title": "API", "filepath": "docs/v1/openapi.yaml" }
          }
        }
      }
    }
  }
}

Each version entry supports: title, routes (required), header, sidebar, tabs.


Common Patterns

Multi-project on same domain: Same customDomain or subdomain, different subpath per repo.

MDX: Use .mdx extension in filepath; same structure as Markdown pages.

Hide TOC on a page: "layout": { "toc": false } on that route.

API Reference auth: Add config under the openapi route with authentication (same options as API Reference config).

Custom domain DNS: CNAME host docs → dns.scalar.com (DNS-only, no proxy).


References

Search skills and MCP servers

Fuzzy search across 23,137 skills and servers