diff --git a/.agents/skills/scalar-docs-config-skill.mdc b/.agents/skills/scalar-docs/SKILL.md similarity index 97% rename from .agents/skills/scalar-docs-config-skill.mdc rename to .agents/skills/scalar-docs/SKILL.md index 7cf2fe9..eec2a6d 100644 --- a/.agents/skills/scalar-docs-config-skill.mdc +++ b/.agents/skills/scalar-docs/SKILL.md @@ -1,8 +1,8 @@ --- -description: Skill for writing and updating scalar.config.json — Scalar Docs configuration reference for users and LLMs -globs: scalar.config.json, scalar.config.json5 -alwaysApply: false +name: scalar-docs +description: Skill for writing and updating scalar.config.json — Scalar Docs configuration reference for users and LLMs. --- + # Scalar Docs Configuration Skill — scalar.config.json Reference for writing and updating `scalar.config.json`, the central configuration file for [Scalar Docs](https://docs.scalar.com). Use this when creating, editing, or validating Docs configuration for any project. @@ -128,12 +128,15 @@ Markdown/MDX content from a file: "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: diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ffa97dd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,37 @@ +# AGENTS.md + +## Repository purpose + +The Scalar Docs Starter Kit — a configuration-only documentation project deployed via Scalar Docs GitHub Sync. There is no build system, no package.json, and no source code. All behavior is driven by `scalar.config.json` plus MDX files under `docs/content/` (the starter is MDX-by-default; `.md` still works) and OpenAPI documents under `docs/api-reference/`. + +## Commands + +All tooling runs through the Scalar CLI (`npx @scalar/cli`). There is no install step. + +- `npx @scalar/cli project preview` — local dev server at `http://localhost:7971` with live reload +- `npx @scalar/cli project check-config` — validate `scalar.config.json` (this is what CI runs) +- `npx @scalar/cli project publish` — publish current local files to Scalar +- `npx @scalar/cli project upgrade` — migrate a Docs 1.0 config to 2.0 + +CI (`.github/workflows/validate-scalar-configuration.yml`) runs `check-config` on any push/PR that touches `scalar.config.json` or `docs/**`. Run `check-config` locally before committing changes to those paths. + +## Architecture + +Everything is orchestrated by `scalar.config.json`: + +- `navigation.routes` is the single source of truth for sitemap and sidebar. Each key is a URL path; each value has a `type` of `page`, `openapi`, `group`, or `link`. +- `type: "page"` routes reference MDX via `filepath` (paths relative to repo root, e.g. `docs/content/quickstart.mdx`). +- `type: "openapi"` routes reference OpenAPI documents via `filepath`, or pull from the Scalar Registry (`namespace` + `slug`), or a remote `url`. +- `type: "group"` nests children and supports `mode`: `folder` (default), `flat`, or `nested`. `mode: "flat"` hoists children into the parent level without a collapsible wrapper — used in this repo for the Components, Layouts, and Examples sections. +- `siteConfig` controls branding, theme, custom domain/subdomain, `head` injection (scripts/styles/meta), and redirects. +- Page-level `layout` overrides (`toc`, `sidebar`, `header`, `tabs`, `pageTitle`, `pageActions`, `search`) live on the route entry, not in the MDX. See the Layouts gallery for live examples. + +Adding a new page: create a `.mdx` file under `docs/content/`, then add a route entry in `scalar.config.json` pointing at it. `docs/content/components/` and `docs/content/layouts/` are galleries — don't add unrelated pages there; put new top-level content next to `quickstart.mdx`. Adding a new API reference: drop the OpenAPI document under `docs/api-reference/` and add a `type: "openapi"` route. The file path in `filepath` is relative to the repo root, not to `docs/`. + +MDX components from `scalar-mdx-components` (`Callout`, `Button`, `Tabs`, `PageLink`, etc.) currently need explicit imports at the top of each page — the CLI's MDX pipeline does not auto-inject them. The Components gallery pages demonstrate the pattern. + +The config schema is fetched from `https://registry.scalar.com/@scalar/schemas/config` (see `$schema`). `.vscode/settings.json` whitelists this host so VS Code autocompletes and validates the config inline — keep that whitelist when editing VS Code settings. + +## Scalar config reference + +`.agents/skills/scalar-docs-config-skill.mdc` is a comprehensive, up-to-date reference for every field in `scalar.config.json` (route types, header/sidebar/tabs, theming, domains, `head` injection, redirects, migration from 1.0). Consult it before editing the config rather than guessing field names — it is the authoritative local reference and more specific than the public docs. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/README.md b/README.md index a4375e8..aed59ca 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Twitter](https://img.shields.io/twitter/follow/scalar)](https://x.com/scalar) [![Discord](https://img.shields.io/discord/1135330207960678410?style=flat&color=5865F2)](https://discord.gg/scalar) -Welcome to the Scalar Docs Starter Kit! Deploy Markdown and OpenAPI documents from GitHub. +Welcome to the Scalar Docs Starter Kit! Deploy MDX and OpenAPI documents from GitHub. ## Preview @@ -36,11 +36,15 @@ This repository includes a GitHub Action workflow that automatically validates t ``` starter/ ├── docs/ -│ ├── api-reference/ # OpenAPI documents -│ └── guides/ # Free-form text -├── scalar.config.json # Configuration +│ ├── api-reference/ # OpenAPI documents +│ └── content/ # MDX pages (.mdx by default; .md still works) +│ ├── components/ # Gallery — one page per Scalar MDX component +│ └── layouts/ # Gallery — per-page layout overrides +├── scalar.config.json # Configuration ``` +Pages are `.mdx` by default, so you can mix Markdown with JSX expressions and drop in components like ``, ` + +## Props + +| Prop | Type | Description | +| ------ | -------- | -------------------------------------------------------------- | +| `href` | `string` | Destination URL. | +| `icon` | `string` | Optional icon identifier (e.g. `line/arrow-right`). | +| `title`| `string` | Alternative to nested text content. | + +## Variants + + + + diff --git a/docs/content/components/callout.mdx b/docs/content/components/callout.mdx new file mode 100644 index 0000000..6c2f124 --- /dev/null +++ b/docs/content/components/callout.mdx @@ -0,0 +1,38 @@ +import { Callout } from 'scalar-mdx-components' + +# Callout + +Highlight a block of content with a typed banner. Use sparingly — one or two per page. + +## Usage + + + This is the simplest possible callout. + + +## Props + +| Prop | Type | Description | +| ------ | ------------------------------------------------------------------ | ---------------------------------------------------- | +| `type` | `'info' \| 'warning' \| 'danger' \| 'success' \| 'neutral'` | Controls color and icon. Defaults to `neutral`. | +| `icon` | `string` | Override the default icon for this type. | + +## Variants + + + Neutral information the reader may want to know. + + + + Something to be careful about — non-blocking. + + + + Something destructive or blocking. Read before proceeding. + + + + A happy confirmation or positive note. + + +Markdown works inside the body — use `code`, **bold**, [links](https://scalar.com), and lists freely. diff --git a/docs/content/components/embed.mdx b/docs/content/components/embed.mdx new file mode 100644 index 0000000..adaed7e --- /dev/null +++ b/docs/content/components/embed.mdx @@ -0,0 +1,21 @@ +import { Embed } from 'scalar-mdx-components' + +# Embed + +Drop any iframe-embeddable URL — video, demo, widget — directly into the page. Anything a provider allows to be framed (YouTube, Vimeo, Loom, CodeSandbox, Figma, …) works. + +## Usage + + + +## Props + +| Prop | Type | Description | +| --------- | -------- | ---------------------------------------------------------------------------- | +| `src` | `string` | URL to embed. Use the provider's **embed** URL, not the share/watch URL. | +| `alt` | `string` | Accessible title for the iframe. | +| `caption` | `string` | Optional caption shown below the iframe. | + +## Variants + + diff --git a/docs/content/components/fineprint.mdx b/docs/content/components/fineprint.mdx new file mode 100644 index 0000000..c0688d9 --- /dev/null +++ b/docs/content/components/fineprint.mdx @@ -0,0 +1,15 @@ +# Fineprint + +Render small legal-style text for disclaimers, terms-like footnotes, or version badges. + +Unlike the other components in this gallery, Fineprint is a **custom element**, not a React/MDX component. Use the lowercase tag `` directly — no `import` needed. + +## Usage + + + This is fine print. Subject to change without notice. + + +## Why is this one different? + +Most components ship a React wrapper exported from `scalar-mdx-components`. Fineprint is implemented only as a server-rendered custom element, so you write it as HTML in your MDX and Scalar's server-side pipeline renders it. This is also how you'd use any other `` element that doesn't have an MDX wrapper yet. diff --git a/docs/content/components/image.mdx b/docs/content/components/image.mdx new file mode 100644 index 0000000..d187e10 --- /dev/null +++ b/docs/content/components/image.mdx @@ -0,0 +1,25 @@ +import { Image } from 'scalar-mdx-components' + +# Image + +Display an image with optional caption, dark-mode source, and sizing. + +## Usage + +A beautiful landscape + +## Props + +| Prop | Type | Description | +| ---------- | ------------------- | ---------------------------------------------- | +| `src` | `string` | Image URL. | +| `alt` | `string` | Alt text for accessibility. | +| `caption` | `string` | Optional caption shown below the image. | +| `src-dark` | `string` | Alternative source rendered in dark mode. | +| `href` | `string` | Wrap the image in a link. | +| `width` | `string \| number` | HTML `width` attribute. | +| `height` | `string \| number` | HTML `height` attribute. | + +## Variants + +Mountain lake at sunset diff --git a/docs/content/components/math.mdx b/docs/content/components/math.mdx new file mode 100644 index 0000000..1a036cd --- /dev/null +++ b/docs/content/components/math.mdx @@ -0,0 +1,22 @@ +import { Math } from 'scalar-mdx-components' + +# Math + +Render LaTeX equations with [KaTeX](https://katex.org/). + +## Usage + + + +## Props + +| Prop | Type | Description | +| ---------- | -------- | ---------------------------------------------------------------------- | +| `equation` | `string` | The LaTeX expression. Alternatively, put the expression in the body. | +| `caption` | `string` | Optional caption shown below the rendered equation. | + +## Variants + + + + diff --git a/docs/content/components/page-link.mdx b/docs/content/components/page-link.mdx new file mode 100644 index 0000000..5b3784b --- /dev/null +++ b/docs/content/components/page-link.mdx @@ -0,0 +1,24 @@ +import { PageLink } from 'scalar-mdx-components' + +# PageLink + +Link to another page in this documentation. Preferred over a plain Markdown link — the title and description stay in sync with the target page's metadata. + +## Usage + + + +## Props + +| Prop | Type | Description | +| ------------- | -------- | ------------------------------------------------------------------------------------------------ | +| `filepath` | `string` | Path to another MDX/Markdown page, relative to the content root (e.g. `components/tabs`). | +| `uid` | `string` | Alternative to `filepath` for editor-managed docs. | +| `title` | `string` | Override the target page's title. | +| `description` | `string` | Override the target page's description. | + +## Variants + + + + diff --git a/docs/content/components/tabs.mdx b/docs/content/components/tabs.mdx new file mode 100644 index 0000000..9c39fc7 --- /dev/null +++ b/docs/content/components/tabs.mdx @@ -0,0 +1,40 @@ +import { Tabs, Tab } from 'scalar-mdx-components' + +# Tabs + +Group related content — typically code samples in different languages — behind a tab switcher. + +## Usage + + + + ```js + const users = await fetch('/api/users').then((r) => r.json()) + ``` + + + ```python + import requests + users = requests.get('/api/users').json() + ``` + + + ```bash + curl https://api.example.com/users + ``` + + + +## Props + +### `` + +| Prop | Type | Description | +| --------- | -------- | ---------------------------------------------------------------------------------- | +| `default` | `string` | Title of the tab to open by default. Matches case-insensitively. First tab if omitted. | + +### `` + +| Prop | Type | Description | +| ------- | -------- | ----------- | +| `title` | `string` | Tab label. | diff --git a/docs/content/development.md b/docs/content/development.md deleted file mode 100644 index 8ba4613..0000000 --- a/docs/content/development.md +++ /dev/null @@ -1,24 +0,0 @@ -# Development - -## Local Preview - -Run `@scalar/cli project preview` to start a local development server with live reload. - -## Port - -The default port is `7970`. Override with `--port`: - -```sh -npx @scalar/cli project preview --port 3000 -``` - -If the port is in use, the CLI selects another automatically. - -## Configuration - -The CLI looks for `scalar.config.json` in the current directory by default. To use a different config: - -```sh -npx @scalar/cli project preview my-scalar-config.json -npx @scalar/cli project preview ../some-other-directory/scalar.config.json -``` diff --git a/docs/content/layouts/minimal.mdx b/docs/content/layouts/minimal.mdx new file mode 100644 index 0000000..e75eb29 --- /dev/null +++ b/docs/content/layouts/minimal.mdx @@ -0,0 +1,29 @@ +# Minimal + +Hides every piece of chrome: header, sidebar, tabs, TOC, page title, page actions, and search. Use for fully custom landing pages, marketing pages, or embeddable standalone docs. + +With everything off there's no built-in way back, so link somewhere manually: + +[← Back to Quickstart](/) + +## Config + +```json +{ + "type": "page", + "filepath": "docs/content/layouts/minimal.mdx", + "layout": { + "toc": false, + "header": false, + "sidebar": false, + "tabs": false, + "pageTitle": false, + "pageActions": false, + "search": { + "enabled": false + } + } +} +``` + +Drop the `layout` block into the route for any page you want to behave this way. diff --git a/docs/content/layouts/no-sidebar.mdx b/docs/content/layouts/no-sidebar.mdx new file mode 100644 index 0000000..b32296d --- /dev/null +++ b/docs/content/layouts/no-sidebar.mdx @@ -0,0 +1,17 @@ +# No Sidebar + +Hides the left navigation sidebar on this page only. Use for marketing pages or anything that wants full-width content. + +This is a page-level opt-out — the sidebar returns on every other page in the site. + +## Config + +```json +{ + "type": "page", + "filepath": "docs/content/layouts/no-sidebar.mdx", + "layout": { "sidebar": false } +} +``` + +Drop the `layout` block into the route for any page you want to behave this way. diff --git a/docs/content/layouts/no-toc.mdx b/docs/content/layouts/no-toc.mdx new file mode 100644 index 0000000..e38f046 --- /dev/null +++ b/docs/content/layouts/no-toc.mdx @@ -0,0 +1,31 @@ +# No TOC + +Hides the right-hand table of contents. Use on long scrolling pages, landing pages, or anywhere the TOC would be noise. + +## Config + +```json +{ + "type": "page", + "filepath": "docs/content/layouts/no-toc.mdx", + "layout": { "toc": false } +} +``` + +Drop the `layout` block into the route for any page you want to behave this way. + +## Verify + +This page has several headings below. On every other page they'd populate the right-hand TOC. Here that column is empty. + +## First extra heading + +Filler text. + +## Second extra heading + +More filler text. + +## Third extra heading + +Still more filler text. diff --git a/docs/content/layouts/search-in-header.mdx b/docs/content/layouts/search-in-header.mdx new file mode 100644 index 0000000..260fdd1 --- /dev/null +++ b/docs/content/layouts/search-in-header.mdx @@ -0,0 +1,19 @@ +# Search in Header + +Moves the search input from the sidebar into the top bar. Use when your audience expects search up top, or when the header feels empty. + +## Config + +```json +{ + "type": "page", + "filepath": "docs/content/layouts/search-in-header.mdx", + "layout": { + "search": { + "position": "header" + } + } +} +``` + +`position` accepts `"sidebar"` (default) or `"header"`. Drop the `layout` block into the route for any page you want to behave this way. diff --git a/docs/content/quickstart.md b/docs/content/quickstart.md deleted file mode 100644 index bc80996..0000000 --- a/docs/content/quickstart.md +++ /dev/null @@ -1,57 +0,0 @@ -# Quickstart - -This is the Scalar Docs Starter Kit — a ready-to-use template for building beautiful documentation. Fork it, clone it, and make it your own. Everything here is meant to be modified, extended, or replaced to fit your project. - -## 1. Preview Your Docs - -Run a local development server to see your changes in real-time: - -```bash -npx @scalar/cli project preview -``` - -This starts a live preview at `http://localhost:7971` where every edit you make is instantly visible. - -Read more about [Development](development.md). - -## 2. Include OpenAPI Documents - -Drop your OpenAPI files into `docs/api-reference/`, and add them to `@scalar.config.json` to have them automatically become interactive API references. - -The starter kit includes an example OpenAPI document to show you how it works. - -Read more about [API References](api-references.md) - -## 3. Customize Everything - -Make it yours with themes, custom CSS, and MDX. Configure your documentation structure, navigation, and styling through `scalar.config.json`. - -## 4. Publish Your Docs - -First, authenticate with your Scalar account: - -```bash -npx @scalar/cli auth login -``` - -Then publish your documentation: - -```bash -npx @scalar/cli project publish -``` - -Your site will be available at `.apidocumentation.com`. - -## Stuck? - -Check whether your `scalar.config.json` is valid: - -```bash -npx @scalar/cli project check-config -``` - -We're here to help: - -- [Email support@scalar.com](mailto:support@scalar.com) -- [Chat with us on Discord](https://discord.gg/scalar) -- [Schedule a call](https://scalar.cal.com/scalar/chat-with-scalar) diff --git a/docs/content/quickstart.mdx b/docs/content/quickstart.mdx new file mode 100644 index 0000000..3c33cb3 --- /dev/null +++ b/docs/content/quickstart.mdx @@ -0,0 +1,26 @@ +# Quickstart + +Welcome to the Scalar Docs Starter Kit — a template for deploying beautiful documentation from a GitHub repository. Every page is MDX by default: mix Markdown with JSX expressions (this page rendered in {new Date().getFullYear()}) and drop in components anywhere. Fork it, edit the files under `docs/content/`, and make it yours. + +## Explore + +- [**Layouts:**](layouts/no-toc) hide the sidebar, move search, or build a fully custom landing page +- [**Components:**](components/callout) Callout, Button, Tabs, and every other component you can drop into MDX +- [**API References:**](api-references) add OpenAPI documents from a file, the Scalar Registry, or a URL + +## Preview locally + +```bash +npx @scalar/cli@latest project preview +``` + +Starts a dev server at `http://localhost:7971` with live reload. + +## Publish + +```bash +npx @scalar/cli@latest auth login +npx @scalar/cli@latest project publish +``` + +Your site will be available at `.apidocumentation.com`. diff --git a/scalar.config.json b/scalar.config.json index 5d83994..c1889ba 100644 --- a/scalar.config.json +++ b/scalar.config.json @@ -12,6 +12,10 @@ } }, "navigation": { + "header": [ + { "type": "link", "title": "Log in", "to": "https://dashboard.scalar.com/login" }, + { "type": "link", "title": "Register", "style": "button", "icon": "phosphor/regular/user-plus", "to": "https://dashboard.scalar.com/register" } + ], "routes": { "/": { "type": "group", @@ -19,32 +23,128 @@ "children": { "/": { "type": "page", - "filepath": "docs/content/quickstart.md", + "filepath": "docs/content/quickstart.mdx", "title": "Quickstart", "icon": "phosphor/regular/fast-forward" }, - "/usage": { + "/api-references": { + "type": "page", + "filepath": "docs/content/api-references.mdx", + "title": "API References", + "icon": "phosphor/regular/notebook" + }, + "/documentation": { + "type": "link", + "title": "Documentation", + "url": "https://scalar.com/products/docs/getting-started", + "icon": "phosphor/regular/book-open" + }, + "/github": { + "type": "link", + "title": "GitHub", + "url": "https://github.com/scalar/starter", + "icon": "phosphor/regular/github-logo" + }, + "/components": { + "type": "group", + "title": "Components", + "mode": "flat", + "children": { + "/callout": { + "type": "page", + "filepath": "docs/content/components/callout.mdx", + "title": "Callout", + "icon": "phosphor/regular/megaphone" + }, + "/button": { + "type": "page", + "filepath": "docs/content/components/button.mdx", + "title": "Button", + "icon": "phosphor/regular/cursor-click" + }, + "/embed": { + "type": "page", + "filepath": "docs/content/components/embed.mdx", + "title": "Embed", + "icon": "phosphor/regular/video" + }, + "/image": { + "type": "page", + "filepath": "docs/content/components/image.mdx", + "title": "Image", + "icon": "phosphor/regular/image" + }, + "/fineprint": { + "type": "page", + "filepath": "docs/content/components/fineprint.mdx", + "title": "Fineprint", + "icon": "phosphor/regular/text-aa" + }, + "/math": { + "type": "page", + "filepath": "docs/content/components/math.mdx", + "title": "Math", + "icon": "phosphor/regular/function" + }, + "/page-link": { + "type": "page", + "filepath": "docs/content/components/page-link.mdx", + "title": "PageLink", + "icon": "phosphor/regular/link" + }, + "/tabs": { + "type": "page", + "filepath": "docs/content/components/tabs.mdx", + "title": "Tabs", + "icon": "phosphor/regular/squares-four" + } + } + }, + "/layouts": { "type": "group", - "title": "Usage", + "title": "Layouts", "mode": "flat", "children": { - "/development": { + "/no-toc": { "type": "page", - "filepath": "docs/content/development.md", - "title": "Development", - "icon": "phosphor/regular/code" + "filepath": "docs/content/layouts/no-toc.mdx", + "title": "No TOC", + "icon": "phosphor/regular/list-dashes", + "layout": { "toc": false } }, - "/api-references": { + "/no-sidebar": { "type": "page", - "filepath": "docs/content/api-references.md", - "title": "API References", - "icon": "phosphor/regular/notebook" + "filepath": "docs/content/layouts/no-sidebar.mdx", + "title": "No Sidebar", + "icon": "phosphor/regular/sidebar-simple", + "layout": { "sidebar": false } }, - "/documentation": { - "title": "Full Documentation", - "icon": "phosphor/regular/book", - "url": "https://scalar.com/products/docs/getting-started", - "type": "link" + "/search-in-header": { + "type": "page", + "filepath": "docs/content/layouts/search-in-header.mdx", + "title": "Search in Header", + "icon": "phosphor/regular/magnifying-glass", + "layout": { + "header": true, + "search": { + "position": "header" + } + } + }, + "/minimal": { + "type": "page", + "filepath": "docs/content/layouts/minimal.mdx", + "title": "Minimal", + "icon": "phosphor/regular/square", + "layout": { + "toc": false, + "header": false, + "sidebar": false, + "tabs": false, + "pageTitle": false, + "pageActions": false, + "search": { "enabled": false } + } } } }, diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 0000000..e51e083 --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,10 @@ +{ + "version": 1, + "skills": { + "scalar-docs": { + "source": "scalar/scalar", + "sourceType": "github", + "computedHash": "11e11f9e8732d0873886e9290243f76d0188fc3cf2ce8674e595056a614073a5" + } + } +}