Configure Osirion.Blazor
This guide shows where each Osirion setting lives, how to set it in appsettings.json or in code, how to vary it per
environment, and where secrets such as a GitHub token belong. It is for developers who have installed the packages.
Before you start
- Osirion.Blazor is installed and
AddOsirionis registered, as in the installation guide. - This guide is written for Osirion.Blazor 4.1.0. One key,
Osirion:Seo:SiteUrl, arrives in the release after 4.1.0 and is marked where it appears.
1. Know the sections
Everything binds from the Osirion section. AddOsirion(builder.Configuration) configures a module only when its
section exists, so a site that sets nothing for a module gets that module's defaults.
| Section | Bound to | Read about it |
|---|---|---|
Osirion:Site |
OsirionSiteOptions: name, menu, footer, social links, announcement |
OsirionSiteLayout |
Osirion:Theming |
ThemingOptions: Framework, DefaultMode, DefaultPalette, AllowPaletteSelection, UseDefaultStyles, CustomVariables |
Theming |
Osirion:Cms:Web:FileSystem |
FileSystemOptions: one local folder |
Content providers |
Osirion:Cms:Web:GitHub:<Name> |
GitHubOptions: one provider per child key |
Content providers |
Osirion:Seo |
SeoMetadataOptions: SiteName, SiteDescription, SiteLogoUrl, AllowSearchIndexing and more |
SeoMetadataRenderer |
Osirion:Email |
EmailOptions: Provider, ToEmail, and a subsection each for Smtp, SendGrid and Infobip |
Contact form |
Osirion:Analytics:<Service> |
One options class per service: Clarity, Matomo, GA4, YandexMetrica, Plausible, Umami |
Analytics |
Osirion:Analytics:Consent |
AnalyticsConsentOptions: RequireConsent, Category |
Analytics |
Osirion:Navigation:Enhanced |
EnhancedNavigationOptions |
Navigation |
Osirion:Navigation:ScrollToTop |
ScrollToTopOptions |
Navigation |
The sitemap and feeds are not under Osirion. MapOsirionFeeds takes its own options object, and the templates fill
it from a top-level Feeds section that their Program.cs binds. The deployment guide shows how.
2. Configure in appsettings.json
A small site that reads Markdown from a folder, uses Osirion's own colors and renders its shell with
OsirionSiteLayout:
{
"Osirion": {
"Theming": {
"Framework": "None",
"DefaultMode": "System"
},
"Site": {
"Name": "My Blog",
"Menu": [
{ "Text": "Blog", "Href": "/blog", "MatchPrefix": true },
{ "Text": "About", "Href": "/about" }
]
},
"Cms": {
"Web": {
"FileSystem": {
"BasePath": "content",
"IsDefault": true
}
}
},
"Seo": {
"SiteName": "My Blog",
"SiteDescription": "Notes, guides and ideas, written in Markdown."
}
}
}
Key names are not case sensitive, as with any ASP.NET Core configuration. A key that matches no property is ignored without a message, so check a new key by looking at its effect.
Osirion:Seo:SiteUrl names the site's public address. When it is an absolute http or https address, the canonical
URL, og:url and the addresses in structured data use it instead of the host that served the request. The sitemap and
the feeds use it too when Feeds:SiteUrl is not set. It arrives in the release after 4.1.0.
3. Configure in code
Two ways, depending on whether the values come from appsettings.json too.
To set everything in code, call the overload of AddOsirion that takes a builder. It does not read the Osirion
section; each module takes the values you set in the delegate:
using Osirion.Blazor.Components;
using Osirion.Blazor.Extensions;
using Osirion.Blazor.Options;
builder.Services.AddOsirion(osirion => osirion
.UseTheming(theming => theming
.UseFramework(CssFramework.Bootstrap)
.Configure(options => options.DefaultMode = ThemeMode.Dark))
.UseSeoMetadata(seo => seo.SiteName = "My Blog")
.UseSite(site =>
{
site.Name = "My Blog";
site.Menu.Add(new SiteMenuItem { Text = "Blog", Href = "/blog" });
})
.UseContent(content => content.AddFileSystem(files =>
{
files.BasePath = "content";
files.IsDefault = true;
})));
In this form the content builder offers AddFileSystem for a local folder. It starts from the
Osirion:Cms:Web:FileSystem section when that exists, then runs your delegate. The named GitHub providers under
Osirion:Cms:Web:GitHub are registered only by AddOsirion(builder.Configuration), so a site with a GitHub provider
uses the configuration overload (see Content providers).
To keep appsettings.json and still change one value in code, register with AddOsirion(builder.Configuration) and
then use the options pipeline. PostConfigure runs after every other registration, so it has the last word:
using Osirion.Blazor.Cms.Domain.Options;
using Osirion.Blazor.Components;
using Osirion.Blazor.Extensions;
builder.Services.AddOsirion(builder.Configuration);
builder.Services.PostConfigure<FileSystemOptions>(options =>
options.BasePath = Path.GetFullPath(options.BasePath, builder.Environment.ContentRootPath));
builder.Services.PostConfigure<ThemingOptions>(options => options.DefaultMode = ThemeMode.Dark);
The first PostConfigure is the one the templates use: it turns a relative BasePath into an absolute path under the
host's content root and leaves an absolute path as it is. The content root is the folder the process starts in, so this
does not make the path independent of the starting folder; the providers guide says what does.
4. Vary settings per environment
ASP.NET Core reads appsettings.json first, then appsettings.{Environment}.json, where the environment comes from
ASPNETCORE_ENVIRONMENT (Development under dotnet run with the default launch profile, Production when it is
unset). A later file overrides only the keys it contains.
A site that reads a local folder while you write and a GitHub repository in production keeps neither provider in
appsettings.json. appsettings.Development.json:
{
"Osirion": {
"Cms": {
"Web": {
"FileSystem": {
"BasePath": "content",
"IsDefault": true
}
}
}
}
}
appsettings.Production.json:
{
"Osirion": {
"Cms": {
"Web": {
"GitHub": {
"Blog": {
"Owner": "your-account",
"Repository": "your-content-repository",
"Branch": "main",
"ContentPath": "content",
"IsDefault": true
}
}
}
}
}
}
Providers are registered from whatever sections exist, so each environment gets exactly one.
5. Keep secrets out of appsettings.json
These keys are secrets. They never belong in a file under source control:
| Key | Holds |
|---|---|
Osirion:Cms:Web:GitHub:<Name>:ApiToken |
The GitHub token the provider reads the repository with |
Osirion:Cms:Web:GitHub:<Name>:WebhookSecret |
The secret that signs GitHub webhook deliveries |
Osirion:Email:Smtp:Password |
The SMTP password |
Osirion:Email:SendGrid:ApiKey, Osirion:Email:Infobip:ApiKey |
Email service API keys |
In development, use user secrets. They live in your user profile, outside the project:
dotnet user-secrets init
dotnet user-secrets set "Osirion:Cms:Web:GitHub:Blog:ApiToken" "<your token>"
User secrets are loaded only when the environment is Development. In production, use environment variables. An
environment variable name writes the key path with a double underscore where the key has a colon, so the same token
is:
export Osirion__Cms__Web__GitHub__Blog__ApiToken="<your token>"
In PowerShell:
$env:Osirion__Cms__Web__GitHub__Blog__ApiToken = "<your token>"
List items take their index as a path segment, for example Osirion__Site__Menu__0__Text. Environment variables
override both JSON files and user secrets, so a value set on the host wins over the same key in a file. A secret store
that your host maps to environment variables works the same way.
6. Know what is checked at startup
Only some options are validated, and each fails differently:
Osirion:Siteis validated when the application starts. A site without aName, or a menu item without aText, anHrefor childItems, stops startup with anOptionsValidationExceptionwhose messages name the key, for exampleOsirion:Site:Name is required.- Each analytics service under
Osirion:Analyticsis validated at startup when it is enabled, for example a GA4MeasurementIdthat does not look likeG-XXXXXXXXXX. - The feed options are checked when
MapOsirionFeedsruns: aSiteUrlthat is not an absolutehttporhttpsaddress throwsArgumentException. - Content providers, theming, SEO and email are not validated. A missing GitHub token, for instance, shows up as a logged error when content is first requested, not as a startup failure. The providers guide says what you see.
Check that it works
Start the app and look at the effect of one key from each section you set. A wrong Osirion:Site value fails
immediately with the message above. For the others, an unchanged page after you set a key usually means the key path is
misspelled, or an environment variable or user secret with a different value overrides it. To see the value the app
resolved, inject IOptions<T> for the options class in the table, for example IOptions<ThemingOptions>, and read its
Value.
Next steps
- Content providers: the
Osirion:Cmskeys and their defaults. - Deployment: what a deployed site needs in its environment.
- Theming: every
Osirion:Themingoption. - Analytics: the services under
Osirion:Analytics.