Lunet generates .NET API pages from one or more .csproj files with api.dotnet.
config.scriban)with api.dotnet
title = "MyProject API Reference"
path = "/api"
menu_name = "api"
menu_title = "API Reference"
config = "Release"
properties = { TargetFramework: "net10.0" }
projects = [
{ name: "MyProject", path: "../src/MyProject/MyProject.csproj" }
]
end
This generates API pages under path (default /api) and registers all API UIDs for xref: links.
For a local sample API that you only want during lunet serve/--dev, wrap it with:
if environment == "dev"
with api.dotnet
# sample/local API config
end
end
| Property | Type | Default | Description |
|---|---|---|---|
api.dotnet.title |
string | "<site title> .NET API Reference" |
Title of the generated API root page |
api.dotnet.path |
string | "/api" |
Root URL/path for generated API pages |
api.dotnet.menu_name |
string | "api" |
Menu name exposed on site.menu.<name> |
api.dotnet.menu_title |
string | api.dotnet.title |
Root menu title |
api.dotnet.menu_width |
int | 4 |
Sidebar width hint for this menu |
api.dotnet.max_slug_length |
int | 96 |
Maximum URL slug length for generated member/namespace pages; long UIDs are shortened with a stable hash suffix |
api.dotnet.config |
string | "Release" |
Build configuration passed to dotnet build |
api.dotnet.properties |
object | empty | Extra MSBuild properties (-p:), e.g. TargetFramework |
api.dotnet.projects |
array | required | Projects to extract (string or object entries) |
api.dotnet.references |
array |
empty | Referenced assemblies to include for all projects |
api.dotnet.kind_icons |
object | built-in icon map | Optional icon overrides by API kind (Class, Struct, Method, Extension, default, …). Value can be a Bootstrap icon class ("bi-lightning-charge") or raw <i> HTML |
api.dotnet.external_apis |
object/array | empty | Maps external UIDs (usually assembly/namespace prefixes) to another Lunet API base URL for cross-site xref links |
api.dotnet.include_helper |
string | empty | Optional additional helper include loaded for generated API pages (built-in helpers are implemented in C#) |
api.dotnet.layout |
string | "_default" |
Base layout used by generated API pages |
api.dotnet.table_class |
string | "api-dotnet-members list-group list-group-flush" |
CSS classes used by default API member lists. Can also be overridden via members_class |
Project entry object:
| Key | Type | Required | Description |
|---|---|---|---|
name |
string | no | Logical project name (cache id). Defaults to project filename |
path |
string | yes | Path to a .csproj (or glob pattern) |
properties |
object | no | Per-project MSBuild properties (override api.dotnet.properties) |
references |
array |
no | Per-project referenced assemblies to include |
api.dotnet.external_apis accepts:
{ uid_prefix, url, max_slug_length? } (or assembly instead of uid_prefix)Example:
with api.dotnet
external_apis = [
{ assembly: "XenoAtom.Terminal", url: "https://xenoatom.github.io/terminal/api" }
{ assembly: "XenoAtom.Terminal.UI", url: "https://xenoatom.github.io/terminal/api" }
{ assembly: "XenoAtom.Ansi", url: "https://xenoatom.github.io/terminal/api" }
]
end
When an unresolved xref UID matches a configured prefix, Lunet builds a remote URL using the same Lunet API slug algorithm (max_slug_length defaults to local api.dotnet.max_slug_length) and links to that remote page.
Lunet creates dynamic pages:
<path>/ with layout_type = "api-dotnet" (API root)<path>/<namespace-uid>/ with layout_type = "api-dotnet-namespace"<path>/<member-uid>/ with layout_type = "api-dotnet-member"For very long UIDs (common with large generic signatures), Lunet automatically shortens the page slug to stay filesystem-safe on Windows while keeping URLs deterministic.
Default templates:
src/Lunet.Api.DotNet/shared/.lunet/layouts/_default.api-dotnet.sbn-mdsrc/Lunet.Api.DotNet/shared/.lunet/layouts/_default.api-dotnet-namespace.sbn-mdsrc/Lunet.Api.DotNet/shared/.lunet/layouts/_default.api-dotnet-member.sbn-mdsrc/Lunet.Api.DotNet/shared/.lunet/includes/_builtins/api-dotnet-helpers.sbn-html (optional extension point)Override by adding files with the same names under site/.lunet/layouts or site/.lunet/includes.
By default, generated API lists use Bootstrap table classes (.table, .table-striped, .table-hover, .table-sm).
api.dotnet now builds a menu tree automatically:
menu_title)The generated menu is available as site.menu.<menu_name> and every API page receives:
page.menu_item (current menu node)page.menu (renderable menu root/subtree like normal menus)You can therefore render API menus with the same helpers as menu.yml menus.
Generated API menus include Bootstrap icon markup (bi-*) for namespaces, types, member groups, and members.
When using deep API trees, render with a higher menu depth (for example depth: 6) so namespace/type/member levels are visible.
You can reference the API root in menu.yml:
home:
- { path: readme.md, title: Home }
- { path: api/readme.md, title: API Reference, folder: true }
When folder: true, Lunet reuses the generated API hierarchy as children of this menu item.
This makes API navigation work without creating a dedicated api/menu.yml.
Root API page (api-dotnet):
api.namespaces -> namespace objectsapi.objects -> UID -> API object mapapi.references -> UID -> reference object mapNamespace page (api-dotnet-namespace) variable:
namespace (uid, name, summary, remarks, classes, structs, interfaces, enums, delegates)Member page (api-dotnet-member) variable:
member (uid, type, name, fullName, namespace, assemblies, summary, remarks, syntax, constructors, fields, properties, methods, events, operators, extensions, explicit_interface_implementation_methods)Global helper:
apiref "My.Namespace.Type" -> API object by UID (or null)Markdown:
See [NuGetVersion](xref:NuGet.Versioning.NuGetVersion).
DocFX-style inline:
<xref href="NuGet.Versioning.NuGetVersion"></xref>
Scriban:
{{ $link = "NuGet.Versioning.NuGetVersion" | xref }}
{{ if $link }}<a href="{{ $link.url }}">{{ $link.fullname }}</a>{{ end }}
Use references to include API from referenced assemblies (for example NuGet packages):
api.dotnet.references applies to all configured projectsprojects[i].references applies only to one projectIf XML docs are available for referenced assemblies, summaries and remarks are surfaced.
api.dotnet also merges extra Markdown docs into existing API UIDs.
Convention (automatic):
apidocs/ folder (<project>/apidocs/**/*.md)uid: <exact API uid># Summary, # Remarks, and optionally repeated # ExampleExample (src/MyProject/apidocs/MyCompany.MyProduct.md):
---
uid: MyCompany.MyProduct
---
# Summary
Namespace summary from Markdown.
# Remarks
Longer namespace remarks from Markdown.
The uid can target a namespace, type, or member. Content is merged into the generated model before rendering pages.
The Lunet docs site uses:
site/config.scriban -> api.dotnet configuration (enabled only when environment == "dev")src/Lunet.ApiExample/Lunet.ApiExample.csproj -> local sample project rendered under /apisrc/Lunet.ApiExample/apidocs/*.md -> namespace summary/remarks merged from Markdown (Lunet.ApiExample, Lunet.ApiExample.Advanced, Lunet.ApiExample.Http)allows ref struct, extension members, native/function pointer signatures)Public cross-site examples generated with Lunet:
site.api registryxref: link resolution in content pages