WebSpark.Bootswatch
1.34.0
dotnet add package WebSpark.Bootswatch --version 1.34.0
NuGet\Install-Package WebSpark.Bootswatch -Version 1.34.0
<PackageReference Include="WebSpark.Bootswatch" Version="1.34.0" />
<PackageVersion Include="WebSpark.Bootswatch" Version="1.34.0" />
<PackageReference Include="WebSpark.Bootswatch" />
paket add WebSpark.Bootswatch --version 1.34.0
#r "nuget: WebSpark.Bootswatch, 1.34.0"
#:package WebSpark.Bootswatch@1.34.0
#addin nuget:?package=WebSpark.Bootswatch&version=1.34.0
#tool nuget:?package=WebSpark.Bootswatch&version=1.34.0
WebSpark.Bootswatch
A .NET Razor Class Library that provides seamless integration of Bootswatch themes into ASP.NET Core applications. Built on Bootstrap 5, this library offers modern, responsive theming with dynamic theme switching, light/dark mode support, and comprehensive caching mechanisms.
Multi-Framework Support: Targets .NET 8.0 (LTS), .NET 9.0 (STS), and .NET 10.0 for maximum compatibility.
Latest Release: v1.34.0 - Demo site UI improvements for better theme visibility
๐ Quick Links
- ๐ฆ NuGet Package: WebSpark.Bootswatch
- ๐จ Demo Site: bootswatch.markhazleton.com
- ๐ Documentation: GitHub Wiki
- ๐ Issues: Report a Bug
โจ Features
- ๐จ Complete Bootswatch Integration: All official Bootswatch themes plus custom themes
- ๐ Light/Dark Mode Support: Automatic theme detection and switching
- โก High Performance: Built-in caching with
StyleCacheservice - ๐ง Easy Integration: Single-line setup with extension methods
- ๐ฑ Responsive Design: Mobile-first Bootstrap 5 foundation
- ๐ฏ Tag Helper Support:
<bootswatch-theme-switcher />for easy UI integration - ๐ Production Ready: Comprehensive error handling and fallback mechanisms
- ๐ Full Documentation: IntelliSense support and XML documentation
- ๐ Multi-Framework: Supports .NET 8.0 (LTS), 9.0 (STS), and 10.0
โ ๏ธ IMPORTANT: Required Dependencies
WebSpark.Bootswatch requires WebSpark.HttpClientUtility to be installed AND registered separately.
โ Quick Setup Checklist
Before starting, ensure you complete ALL of these steps:
- Install both packages:
WebSpark.BootswatchANDWebSpark.HttpClientUtility - Add both using statements to
Program.cs - Register
AddHttpClientUtility()BEFOREAddBootswatchThemeSwitcher() - Add required configuration to
appsettings.json - Use
UseBootswatchAll()BEFOREUseStaticFiles()in middleware pipeline
Missing any of these steps will cause runtime errors!
Common Setup Mistake
// โ WRONG - Missing HttpClientUtility registration
builder.Services.AddBootswatchThemeSwitcher();
// โ
CORRECT - HttpClientUtility registered first
using WebSpark.Bootswatch;
using WebSpark.HttpClientUtility;
builder.Services.AddHttpClientUtility(); // Must be FIRST
builder.Services.AddBootswatchThemeSwitcher(); // Then this
๐ Prerequisites
Framework Support
The library supports multiple .NET versions:
| Framework | Status | Support Level |
|---|---|---|
| .NET 8.0 | โ Supported | LTS (Long Term Support) |
| .NET 9.0 | โ Supported | STS (Standard Term Support) |
| .NET 10.0 | โ Supported | Current Release |
Your project can target any of these frameworks and will receive the appropriate version of the library.
Required Dependencies
<PackageReference Include="WebSpark.Bootswatch" Version="1.34.0" />
<PackageReference Include="WebSpark.HttpClientUtility" Version="2.1.1" />
Configuration Requirements
Add to your appsettings.json for dynamic theme fetching:
{
"CsvOutputFolder": "c:\\temp\\WebSpark\\CsvOutput",
"HttpRequestResultPollyOptions": {
"MaxRetryAttempts": 3,
"RetryDelaySeconds": 1,
"CircuitBreakerThreshold": 3,
"CircuitBreakerDurationSeconds": 10
}
}
๐ ๏ธ Installation
Package Manager Console
Install-Package WebSpark.Bootswatch
Install-Package WebSpark.HttpClientUtility
.NET CLI
dotnet add package WebSpark.Bootswatch
dotnet add package WebSpark.HttpClientUtility
PackageReference
<PackageReference Include="WebSpark.Bootswatch" Version="1.34.0" />
<PackageReference Include="WebSpark.HttpClientUtility" Version="2.1.1" />
The NuGet package automatically selects the correct assembly based on your project's target framework.
โก Quick Start
Step 1: Install BOTH Required Packages
# Install WebSpark.Bootswatch
dotnet add package WebSpark.Bootswatch
# Install REQUIRED dependency (NOT automatically installed)
dotnet add package WebSpark.HttpClientUtility
Verify Installation:
Your .csproj should now include BOTH packages:
<PackageReference Include="WebSpark.Bootswatch" Version="1.34.0" />
<PackageReference Include="WebSpark.HttpClientUtility" Version="2.1.1" />
Step 2: Add Required Configuration
Create or update appsettings.json:
{
"CsvOutputFolder": "c:\\temp\\WebSpark\\CsvOutput",
"HttpRequestResultPollyOptions": {
"MaxRetryAttempts": 3,
"RetryDelaySeconds": 1,
"CircuitBreakerThreshold": 3,
"CircuitBreakerDurationSeconds": 10
},
"BootswatchOptions": {
"DefaultTheme": "yeti",
"EnableCaching": true,
"CacheDurationMinutes": 60
}
}
Step 3: Configure Services in Program.cs
Add using statements at the top:
using WebSpark.Bootswatch;
using WebSpark.HttpClientUtility;
Register services in the correct order:
var builder = WebApplication.CreateBuilder(args);
// Add services
builder.Services.AddRazorPages();
builder.Services.AddHttpContextAccessor();
// โ ๏ธ CRITICAL: Register HttpClientUtility FIRST
builder.Services.AddHttpClientUtility();
// Then register Bootswatch theme switcher
builder.Services.AddBootswatchThemeSwitcher();
var app = builder.Build();
// Configure middleware pipeline
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// โ ๏ธ CRITICAL: UseBootswatchAll() must come BEFORE UseStaticFiles()
app.UseBootswatchAll();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Step 4: Update _ViewImports.cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, WebSpark.Bootswatch
Step 5: Update _Layout.cshtml
Add required using statements and inject StyleCache:
@using WebSpark.Bootswatch.Services
@using WebSpark.Bootswatch.Helpers
@inject StyleCache StyleCache
Update the HTML structure:
<!DOCTYPE html>
<html lang="en" data-bs-theme="@(BootswatchThemeHelper.GetCurrentColorMode(Context))">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"]</title>
@{
var themeName = BootswatchThemeHelper.GetCurrentThemeName(Context);
var themeUrl = BootswatchThemeHelper.GetThemeUrl(StyleCache, themeName);
}
<link id="bootswatch-theme-stylesheet" rel="stylesheet" href="@themeUrl" />
<script src="/_content/WebSpark.Bootswatch/js/bootswatch-theme-switcher.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" />
</head>
<body>
<nav class="navbar navbar-expand-lg">
<div class="container">
<a class="navbar-brand" href="/">My App</a>
<ul class="navbar-nav ms-auto">
<bootswatch-theme-switcher />
</ul>
</div>
</nav>
<main>
@RenderBody()
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Step 6: Verify Setup
Build and run your application:
dotnet build
dotnet run
Expected Results:
- โ Application starts without errors
- โ Theme switcher appears in navigation
- โ Default theme is applied
- โ Theme switching works
- โ Light/dark mode toggle functions
โ ๏ธ Common Errors & Solutions
Error: "Unable to resolve service for type 'IHttpRequestResultService'"
Full Error Message:
System.AggregateException: Some services are not able to be constructed
(Error while validating the service descriptor 'ServiceType: WebSpark.Bootswatch.Model.IStyleProvider
Lifetime: Scoped ImplementationType: WebSpark.Bootswatch.Provider.BootswatchStyleProvider':
Unable to resolve service for type 'WebSpark.HttpClientUtility.RequestResult.IHttpRequestResultService'
Cause: WebSpark.HttpClientUtility services are not registered.
Solution:
- Verify package is installed:
dotnet list package | findstr HttpClientUtility - Add using statement:
using WebSpark.HttpClientUtility; - Register services BEFORE Bootswatch:
using WebSpark.Bootswatch;
using WebSpark.HttpClientUtility;
builder.Services.AddHttpClientUtility(); // โ
Must be FIRST
builder.Services.AddBootswatchThemeSwitcher(); // โ
Then this
Error: "Themes not loading" or "404 errors for theme files"
Cause: Middleware is in wrong order.
Solution:
Ensure UseBootswatchAll() comes BEFORE UseStaticFiles():
// โ
CORRECT ORDER
app.UseBootswatchAll(); // First
app.UseStaticFiles(); // Then this
// โ WRONG ORDER (will fail)
app.UseStaticFiles();
app.UseBootswatchAll();
Error: "Configuration section not found"
Cause: Missing or incorrect appsettings.json configuration.
Solution:
Ensure ALL required sections are present in appsettings.json:
{
"CsvOutputFolder": "c:\\temp\\WebSpark\\CsvOutput",
"HttpRequestResultPollyOptions": {
"MaxRetryAttempts": 3,
"RetryDelaySeconds": 1,
"CircuitBreakerThreshold": 3,
"CircuitBreakerDurationSeconds": 10
}
}
Error: Theme switcher not visible
Cause: Tag helper not registered in _ViewImports.cshtml.
Solution:
Add to _ViewImports.cshtml:
@addTagHelper *, WebSpark.Bootswatch
๐ฏ Advanced Usage
StyleCache Service
public class HomeController : Controller
{
private readonly StyleCache _styleCache;
public HomeController(StyleCache styleCache)
{
_styleCache = styleCache;
}
public IActionResult Index()
{
// Get all available themes
var allThemes = _styleCache.GetAllStyles();
// Get specific theme
var defaultTheme = _styleCache.GetStyle("default");
return View(allThemes);
}
}
Theme Helper Methods
// Get current theme information
var currentTheme = BootswatchThemeHelper.GetCurrentThemeName(Context);
var colorMode = BootswatchThemeHelper.GetCurrentColorMode(Context);
var themeUrl = BootswatchThemeHelper.GetThemeUrl(StyleCache, currentTheme);
// Generate theme switcher HTML
var switcherHtml = BootswatchThemeHelper.GetThemeSwitcherHtml(StyleCache, Context);
Custom Theme Integration
// Add custom themes to your StyleCache
public void ConfigureServices(IServiceCollection services)
{
services.AddBootswatchThemeSwitcher();
services.Configure<BootswatchOptions>(options =>
{
options.CustomThemes.Add(new StyleModel
{
Name = "custom-theme",
Description = "My Custom Theme",
CssPath = "/css/custom-theme.css"
});
});
}
๐งช Testing & Demo
Demo Project
Explore the complete implementation in our demo project:
git clone https://github.com/MarkHazleton/WebSpark.Bootswatch.git
cd WebSpark.Bootswatch
dotnet run --project WebSpark.Bootswatch.Demo
The demo showcases:
- โ All Bootswatch themes
- โ Light/dark mode switching
- โ Responsive design patterns
- โ Integration examples
- โ Performance optimizations
Multi-Framework Testing
The library includes comprehensive tests that run on all supported frameworks:
# Test all frameworks
dotnet test
# Test specific framework
dotnet test --framework net8.0
dotnet test --framework net9.0
dotnet test --framework net10.0
# Use PowerShell script for detailed output
.\run-multi-framework-tests.ps1
Our CI/CD pipeline runs separate test jobs for each framework, ensuring compatibility across all supported .NET versions.
๐๏ธ Architecture
Core Components
| Component | Purpose | Lifecycle |
|---|---|---|
StyleCache |
Theme data caching | Singleton |
BootswatchStyleProvider |
Theme management | Scoped |
BootswatchThemeHelper |
Static utilities | Static |
BootswatchThemeSwitcherTagHelper |
UI component | Transient |
Middleware Pipeline
The correct middleware order is crucial:
app.UseBootswatchStaticFiles(); // 1. Bootswatch static files
app.UseStaticFiles(); // 2. Application static files
app.UseRouting(); // 3. Routing
Multi-Framework Package Structure
The NuGet package contains separate assemblies for each target framework:
WebSpark.Bootswatch.1.31.0.nupkg
โโโ lib/
โ โโโ net8.0/
โ โ โโโ WebSpark.Bootswatch.dll
โ โโโ net9.0/
โ โ โโโ WebSpark.Bootswatch.dll
โ โโโ net10.0/
โ โโโ WebSpark.Bootswatch.dll
Each assembly is compiled with framework-specific optimizations and references the appropriate version of dependencies.
๐ง Configuration Options
Middleware Configuration
// Full configuration
app.UseBootswatchAll();
// Or individual components
app.UseBootswatchStaticFiles();
app.UseBootswatchThemeRoutes();
Service Configuration
services.AddBootswatchThemeSwitcher(options =>
{
options.DefaultTheme = "bootstrap";
options.EnableCaching = true;
options.CacheDurationMinutes = 60;
});
๐ Performance
Caching Strategy
- Theme Data: Cached in
StyleCachesingleton - HTTP Requests: Resilient HTTP client with Polly
- Static Files: Embedded resources with cache headers
- Background Loading: Non-blocking theme initialization
Bundle Optimization
- CSS: Minified Bootswatch themes
- JavaScript: Lightweight theme switcher (~2KB)
- Icons: Optimized SVG assets
Framework-Specific Optimizations
Each target framework receives optimized builds:
- .NET 8.0: LTS-optimized with proven stability
- .NET 9.0: Enhanced performance features
- .NET 10.0: Latest runtime optimizations
๐ Security
- โ Input Validation: Theme names sanitized and validated
- โ XSS Protection: HTML encoding in all outputs
- โ HTTPS: Secure external resource loading
- โ CSP Friendly: No inline scripts or styles
- โ CORS Compliant: Proper resource sharing policies
๐ ๏ธ Troubleshooting
For detailed troubleshooting, see the Common Errors & Solutions section above.
Quick Reference
| Issue | Solution |
|---|---|
| Service resolution error | Register AddHttpClientUtility() before AddBootswatchThemeSwitcher() |
| Themes not loading | Check middleware order: UseBootswatchAll() before UseStaticFiles() |
| Theme switcher not visible | Ensure @addTagHelper *, WebSpark.Bootswatch in _ViewImports.cshtml |
| Missing dependencies | Install WebSpark.HttpClientUtility package |
| Configuration errors | Add required appsettings.json configuration |
| Wrong framework version | NuGet automatically selects correct version based on your target framework |
Debug Mode
Enable detailed logging:
builder.Services.AddLogging(config =>
{
config.AddConsole();
config.SetMinimumLevel(LogLevel.Debug);
});
๐ Browser Support
| Browser | Version | Status |
|---|---|---|
| Chrome | 90+ | โ Fully Supported |
| Firefox | 88+ | โ Fully Supported |
| Safari | 14+ | โ Fully Supported |
| Edge | 90+ | โ Fully Supported |
| IE | 11 | โ Not Supported |
๐ค Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Development Setup
# Clone repository
git clone https://github.com/MarkHazleton/WebSpark.Bootswatch.git
cd WebSpark.Bootswatch
# Restore dependencies
dotnet restore
# Build solution (builds for all target frameworks)
dotnet build
# Run tests (tests all frameworks)
dotnet test
# Run demo
dotnet run --project WebSpark.Bootswatch.Demo
Testing Contributions
When contributing, ensure your changes work across all target frameworks:
# Run comprehensive multi-framework tests
.\run-multi-framework-tests.ps1 -Configuration Release
Contribution Areas
- ๐ Bug fixes and improvements
- ๐ Documentation enhancements
- ๐จ New theme contributions
- ๐งช Test coverage expansion
- ๐ Performance optimizations
- ๐ฏ Framework-specific optimizations
๐ Changelog
[1.34.0] - 2025-12-03
- ๐จ Demo Site UI Improvements: Enhanced hero section visibility across all themes
- ๐จ Better Contrast: Added shadow effects and explicit color classes for readability
- ๐จ Typography Enhancements: Improved visual hierarchy with better weights
- โ No Library Changes: Demo-only improvements, library remains unchanged
- โ No Breaking Changes: Fully backward compatible
[1.33.0] - 2025-12-03
- โ Dependency Validation: Automatic detection of missing required services
- โ Configuration Validation: Startup validation service with helpful warnings
- โ Enhanced XML Documentation: Comprehensive IntelliSense with code examples
- โ Improved Error Messages: Clear, actionable error messages with solutions
- ๐ README Rewrite: Complete step-by-step setup guide with troubleshooting
- โ No Breaking Changes: Fully backward compatible
[1.31.0] - 2025-01-13
- โ Multi-Framework Support: Added .NET 8.0, 9.0, and 10.0 targeting
- โ Updated Dependencies: Framework-specific package versions
- โ Comprehensive Testing: Multi-framework test suite with CI/CD
- โ Removed Legacy Code: Eliminated System.Text.RegularExpressions (now in BCL)
- โ No Breaking Changes: Fully backward compatible
[1.30.0] - 2025-01-07
- โ Updated all NuGet dependencies to latest versions
- โ Enhanced security with latest dependency versions
- โ No breaking changes
[1.10.3] - 2025-05-20
- โ Patch release with minor improvements
- โ Enhanced logging and diagnostics
[1.10.0] - 2025-05-15
- โ Added Bootswatch Theme Switcher Tag Helper
- โ Included sample layout file in NuGet package
- โ Improved documentation and integration guides
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Third-Party Licenses
- Bootstrap: MIT License
- Bootswatch: MIT License
- WebSpark.HttpClientUtility: MIT License
See NOTICE.txt for complete attribution.
๐ Acknowledgments
- Bootstrap Team - For the amazing Bootstrap framework
- Thomas Park - Creator of Bootswatch themes
- .NET Team - For excellent multi-targeting support
- Contributors - Everyone who has contributed to this project
๐ Support
- ๐ Documentation: GitHub Wiki
- ๐ Bug Reports: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- ๐ง Email: Contact Author
<div align="center"> <p>Made with โค๏ธ by <a href="https://github.com/MarkHazleton">Mark Hazleton</a></p> <p> <a href="https://github.com/MarkHazleton/WebSpark.Bootswatch">โญ Star this repo</a> โข <a href="https://github.com/MarkHazleton/WebSpark.Bootswatch/fork">๐ Fork</a> โข <a href="https://github.com/MarkHazleton/WebSpark.Bootswatch/issues">๐ Report Bug</a> โข <a href="https://github.com/MarkHazleton/WebSpark.Bootswatch/discussions">๐ฌ Discuss</a> </p> </div>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.AspNetCore.Mvc.Razor (>= 2.3.0)
- Microsoft.AspNetCore.Mvc.ViewFeatures (>= 2.3.0)
- Microsoft.AspNetCore.StaticFiles (>= 2.3.0)
- Microsoft.Extensions.FileProviders.Embedded (>= 10.0.0)
- WebSpark.HttpClientUtility (>= 2.1.1)
-
net8.0
- Microsoft.AspNetCore.Mvc.Razor (>= 2.3.0)
- Microsoft.AspNetCore.Mvc.ViewFeatures (>= 2.3.0)
- Microsoft.AspNetCore.StaticFiles (>= 2.3.0)
- Microsoft.Extensions.FileProviders.Embedded (>= 8.0.11)
- WebSpark.HttpClientUtility (>= 2.1.1)
-
net9.0
- Microsoft.AspNetCore.Mvc.Razor (>= 2.3.0)
- Microsoft.AspNetCore.Mvc.ViewFeatures (>= 2.3.0)
- Microsoft.AspNetCore.StaticFiles (>= 2.3.0)
- Microsoft.Extensions.FileProviders.Embedded (>= 9.0.9)
- WebSpark.HttpClientUtility (>= 2.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.34.0 | 196 | 12/4/2025 |
| 1.32.0 | 292 | 11/13/2025 |
| 1.30.0 | 129 | 9/27/2025 |
| 1.20.1 | 222 | 7/1/2025 |
| 1.10.3 | 216 | 5/21/2025 |
| 1.10.2 | 205 | 5/20/2025 |
| 1.10.1 | 218 | 5/18/2025 |
| 1.10.0 | 289 | 5/15/2025 |
| 1.0.7 | 292 | 5/15/2025 |
| 1.0.6 | 231 | 5/5/2025 |
| 1.0.5 | 216 | 5/5/2025 |
| 1.0.4 | 215 | 5/4/2025 |
| 1.0.3 | 203 | 5/4/2025 |
| 1.0.2 | 190 | 5/4/2025 |
Version 1.34.0: Demo site UI improvements
DEMO SITE ENHANCEMENTS:
- 🎨 Improved hero section visibility across all 28 themes
- 🎨 Enhanced text contrast with shadow effects and explicit color classes
- 🎨 Better visual hierarchy with improved typography weights
- 🎨 Ensures readability in both light and dark mode themes
LIBRARY CHANGES: None - This is a demo-only release
BREAKING CHANGES: None - Fully backward compatible
Previous version 1.33.0: Enhanced developer experience with dependency validation,
configuration validation service, comprehensive XML documentation, and improved error
messages.
Complete README rewrite with step-by-step setup guide and troubleshooting section.
SETUP REQUIREMENTS:
1. Install: dotnet add package WebSpark.HttpClientUtility
2. Register: builder.Services.AddHttpClientUtility(); (BEFORE AddBootswatchThemeSwitcher)
3. Add HttpRequestResultPollyOptions to appsettings.json
4. Use UseBootswatchAll() BEFORE UseStaticFiles()
For complete setup guide, see:
https://github.com/MarkHazleton/WebSpark.Bootswatch/wiki/Getting-Started