sharpdocs.json schema
Formal shape of the structural sharpdocs.json + the content site.json (base + locale overlays).
A SharpDocs project is described by two required JSON files at its root, plus optional per-locale overlays:
| File | Purpose | Required |
|---|---|---|
sharpdocs.json |
Structural — locales, defaultLocale, paths | yes |
site.json |
Base content — title, description, sidebar | yes |
site.{locale}.json |
Sparse content overlay for that locale | optional |
Path resolution rule: every relative path inside a JSON file is resolved relative to the directory of that file. The root sharpdocs.json's projects[].path is relative to the root docs folder; a per-project sharpdocs.json's artifacts is relative to its own project folder. Paths in appsettings.json follow a different rule (see Configuration options).
sharpdocs.json — single-project / per-project schema
The structural file. Same shape whether it's the root of a single-project site or one project inside a multi-project tree.
{
"github": "string | null", // optional repo URL, rendered in header
"artifacts": "string | null", // optional path; default "./artifacts" (per-project)
// or appsettings (single-project root)
"defaultLocale": "string", // required; must appear in `locales`
"locales": ["string", "string", ...] // required; non-empty
}
In a single-project root file, optional title / description are accepted for compatibility but unused — the per-locale site.json supplies them.
sharpdocs.json — multi-project root schema
A root file with a non-empty projects array switches the site to multi-project mode. The structural fields above move into each project's own sharpdocs.json; the root file is a thin pointer.
{
"title": "string | null", // optional — picker page branding only, untranslated
"description": "string | null", // optional — picker page branding only, untranslated
"projects": [
{
"id": "string", // url segment, sanitized to [a-z0-9-]
"path": "string" // relative to the root docs folder
}
]
}
There is no root defaultLocale or locales in multi-project mode — each project owns its own.
site.json — base content schema
The default-locale labels and sidebar structure. Required for every project.
{
"title": "string", // shown in header + <title>
"description": "string", // meta description
"sidebar": [
{
"label": "string", // group heading
"items": [
{
"label": "string", // link text
"slug": "string" // must match a page slug
}
]
}
]
}
site.
Same shape as site.json, but every field is optional. The merge is structural-by-position: each group/item overrides the entry at the same index in the base; missing or empty fields inherit. See Localization for the full overlay model.
{
"title": "string | null",
"description": "string | null",
"sidebar": [ // optional; can have fewer groups than base
{
"label": "string | null", // optional — null/missing → inherit from base[i]
"items": [ // optional; can have fewer items than base[i].items
{ "label": "string | null", "slug": "string | null" }
]
}
]
}
Matching rules
- JSON property names are case-insensitive.
slugis matched case-insensitively against the in-memory page lookup.- Leading and trailing slashes on
slugare trimmed before lookup. - Project
idis sanitized: lowercased, anything outside[a-z0-9-]stripped, runs of-collapsed, leading/trailing-trimmed. - Reserved ids (post-sanitization), applied to both project ids and locale codes:
search,packages,v3,api,docs. A reserved id is degraded with an error. - Duplicate project ids or locale codes (post-sanitization) silently drop the second occurrence.
- Locale-suffix detection on filenames (
foo.{locale}.md) only fires when{locale}appears inlocales— otherwise the dot is part of the slug.
Validation at startup
sharpdocs.jsonmust exist at the docs root —FileNotFoundExceptionotherwise.- It must deserialize to a non-null object —
InvalidOperationExceptionotherwise. defaultLocalemust be present inlocales.site.jsonmust exist for each project — fatal for that project if missing.- Every sidebar
slugmust resolve to a markdown file (base or locale override). Missing slugs degrade that locale. If the default locale fails, the whole project degrades. - A missing or malformed per-project
sharpdocs.jsondegrades the project, not the site. - Per-locale overlay files (
site.{locale}.json) are optional — silent when absent, logged-and-skipped when malformed.
Complete examples
Single-project, two locales
sharpdocs.json:
{
"github": "https://github.com/you/my-library",
"defaultLocale": "en",
"locales": ["en", "vi"]
}
site.json:
{
"title": "My library",
"description": "A small .NET library.",
"sidebar": [
{ "label": "Overview", "items": [{ "label": "Introduction", "slug": "index" }] }
]
}
site.vi.json (sparse — only the title is translated; sidebar inherits):
{ "title": "My library (Tiếng Việt)" }
Multi-project root
{
"title": "Codezerg Libraries",
"description": "Shared utilities.",
"projects": [
{ "id": "alpha", "path": "../codezerg-alpha" },
{ "id": "beta", "path": "../codezerg-beta" }
]
}
Multi-project per-project sharpdocs.json
{
"github": "https://github.com/codezerg/alpha",
"artifacts": "./artifacts",
"defaultLocale": "en",
"locales": ["en", "ja"]
}
(plus its own site.json, optional site.ja.json, and *.md / *.ja.md files at that project's root.)
Related
- Localization — overlay model
- Site config — narrative overview
- Multi-project sites — when and why