I have Blazor Webassembly ASP.NET Core hosted and I installed Swashbuckle.AspNetCore to display endpoints that my Blazor app has (/swagger
endpoint).
My Startup.Configure
looks like this (only swagger part):
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
c.SwaggerEndpoint($"{description.GroupName}/swagger.json", $"v{description.GroupName.ToUpperInvariant()}");
}
c.InjectStylesheet("/css/swaggerDark.css");
});
As you can see, I inject custom .css file which works.
In my Blazor app, I inject swagger so my page looks like this (.razor page):
<iframe src="swagger"/>
Again, it works correctly, swagger documentation is displayed and it has dark theme.
I have noticed (to no suprise) that this iframe
has a link to this .css file:
<link href="/css/swaggerDark.css" rel="stylesheet" media="screen" type="text/css">
Removing this link brings the default swagger look (light theme).
The user of my app can choose which theme he wants (light/dark) of the whole application. My question is, how do I dynamically inject/remove (or maybe enable/disable) this .css file so depending on which app theme the user chooses, the swagger will either display default (light) or dark theme (using that .css file)?
I couldn't find any relevant info on this issue so I decided to create this question. I appreciate any help. Thank you.
Ok, I figured it out. The answer is: use JsInterop.
My .razor page looks like this at the moment:
@page "/something"
@inject IJSRuntime JS //needed to call InvokeVoidAsync
//I made my own ThemeManager to control the Blazor app theme
@if (ThemeManager.IsDefaultTheme)
{
<iframe id="myiframe" src="swagger" @onload="() => ToggleSwaggerTheme(true)" />
}
else
{
<iframe id="myiframe" src="swagger" @onload="() => ToggleSwaggerTheme(false)" />
}
@code {
private async Task ToggleSwaggerTheme(bool isLight) => await JS.InvokeVoidAsync("toggleSwaggerTheme", isLight);
}
I made it so the iframe
toggles depending on the app theme. The ToggleSwaggerTheme
function is self-explanatory - I'm calling my JS function to toggle the theme of swagger.
In index.html
I added a script to load my helperFunctions.js
(in body) in which toggleSwaggerTheme
function can be found:
<script src="/js/helperFunctions.js"></script>
I added helperFunctions.js
in my wwwroot
:
wwwroot -> js -> helperFunctions.js
My helperFunctions.js
looks like this:
function toggleSwaggerTheme(isLight) {
let myiframe = document.getElementById('myiframe');
let styleSheets = myiframe.contentWindow.document.styleSheets;
for (let i = 0; i < styleSheets.length; i++) {
if (styleSheets[i].href == null) {
continue;
}
if (styleSheets[i].href.includes("/css/swaggerDark.css")) {
styleSheets[i].disabled = isLight;
break;
}
}
}
The above function allowed me to toggle the swagger theme. Please note, I don't know if this is the best solution that can be created. Also, I'm not sure how it's going to behave in the production environment. I will update this answer if there are any problems in the production. I hope it can help somebody.
UPDATE AFTER GOING LIVE:
I've had some issues with displaying dark theme after going live. But the following seems to fix the issue: In Program.cs (Server side), in CreateHostBuilder method I added (not sure if it's needed):
webBuilder.UseStaticWebAssets();
So in my case, it looks like this:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStaticWebAssets();
webBuilder.UseStartup<Startup>();
});
I also changed my swaggerDark.css
file property: the Copy to Output Directory
to Copy always
.
You do this by right-clicking the file in Solution Explorer -> Properties (at the end).
After doing these new steps, It seems to be working fine. I hope it can help somebody.