ASP.NET Core Favicon Generator
In ASP.NET Core the web root is wwwroot. Icon files go there, and the link tags go in your layout (MVC/Razor Pages) or App component (Blazor). Static file middleware has to be in the pipeline or every icon 404s regardless of the markup.
wwwroot is the only public folder
Only files under wwwroot are addressable over HTTP. A favicon.ico sitting next to Program.cs is invisible to browsers. Place icons in wwwroot (or a subfolder) and reference them from the HTML the app actually renders.
Recent templates call MapStaticAssets() for build-time discovered assets with fingerprinting. Older apps call UseStaticFiles(). Either way, something in Program.cs has to enable static file serving before endpoints run, or the tags resolve to 404s.
Where the files go
- MyWebApp/
- wwwroot/web root
- favicon.icoadd
- favicon-32x32.pngadd
- apple-touch-icon.pngadd180x180
- icon-192.pngadd
- icon-512.pngadd
- site.webmanifestadd
- Pages/Razor Pages layout lives here
- Shared/
- _Layout.cshtml
- Program.csMapStaticAssets / UseStaticFiles
MVC apps use Views/Shared/_Layout.cshtml instead of Pages/Shared. Blazor Web Apps usually put the tags in Components/App.razor.
Razor layout head
@* Pages/Shared/_Layout.cshtml or Views/Shared/_Layout.cshtml *@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MyWebApp</title>
<link rel="icon" href="~/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="~/favicon-32x32.png" />
<link rel="apple-touch-icon" href="~/apple-touch-icon.png" />
<link rel="manifest" href="~/site.webmanifest" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>The ~ prefix resolves against the web root. In Blazor with MapStaticAssets, prefer @Assets["favicon.ico"] so the fingerprinted URL is used.
Program.cs (minimal)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseHttpsRedirection();
app.MapStaticAssets(); // .NET 9+: fingerprinting + compression
// Older apps: app.UseStaticFiles();
app.MapRazorPages();
app.Run();Order matters: enable static assets before the endpoints that render HTML that links to them.
MVC / Razor Pages vs Blazor
| Stack | Where tags go | How to reference files |
|---|---|---|
| Razor Pages / MVC | _Layout.cshtml <head> | ~/path or asp-append-version |
| Blazor Web App (.NET 9+) | App.razor <head> | @Assets["favicon.png"] with MapStaticAssets |
| Standalone Blazor WASM | wwwroot/index.html | Plain href paths under wwwroot |
ASP.NET Core favicon FAQ
Do I need a link tag if favicon.ico is in wwwroot?
Browsers often request /favicon.ico automatically, so a root .ico can appear without a tag. PNG sizes, apple-touch-icon, and the manifest still need explicit link tags in the layout.
Why does @Assets show a different filename?
MapStaticAssets fingerprints static web assets so deploys bust caches. Use the Assets helper (or the fingerprinted href it generates) instead of hardcoding /favicon.png after you opt into that pipeline.
IIS or nginx still returns 404 for the icon.
Confirm the published output includes wwwroot content and that the reverse proxy forwards those paths to the ASP.NET process (or serves the static files itself from the published wwwroot). A proxy that only forwards / and /api will never see /favicon.ico.