ShellDocs.Core

ShellDocs.Core holds the framework's model layer: how content folders become a nav graph, how pages get ranked in search, how markdown collapses to plain text for indexing. No UI, no rendering : pure data structures and helpers.

Transitive by default

You don't reference ShellDocs.Core directly : it comes in via ShellDocs.Components. Add it explicitly only if you're building something outside the normal AddShellDocs flow (custom search UI, programmatic nav traversal, standalone markdown-to-text conversion).

Install

bash
dotnet add package ShellDocs.Core --prerelease

Key types

Prop Type Default Description
NavigationGraph service — The full site tree. ResolveByUrl, GetPrevNext, GetBreadcrumb, Flatten.
NavigationGraphBuilder static — Build(contentRoot) walks the folder tree, reads meta.json + frontmatter, produces a NavigationGraph.
NavigationNode record — One node: Url, Title, Description, Order, Kind (Page / Section / Divider), Children, Parent.
SearchIndex service — In-memory search index. Entries : page + heading entries with URL, title, description, section, body text.
SearchEntry record — One indexed entry. Page entries carry Body (extracted plain text, 8KB cap); heading entries anchor into their page.
MarkdownPlainText static — Extract(markdown, maxLength) : strips frontmatter, fences, HTML, Razor tags, images, links, inline code, emphasis, heading #. Used by SearchIndex for body-text indexing.

The NavigationGraph walks content/docs/ at startup, reads every meta.json for ordering, every .md for frontmatter (title / description / order), and builds a tree the sidebar / breadcrumb / prev-next chrome all consume.

csharp
// Injected via DI once you've called AddShellDocs
[Inject] NavigationGraph Graph { get; set; } = default!;

var node = Graph.ResolveByUrl("/docs/getting-started/installation");
var (prev, next) = Graph.GetPrevNext(node);
var trail = Graph.GetBreadcrumb(node);
meta.json controls order only

Files you don't list in a folder's meta.json pages array still appear in the sidebar : they get appended alphabetically after your explicit ordering. Drop a new .md into any subfolder and it shows up without editing meta.json.

Search index

Built once at startup from NavigationGraph. Every page becomes one SearchEntry (title + description + section + body); every h2/h3 becomes an anchored SearchEntry (title + section, no body).

The app serves the index as JSON at /_shelldocs/search.json, with no change to Program.cs, and shelldocs build copies that file into a static export. Searching itself happens in the browser: shelldocs.js fetches the file the first time search opens and scores every entry against all four fields, with weighted substring matching and per-token AND, keeping to the docs version the reader is on. Nothing is asked of the server, so search is the same on a .NET host and on a static host. See Search.

Body entries carry up to 8KB of extracted plain text : enough for meaningful body-hit surfacing without bloating the in-memory index for typical docs sites (~100 pages).

MarkdownPlainText

Standalone helper : no DI, no state. Strips markdown to prose for indexing.

csharp
var plain = MarkdownPlainText.Extract(File.ReadAllText("page.md"));
// Frontmatter, fenced blocks, HTML tags, Razor components, images,
// links (text kept), inline code, emphasis, heading #, list markers,
// blockquotes : all stripped. Whitespace collapsed.

Reusable outside search : anywhere you need clean prose from raw markdown.

Learn more