Skip to content

Commit 1bb6faf

Browse files
committed
Fix web command static file serving in single-file executable
- Embed wwwroot files as EmbeddedResource in assembly - Configure EmbeddedFileProvider with correct namespace - Add explicit MIME type configuration for CSS, JS, JSON, ICO - Add inline SVG favicon to avoid external file dependency - Maintains PublishSingleFile=true constraint
1 parent c1ef06a commit 1bb6faf

3 files changed

Lines changed: 42 additions & 2 deletions

File tree

Commands/WebCommand.cs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// SOFTWARE.
2121

2222
using System.ComponentModel;
23+
using Microsoft.Extensions.FileProviders;
2324
using Spectre.Console;
2425
using Spectre.Console.Cli;
2526
using LocalizationManager.Core.Backends.Json;
@@ -253,8 +254,41 @@ public override int Execute(CommandContext context, Settings settings, Cancellat
253254

254255
app.MapControllers();
255256

256-
// Serve static files (CSS, JS, images)
257-
app.UseStaticFiles();
257+
// Serve static files from embedded resources (for single-file executable)
258+
var assembly = typeof(Program).Assembly;
259+
260+
// Debug: List embedded resources
261+
var resourceNames = assembly.GetManifestResourceNames();
262+
AnsiConsole.MarkupLine($"[dim]Embedded resources: {string.Join(", ", resourceNames.Take(5))}...[/]");
263+
264+
var embeddedProvider = new EmbeddedFileProvider(assembly, "LocalizationManager.wwwroot");
265+
266+
var staticFileOptions = new Microsoft.AspNetCore.Builder.StaticFileOptions
267+
{
268+
FileProvider = embeddedProvider,
269+
OnPrepareResponse = ctx =>
270+
{
271+
// Ensure correct MIME types are set
272+
var path = ctx.File.Name.ToLowerInvariant();
273+
if (path.EndsWith(".css"))
274+
{
275+
ctx.Context.Response.ContentType = "text/css; charset=utf-8";
276+
}
277+
else if (path.EndsWith(".js"))
278+
{
279+
ctx.Context.Response.ContentType = "application/javascript; charset=utf-8";
280+
}
281+
else if (path.EndsWith(".json"))
282+
{
283+
ctx.Context.Response.ContentType = "application/json; charset=utf-8";
284+
}
285+
else if (path.EndsWith(".ico"))
286+
{
287+
ctx.Context.Response.ContentType = "image/x-icon";
288+
}
289+
}
290+
};
291+
app.UseStaticFiles(staticFileOptions);
258292

259293
// Blazor Server routing
260294
app.UseRouting();

LocalizationManager.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@
8787
<RazorGenerate Remove="**\*.razor" />
8888
</ItemGroup>
8989

90+
<!-- Embed static files (wwwroot) into single executable -->
91+
<ItemGroup>
92+
<EmbeddedResource Include="wwwroot\**\*" />
93+
</ItemGroup>
94+
9095
</Project>

Pages/_Layout.cshtml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
99
<title>Localization Resource Manager</title>
1010
<base href="~/" />
11+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🌐</text></svg>">
1112
<link rel="stylesheet" href="css/terminal-theme.css" />
1213
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
1314
</head>

0 commit comments

Comments
 (0)