This documentation is also published as Markdown for efficient machine reading: the whole site is indexed at /llms.txt, and every page has a clean Markdown copy under /_llms/. These are generated from the same source and cost far fewer tokens to read than this rendered HTML.

Skip to main content Skip to navigation
Getting Started

Add doc pages and link between them

Build out a Guides area with two content pages, wire sibling navigation, hub-style absolute links, and rename-safe uid cross-references.

By the end of this tutorial the Guides area has two new pages — install.md and configure.md — wired into the sidebar in order: sequence, cross-linked with relative paths, and reachable from a hub index.md that uses both absolute paths and a uid:-based xref: link.

Prerequisites

  • .NET 10 SDK installed
  • Completed Scaffold a DocSite (or have a DocSite project with a Content/guides/ folder ready — this tutorial adds pages to it)

The finished code for this tutorial lives in examples/DocSitePagesAndLinksExample.


1. Add two content pages

Let's drop two markdown files into the Guides area and watch them slot into the sidebar. The pages stand alone for now — linking arrives in the next unit.

1

Create Content/guides/install.md

Add a new file at Content/guides/install.md with the markdown below. The four front-matter keys are the ones DocSiteFrontMatter reads for sidebar wiring: title is the link label, description becomes the meta tag, sectionLabel carries through to breadcrumbs and prev/next chrome, and order decides where the page sorts among siblings.

markdown
---
title: Install Pennington
description: Add the Pennington DocSite package and wire AddDocSite + UseDocSite into a fresh ASP.NET host.
sectionLabel: Guides
order: 20
---
  
# Install Pennington
  
Install Pennington into an ASP.NET project with one NuGet package and three lines of DI wiring.
  
## 1. Add the package
  
```bash
dotnet add package Pennington.DocSite
```
  
## 2. Wire DocSite in `Program.cs`
  
Three calls — register the services, mount the middleware, hand control to the host:
  
```csharp
builder.Services.AddDocSite(() => new DocSiteOptions { /* ... */ });
app.UseDocSite();
await app.RunDocSiteAsync(args);
```
  
The host is now ready for content. Drop markdown files under `Content/guides/` and they appear in the sidebar on the next request.
2

Create Content/guides/configure.md

Add a second file next to the first with the markdown below. Note order: 30 — a larger number than install's order: 20, so configure sorts after install in the sidebar.

markdown
---
title: Configure the site
description: Pick a site title, set the GitHub link, and decide on a single area or multiple.
sectionLabel: Guides
order: 30
---
  
# Configure the site
  
`DocSiteOptions` is the one options record `AddDocSite` reads. Set the fields that surface in the rendered chrome and the rest of the template falls into place.
  
## Fields worth setting first
  
- `SiteTitle` — appears in the header and the `<title>` tag.
- `Description` — meta description used in search snippets and social cards.
- `GitHubUrl` — surfaces the GitHub icon in the header.
- `HeaderContent` / `FooterContent` — raw HTML slots, useful for a logo and a copyright line.
  
## Areas — one or many?
  
`Areas` is an `IReadOnlyList<ContentArea>`. One entry is enough to ship; more entries turn on the area selector and split the sidebar by top-level folder. Stick with a single area until the content outgrows it.

For deeper coverage of section grouping and order: strategy, see Organize content with sections and areas.

Checkpoint

  • Run dotnet run and visit http://localhost:5000/guides/install — the Install Pennington page renders.
  • Visit http://localhost:5000/guides/configure — the Configure the site page renders.
  • The Guides sidebar lists both new pages, with Install Pennington above Configure the site (sorted by order:).

Both pages exist but neither knows about the other. Adding a relative-path link at the bottom of each one creates a natural "previous / next" flow without hardcoding the area slug.

1

Add a "Next" footer to install.md

Append a ## Next heading and a relative-path link to the bottom of install.md. ./configure resolves against the current page's URL (/guides/install), so it points at /guides/configure no matter where the area sits.

markdown
---
title: Install Pennington
description: Add the Pennington DocSite package and wire AddDocSite + UseDocSite into a fresh ASP.NET host.
sectionLabel: Guides
order: 20
---
  
# Install Pennington
  
Install Pennington into an ASP.NET project with one NuGet package and three lines of DI wiring.
  
## 1. Add the package
  
```bash
dotnet add package Pennington.DocSite
```
  
## 2. Wire DocSite in `Program.cs`
  
Three calls — register the services, mount the middleware, hand control to the host:
  
```csharp
builder.Services.AddDocSite(() => new DocSiteOptions { /* ... */ });
app.UseDocSite();
await app.RunDocSiteAsync(args);
```
  
The host is now ready for content. Drop markdown files under `Content/guides/` and they appear in the sidebar on the next request.
  
## Next
  
Pick a site title and decide on areas in [Configure the site](./configure).
2

Add a "Previously" footer to configure.md

Mirror the same shape on configure.md with a ./install link back to the first page. Both pages now link to their sibling with a path that survives any move of the Content/guides/ folder.

markdown
---
title: Configure the site
description: Pick a site title, set the GitHub link, and decide on a single area or multiple.
sectionLabel: Guides
order: 30
---
  
`DocSiteOptions` is the one options record `AddDocSite` reads. Set the fields that surface in the rendered chrome and the rest of the template falls into place.
  
## Fields worth setting first
  
- `SiteTitle` — appears in the header and the `<title>` tag.
- `Description` — meta description used in search snippets and social cards.
- `GitHubUrl` — surfaces the GitHub icon in the header.
- `HeaderContent` / `FooterContent` — raw HTML slots, useful for a logo and a copyright line.
  
## Areas — one or many?
  
`Areas` is an `IReadOnlyList<ContentArea>`. One entry is enough to ship; more entries turn on the area selector and split the sidebar by top-level folder. Stick with a single area until the content outgrows it.
  
## Previously
  
[Install Pennington](./install) covered getting the package and wiring in place.

Checkpoint

  • Reload http://localhost:5000/guides/install — a Configure the site link sits at the bottom of the page. Click it.
  • The browser lands on /guides/configure. A Install Pennington link at the bottom of that page returns to the first.
  • View source on either page: the relative ./configure and ./install markdown links rendered as href="/guides/configure" and href="/guides/install".

3. Turn the index into a hub with absolute paths

The Content/guides/index.md page from the scaffold still says "Walkthroughs and how-tos live in this folder" — a placeholder that no longer matches the content under it. Let's rewrite it as a hub that links to both pages with absolute paths.

1

Replace index.md with the hub markdown below

Absolute paths (/guides/install) survive folder moves of the source page. For the full link-form rundown, see Link between pages without hardcoding URLs.

markdown
---
title: Guides
description: Onboarding walkthroughs for a fresh Pennington DocSite.
sectionLabel: Guides
order: 10
---
  
# Guides
  
Two short walkthroughs cover the path from empty project to running site.
  
- [Install Pennington](/guides/install) — add the package and wire `AddDocSite`.
- [Configure the site](/guides/configure) — set the site title, GitHub link, and areas.

Checkpoint

  • Visit http://localhost:5000/guides/ — the Guides landing page now lists the two walkthroughs.
  • Click Install Pennington — the browser navigates to /guides/install.
  • Click Configure the site — the browser navigates to /guides/configure.

Absolute paths break the moment the target file moves or gets renamed. A uid: declared in the page's front matter gives the page a stable identifier; xref: links resolve through it, so the link survives the file moving or even the URL changing.

1

Add uid: guides.install to install.md's front matter

Open install.md and add one front-matter key — the page is now reachable by xref:guides.install no matter where the file lives.

markdown
---
title: Install Pennington
description: Add the Pennington DocSite package and wire AddDocSite + UseDocSite into a fresh ASP.NET host.
uid: guides.install
sectionLabel: Guides
order: 20
---
  
Install Pennington into an ASP.NET project with one NuGet package and three lines of DI wiring.
  
## 1. Add the package
  
```bash
dotnet add package Pennington.DocSite
```
  
## 2. Wire DocSite in `Program.cs`
  
Three calls — register the services, mount the middleware, hand control to the host:
  
```csharp
builder.Services.AddDocSite(() => new DocSiteOptions { /* ... */ });
app.UseDocSite();
await app.RunDocSiteAsync(args);
```
  
The host is now ready for content. Drop markdown files under `Content/guides/` and they appear in the sidebar on the next request.
  
## Next
  
Pick a site title and decide on areas in [Configure the site](./configure).
2

Swap the install link in index.md to use xref:

Open index.md and replace /guides/install with xref:guides.install. The configure link stays as an absolute path — handy for seeing both forms side by side in the rendered output.

markdown
---
title: Guides
description: Onboarding walkthroughs for a fresh Pennington DocSite.
sectionLabel: Guides
order: 10
---
  
Two short walkthroughs cover the path from empty project to running site.
  
- [Install Pennington](xref:guides.install) — add the package and wire `AddDocSite`.
- [Configure the site](/guides/configure) — set the site title, GitHub link, and areas.

Checkpoint

  • Reload http://localhost:5000/guides/ — both links in the hub still work. The rendered <a> for Install Pennington points at /guides/install just as the absolute-path version did.
  • View source: the xref:guides.install href has been rewritten to the canonical URL. The xref form is the same shape an editor would have produced — but the source markdown now survives any rename of install.md.

Summary

  • Two markdown files under Content/guides/ showed up in the sidebar without any extra wiring, sorted by order: from front matter.
  • Relative paths (./configure) link tightly coupled sibling pages — the form that survives area-folder renames.
  • Absolute paths (/guides/configure) link from a hub where the source page may move but the target's location is stable.
  • uid: plus xref: — the rename-safe form — turns the page identifier itself into the link target.
  • For the full link-form reference (anchors, assets, sub-path deployments), see Link between pages without hardcoding URLs. For deeper uid: semantics, see Cross-reference resolution.