Skip to content

Getting Started

bekov0004 edited this page Sep 28, 2026 · 2 revisions

Getting Started

Installation

dotnet add package Folio.AspNetCore

Supports .NET 6, 7, 8, and 9.

Pointing Folio at your OpenAPI document

The package doesn't care how you generate your OpenAPI document — it just renders whatever you point it at via SpecUrl. Any source works.

Built-in Microsoft.AspNetCore.OpenApi (.NET 9+)

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi(); // publishes /openapi/v1.json

app.UseFolio(options =>
{
    options.RoutePrefix = "docs";           // UI will be at /docs
    options.SpecUrl     = "/openapi/v1.json";
    options.Title       = "My API";          // optional
});

app.Run();

Swashbuckle

builder.Services.AddSwaggerGen();
// ...
app.UseSwagger(); // publishes /swagger/v1/swagger.json

app.UseFolio(options =>
{
    options.SpecUrl = "/swagger/v1/swagger.json";
});

NSwag or a static file

Same idea — point SpecUrl at whatever URL serves your OpenAPI JSON.

What you get

Open /folio (or your configured RoutePrefix):

  • Endpoint list and model schema catalog, generated from the spec.
  • A type-aware request builder for parameters and request bodies.
  • In-browser request execution, with generated code snippets (cURL, JavaScript, Python, C#, Go, PowerShell).
  • Environment support (switch base URLs without editing anything).
  • Authorization against the spec's declared security schemes (apiKey, HTTP Bearer/Basic).
  • Dark mode, instant search, saved examples, shareable deep links.

FolioOptions reference

Property Default Description
RoutePrefix "folio" Path the UI is served under (no leading/trailing slashes).
SpecUrl "/openapi/v1.json" URL of the OpenAPI document — required for a real project.
Title null Page/header title. Falls back to the spec's info.title if not set.
AuthorizationPolicy null Name of an ASP.NET Core authorization policy the UI is gated behind. See Authorization.
LogoutUrl null Shows a "Log out" button in the header, pointing here. Hidden if unset.
ShowTryItOut true Shows the "Send request" button that executes real requests against your API.
ShowRoles true Shows the role badges/popover read from your endpoints' own [Authorize(Roles = "...")]. See Features.
ShowCodeGenerator true Shows the multi-language code generator (cURL/JS/Python/C#/Go/PowerShell).
ShowSchema true Shows the Schema button for viewing a model's JSON schema.
ShowHome true Shows the "Home" button (returns to the welcome screen).
ShowEnvironmentSwitcher true Shows the environment/base-URL switcher.
ShowGlobalHeaders true Shows the "Global headers" button.
ShowAuthorize true Shows the OpenAPI security scheme "Authorization" button, when the spec declares one.
ShowExamples true Shows "Save example" / "My examples".
ShowShare true Shows the "Copy endpoint link" button.

Controlling which UI elements show

Every ShowXxx flag above can be set directly in code:

app.UseFolio(options =>
{
    options.SpecUrl = "/openapi/v1.json";
    options.ShowTryItOut = false;       // e.g. a read-only docs deployment
    options.ShowCodeGenerator = false;
});

...or bound from appsettings.json (or any other IConfiguration source). Folio never reads configuration on its own — you opt in explicitly, the same way Serilog's ReadFrom.Configuration(...) works:

{
  "Folio": {
    "ShowTryItOut": false,
    "ShowCodeGenerator": false
  }
}
app.UseFolio((context, options) =>
{
    options.SpecUrl = "/openapi/v1.json";
    options.ReadFrom.Configuration(context.Configuration, "Folio");
});

Both paths write to the same options, so you can combine them — config as the base, with specific values overridden in code afterward (or vice versa, depending on call order). There's no built-in dev/prod switch inside Folio itself; if you want different values per environment, use ASP.NET Core's own appsettings.{Environment}.json layering — the code above stays identical on every environment.

How it works

The UI (HTML/CSS/JS) is embedded into the package assembly as embedded resources and served through the standard StaticFileMiddleware on top of a ManifestEmbeddedFileProvider — with proper ETag/Last-Modified/conditional requests, not hand-rolled file serving. index.html is served by a small dedicated handler that injects configuration (SpecUrl, Title, ...) into a <script> tag on the fly before the rest of the scripts load — the UI itself hardcodes nothing and works with whatever OpenAPI document you point it at.

Fully offline: fonts, Tailwind CSS, marked.js, and flatpickr are all bundled locally and embedded into the package assembly — zero external requests, both at build time and in the user's browser.

Clone this wiki locally