-
-
Notifications
You must be signed in to change notification settings - Fork 1
Method Theme Classes
Create theme classes for a type-safe, object-oriented approach with full IDE support.
Theme classes are the recommended way to create custom themes. They provide the most powerful and flexible approach with compile-time safety, auto-discovery for theme switcher, and easy reusability across your application.
Tip
This is the recommended approach for production applications. Theme Classes offer all features of Embedded Files plus type-safety, flexible folder location, and automatic theme switcher discovery.
public class CustomTheme : Theme
{
protected CustomTheme(string fileName) : base(fileName)
{
}
public static CustomTheme Corporate => new("corporate.css");
public static CustomTheme Minimal => new("minimal.css");
}Unlike Embedded Files which require the SwaggerThemes folder, Theme Classes can be placed anywhere in your project. The only requirement is that the CSS file must be in the same folder as your theme class.
Example - Custom location:
YourProject/
├── Themes/ ← Any folder name works!
│ ├── CustomTheme.cs
│ ├── corporate.css
│ ├── corporate.min.css
│ ├── minimal.css
│ └── minimal.min.css
└── Program.cs
Tip
Key advantage over Embedded Files: You don't need to specify the assembly when using Theme Classes - the library automatically resolves it from the class. You also have complete freedom over folder naming and location.
Ensure CSS files are embedded in your .csproj. The path depends on where you placed your theme class and styles:
<ItemGroup>
<!-- If using custom folder (e.g., Themes/Styles/) -->
<EmbeddedResource Include="Themes\Styles\your-theme.css" />
<!-- If using SwaggerThemes folder -->
<EmbeddedResource Include="SwaggerThemes\your-theme.css" />
</ItemGroup>Tip
See Custom Themes - Organizing Your Themes for nested folder structure patterns and standalone variant setup.
// Simple usage
app.UseSwaggerUI(CustomTheme.Corporate, options => { });
// With advanced options
app.UseSwaggerUI(CustomTheme.Minimal, options =>
{
options.EnableAllAdvancedOptions();
});✅ No assembly required - Unlike Embedded Files, no need to pass Assembly.GetExecutingAssembly()
✅ Flexible location - Place themes anywhere, not limited to SwaggerThemes folder
✅ Type-safe - Compile-time checking prevents typos
✅ Reusable - Define once, use anywhere in your application
✅ All features available - Advanced options, CSS variables, theme switcher
✅ Organized - Clean, structured project layout
✅ Refactoring-friendly - Rename safely with IDE tools
You can use minified CSS files for better performance. The library does not automatically minify your CSS - you need to create minified versions yourself.
Creating minified files:
Use tools like:
-
csso-cli:
csso corporate.css -o corporate.min.css -
PostCSS + cssnano:
postcss corporate.css -o corporate.min.css --use cssnano - Online tools: CSS Minifier
Theme Classes provide a useMinified parameter to easily switch between regular and minified CSS files.
Use the useMinified parameter to control which CSS file is loaded:
public class CustomTheme : Theme
{
// Always use minified for a better performance
public CustomTheme() : base("my-theme.css", useMinified: true)
{
}
// No minification
public static CustomTheme Dev => new CustomTheme("my-theme.css", useMinified: false);
}// These load my-theme.min.css:
new CustomTheme("my-theme.css", useMinified: true)
new CustomTheme("my-theme.min.css", useMinified: true)
// These load my-theme.css:
new CustomTheme("my-theme.css", useMinified: false)
new CustomTheme("my-theme.min.css", useMinified: false)Note
The constructor automatically handles .min.css - just pass your base filename!
public class SmartTheme : Theme
{
public SmartTheme() : base("my-theme.css", useMinified: !Debugger.IsAttached)
{
// Uses .css when debugging, .min.css in production
}
}public class ProductionTheme : Theme
{
public ProductionTheme(IConfiguration config)
: base("my-theme.css", useMinified: config.GetValue<bool>("UseMinifiedAssets"))
{
}
}Important
Remember to generate and embed both .css and .min.css files when using minification. Only one version will be loaded based on the useMinified flag.
public class CompanyThemes : Theme
{
protected CompanyThemes(string fileName) : base(fileName)
{
}
public static CompanyThemes Light => new("light.css");
public static CompanyThemes Dark => new("dark.css");
public static CompanyThemes HighContrast => new("high-contrast.css");
}public class BrandTheme : Theme
{
private BrandTheme(string fileName, bool useMinified = true)
: base(fileName, useMinified)
{
}
// Production variants (minified)
public static BrandTheme Primary => new("brand-primary.css");
public static BrandTheme Secondary => new("brand-secondary.css");
// Development variants (non-minified)
public static BrandTheme PrimaryDev => new("brand-primary.css", useMinified: false);
public static BrandTheme SecondaryDev => new("brand-secondary.css", useMinified: false);
}public class EnvironmentTheme : Theme
{
private EnvironmentTheme(string fileName, bool useMinified)
: base(fileName, useMinified)
{
}
public static EnvironmentTheme ForEnvironment(string environment)
{
var isDev = environment.Equals("Development", StringComparison.OrdinalIgnoreCase);
return new EnvironmentTheme($"{environment.ToLower()}.css", useMinified: !isDev);
}
}
// Usage:
app.UseSwaggerUI(EnvironmentTheme.ForEnvironment(env.EnvironmentName), options => { });Theme classes are automatically discovered by the Dynamic Theme Switcher:
How It Works:
public class CompanyThemes : Theme
{
protected CompanyThemes(string fileName) : base(fileName) { }
public static CompanyThemes Corporate => new("corporate.css"); // ✅ Discovered
public static CompanyThemes Tech => new("tech.css"); // ✅ Discovered
public static CompanyThemes Minimal => new("minimal.css"); // ✅ Discovered
}
// All static properties are auto-discovered
app.UseSwaggerUI(CompanyThemes.Corporate, options =>
{
options.EnableThemeSwitcher(); // Shows Corporate, Tech, Minimal
});Display Names: Property names are used as display names:
-
Corporate→ "Corporate" -
Tech→ "Tech" -
DarkMode→ "Dark Mode"
Custom Configuration:
app.UseSwaggerUI(CompanyThemes.Corporate, options =>
{
options.EnableThemeSwitcher(new ThemeSwitcherOptions()
.WithThemes(
CompanyThemes.Corporate,
CompanyThemes.Tech
)
.ExcludeThemes(CompanyThemes.Minimal));
});Learn more about theme switcher configuration.
// Good
public static CustomTheme Corporate => new("corporate.css");
// Avoid
var theme = new CustomTheme("corporate.css");public class AppThemes : Theme
{
protected AppThemes(string fileName) : base(fileName) { }
// Customer-facing themes
public static AppThemes Customer => new("customer.css");
// Admin panel themes
public static AppThemes Admin => new("admin.css");
// Developer documentation themes
public static AppThemes Docs => new("docs.css");
}public class BrandTheme : Theme
{
protected BrandTheme(string fileName) : base(fileName) { }
public static BrandTheme V1 => new("brand-v1.css");
public static BrandTheme V2 => new("brand-v2.css");
public static BrandTheme Latest => V2;
}/// <summary>
/// Official company branding themes for Swagger UI.
/// These themes must match the design system defined in our brand guidelines.
/// </summary>
public class OfficialThemes : Theme
{
protected OfficialThemes(string fileName) : base(fileName) { }
/// <summary>
/// Primary brand theme - use for customer-facing APIs
/// </summary>
public static OfficialThemes Primary => new("primary.css");
/// <summary>
/// Internal theme - use for internal/admin APIs
/// </summary>
public static OfficialThemes Internal => new("internal.css");
}- View CSS Variables - Customize your theme styles
- Enable Advanced Options - Add interactive features
- Enable Theme Switcher - Let users choose themes at runtime
- Use Embedded Files - Alternative approach with nested folder support
- Create Standalone Themes - Full control
🚀 Getting Started
✨ Features
📖 Migration Guides