Tutorials
This guide covers all configuration options for Agility CMS .NET applications, including API settings, caching, environment variables, and multi-locale support.
This guide covers all configuration options for Agility CMS .NET applications, including API settings, caching, environment variables, and multi-locale support.
The main configuration file with default settings:
{
"AppSettings": {
"InstanceGUID": "",
"SecurityKey": "",
"FetchAPIKey": "",
"PreviewAPIKey": "",
"Locales": "en-us",
"ChannelName": "website",
"CacheInMinutes": 5
},
"CacheControl": {
"MaxAgeSeconds": 30,
"StaleWhileRevalidateSeconds": 86400,
"StaleIfErrorSeconds": 86400
}
}
Local development credentials (gitignored):
{
"AppSettings": {
"InstanceGUID": "your-instance-guid",
"SecurityKey": "your-security-key",
"FetchAPIKey": "defaultlive.your-fetch-key",
"PreviewAPIKey": "defaultpreview.your-preview-key"
}
}
Development-specific overrides:
{
"DetailedErrors": true,
"AppSettings": {
"CacheInMinutes": 0
}
}
| Setting | Description | Example |
|---|---|---|
InstanceGUID | Your Agility CMS instance identifier | abc123-def456-... |
SecurityKey | Used for preview mode authentication | MySecretKey123 |
FetchAPIKey | API key for published content | defaultlive.abc... |
PreviewAPIKey | API key for draft content | defaultpreview.xyz... |
| Setting | Default | Description |
|---|---|---|
Locales | en-us | Comma-separated locale codes |
ChannelName | website | Agility CMS sitemap channel |
CacheInMinutes | 5 | Server-side cache duration |
WebsiteName | - | Site name for display |
defaultlivedefaultpreviewControl CDN caching behavior with stale-while-revalidate headers:
| Setting | Default | Description |
|---|---|---|
MaxAgeSeconds | 30 | How long CDN serves fresh content |
StaleWhileRevalidateSeconds | 86400 | Serve stale while revalidating (1 day) |
StaleIfErrorSeconds | 86400 | Serve stale if origin is down (1 day) |
Cache-Control: public, max-age=30, stale-while-revalidate=86400, stale-if-error=86400
CDN cache headers are automatically disabled for:
For production deployments (Azure, Docker, etc.), use environment variables instead of config files.
Use double underscores (__) for nested properties:
AppSettings__InstanceGUID=your-guid
AppSettings__SecurityKey=your-key
AppSettings__FetchAPIKey=defaultlive.your-key
AppSettings__PreviewAPIKey=defaultpreview.your-key
AppSettings__Locales=en-us,fr-ca
AppSettings__ChannelName=website
AppSettings__CacheInMinutes=5
CacheControl__MaxAgeSeconds=30
CacheControl__StaleWhileRevalidateSeconds=86400
CacheControl__StaleIfErrorSeconds=86400
az webapp config appsettings set \
--name your-app-name \
--resource-group your-resource-group \
--settings \
AppSettings__InstanceGUID=your-guid \
AppSettings__SecurityKey=your-key \
AppSettings__FetchAPIKey=defaultlive.your-key \
AppSettings__PreviewAPIKey=defaultpreview.your-key
ENV AppSettings__InstanceGUID=your-guid
ENV AppSettings__SecurityKey=your-key
ENV AppSettings__FetchAPIKey=defaultlive.your-key
ENV AppSettings__PreviewAPIKey=defaultpreview.your-key
Or with docker-compose:
services:
web:
environment:
- AppSettings__InstanceGUID=your-guid
- AppSettings__SecurityKey=your-key
- AppSettings__FetchAPIKey=defaultlive.your-key
- AppSettings__PreviewAPIKey=defaultpreview.your-key
Specify supported locales as a comma-separated list:
{
"AppSettings": {
"Locales": "en-us,fr-ca,es-mx"
}
}
The starters detect locale from:
/fr-ca/about uses fr-ca locale// Fetch content for a specific locale
var posts = await _fetchApi.GetTypedContentList<Post>(
referenceName: "posts",
locale: "fr-ca", // French Canadian
take: 10
);
Implement locale switching in your header:
@foreach (var locale in Locales)
{
<a href="/@locale@CurrentPath"
class="@(locale == CurrentLocale ? "active" : "")">
@GetLocaleDisplayName(locale)
</a>
}
The CacheInMinutes setting controls how long API responses are cached in memory:
| Environment | Recommended Value |
|---|---|
| Development | 0 (disabled) |
| Staging | 1-2 |
| Production | 5-10 |
{
"AppSettings": {
"CacheInMinutes": 5
}
}
Configure webhooks in Agility CMS to invalidate cache on publish:
https://your-site.com/api/revalidatehttps://your-site.com/page-path?agilitypreviewkey=HASH
The agilitypreviewkey is generated from your SecurityKey.
https://your-site.com{path}?agilitypreviewkey={previewkey}
public static bool ValidatePreviewKey(string key, string securityKey)
{
using var sha256 = SHA256.Create();
var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(securityKey));
var expectedKey = Convert.ToBase64String(hash);
return key == expectedKey;
}
var builder = WebApplication.CreateBuilder(args);
// Access configuration
var instanceGuid = builder.Configuration["AppSettings:InstanceGUID"];
var locales = builder.Configuration["AppSettings:Locales"]?.Split(',') ?? new[] { "en-us" };
// Bind to strongly-typed options
builder.Services.Configure<AppSettings>(
builder.Configuration.GetSection("AppSettings"));
public class MyService
{
private readonly AppSettings _settings;
public MyService(IOptions<AppSettings> options)
{
_settings = options.Value;
}
public string GetInstanceGuid() => _settings.InstanceGUID;
}
@inject IOptions<AppSettings> AppSettings
@code {
private string InstanceGuid => AppSettings.Value.InstanceGUID;
}
public class AppSettings
{
public string InstanceGUID { get; set; } = "";
public string SecurityKey { get; set; } = "";
public string FetchAPIKey { get; set; } = "";
public string PreviewAPIKey { get; set; } = "";
public string Locales { get; set; } = "en-us";
public string ChannelName { get; set; } = "website";
public int CacheInMinutes { get; set; } = 5;
public string? WebsiteName { get; set; }
public string[] GetLocales() => Locales.Split(',', StringSplitOptions.RemoveEmptyEntries);
public string DefaultLocale => GetLocales().FirstOrDefault() ?? "en-us";
}
public class CacheControl
{
public int MaxAgeSeconds { get; set; } = 30;
public int StaleWhileRevalidateSeconds { get; set; } = 86400;
public int StaleIfErrorSeconds { get; set; } = 86400;
}
appsettings.local.json for local development (gitignored)Ensure your .gitignore includes:
appsettings.local.json
appsettings.*.local.json
*.local.json
For enhanced security, use Azure Key Vault:
builder.Configuration.AddAzureKeyVault(
new Uri($"https://{keyVaultName}.vault.azure.net/"),
new DefaultAzureCredential()
);
appsettings.local.json existsCacheInMinutes > 0SecurityKey matches Agility settings