How to deal with the "HTTP 404 '_content/Foo/Bar.css' not found" when using Razor component package on ASP.NET Core Blazor app
Tags: aspnetcore, blazor
Published: 2020-07-08 13:14:05

---
title: How to deal with the "HTTP 404 '_content/Foo/Bar.css' not found" when using Razor component package on ASP.NET Core Blazor app
published: true
description: This article describes the ASP.NET Core static web assets feature and will show you how to deal with the trouble related to that feature.
tags: aspnetcore, blazor
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ewzso05hud21u0qs7o78.png
---

# ― Prologue ―

## Quick tour of "Razor Class library" package

You can easily create a class library project that includes Blazor components to reuse them from other projects.

Those libraries are called **"Razor Class Library"**, and you can also package it as a NuGet package.

**The "Razor Class Library" NuGet package can also include static web assets** such as JavaScript, CSS, graphics, fonts, etc.

### How to create "Razor Class Library" and package it?

If you use Visual Studio IDE on Windows OS, you can start from the "Razor Class Library" project template for creating it.

![fig.1](https://dev-to-uploads.s3.amazonaws.com/i/9l2lcj74qx3yrsdyam5i.png)

If you use dotnet CLI, `dotnet new razorclasslib` command does it. 

![fig.2](https://dev-to-uploads.s3.amazonaws.com/i/gk558a7jkps9lwcpkxtl.png)

After the new "Razor Class Library" project was generated from the template, you can see the project includes Razor component, JavaScript, CSS, and PNG image file. 

![fig.3](https://dev-to-uploads.s3.amazonaws.com/i/lzbull0u7znfq7tyup34.png)

After implements what you want, you can package it as a NuGet package file(.nupkg).

To package the project on Visual Studio IDE, right-click the project node on solution explorer, and click the "Pack" menu item of the context menu.

![fig.4](https://dev-to-uploads.s3.amazonaws.com/i/p3g5m9mdy3whx6pj3quj.png)

If you use dotnet CLI, the "dotnet pack" command does it.

![fig.5](https://dev-to-uploads.s3.amazonaws.com/i/gqzlwzyqur3zxe2hd2kn.png)

After the process was completed, you can see the NuGet package (.nupkg) file is generated.

Static web asset files that are included in the source project are also bundled inside of the NuGet package file.

![fig.6](https://dev-to-uploads.s3.amazonaws.com/i/f59hkh5yn028ffr3u7zw.png)

### How to redistribute and consume the package?

Once you created the "Razor Class Library" as a NuGet package, you can redistribute it in numerous ways.

One of the easiest ways is, save the package file into the file system.

After configuring the package source settings to adding the folder location where your NuGet packages will be saved (see below), 

![fig.7](https://dev-to-uploads.s3.amazonaws.com/i/dp5gmkizv34620xqn84i.png)

you can add the package reference to that NuGet package into any Blazor app projects.

![fig.8](https://dev-to-uploads.s3.amazonaws.com/i/bl1bs6jg4577ec1b1bvz.png)

And, you can also reference the static web assets that are included the NuGet package from root document such as `index.html` or `_Host.cshtml`.

The URL of those static web assets is:

- starts with "_content/",
- next, the name of the package,
- at last, the file name of the asset file.

As you see, you can create, redistribute, and use a reusable component library package that includes static web assets, very easily.

![fig.9](https://dev-to-uploads.s3.amazonaws.com/i/ft6v5q3dq671v8sjnwww.png)

### Wait, where are static web asset files?

By the way, if you inspect the output files of the application project, you will find that you cannot find any static web asset files provided by the NuGet package.

![fig.10](https://dev-to-uploads.s3.amazonaws.com/i/wl7n3w6e0ork6kje93g5.png)

Where do those files come from?

### The key point is the ".StaticWebAssets.xml" file.

The answer is, "Those files come from the NuGet package cache folder".

You will find `"{OutputName}.StaticWebAssets.xml"` XML formatted file in output folder.

The `.StaticWebAssets.xml` file is generated at the build process, and it describes the mapping information from the URL path to the physical file system location.

![fig.11](https://dev-to-uploads.s3.amazonaws.com/i/ngun9bokrerxknptrz8k.png)

The `.StaticWebAssets.xml` file is read by ASP.NET Core `StaticWebAssetsFileProvider` file provider (in Blazor Server, or Blazor WebAssembly hosted ASP.NET Core scenario) or Blazor DevServer (in Blazor WebAssembly scenario).

`StaticWebAssetsFileProvider` file provider or Blazor DevServer be able to respond static web asset contents that are located NuGet package cache folder to web browsers with the URL mapping information that is provided by `.StaticWebAssets.xml` file.

This "Static Web Assets" feature of ASP.NET Core is helpful for save the build time and reduce file usage size on your disk space.

Of course, this feature is designed for application development time.

After publishing the project, the published folder includes all static web asset files statically that are included NuGet packages.

![fig.12](https://dev-to-uploads.s3.amazonaws.com/i/noi1d15bshu6b8ndxalm.png)

# ― Main Subject ―

## One day, the styling of the component was lost!

One day, my co-worker run into the problem.

**"Wow, what's happening? the styling of "My.Greeting" component on my Blazor Server App is lost! 😱"**

![fig.13](https://dev-to-uploads.s3.amazonaws.com/i/otv7grmdmwk2h2hwavom.png)

I started an investigation with developer tools on the web browser immediately to know what is happening.

The developer tools said the request to static web asset (in this case, the .css file that bundled the NuGet package) was failed by HTTP 404 "Resouce not found".

![fig.14](https://dev-to-uploads.s3.amazonaws.com/i/d19uw3a6rwrr4d7415ja.png)

I also inspected `.StaticWebAssets.xml` file was broken or not, but it existed and it was no problem.

Why the `StaticWebAssetsFileProvider` in the Blazor Server app could not find the static web asset files?

## The reason is ...

Next, I cloned my coworker's Git repository and compared the two Blazor Server app projects, one is my co-worker's project, and another one is mine that is not broken.

After a few hours I was using diff tools, finally, I found the reason for the problem.

The reason for the problem was the **"ASPNETCORE_ENVIRONMENT"** environment variable.

In the Blazor Server app project broken version, the configuration of the **"ASPNETCORE_ENVIRONMENT"** environment variable was **set with "Release", not "Development"**.

![fig.15](https://dev-to-uploads.s3.amazonaws.com/i/a0jfssdj47hmnohvfzwc.png)

My co-worker wanted to investigate the behavior of the Blazor Server app in the "Release" mode, so she changed the setting of the"'ASPNETCORE_ENVIRONMENT" environment variable.

Unfortunately, the `StaticWebAssetsFileProvider` is used only when the "ENVIRONMENT" configuration is "Development"...! (See ASP.NET Core source code at below.)

- https://github.com/dotnet/aspnetcore/blob/c1866c2b61361e601a448a82607d8879ad01696a/src/DefaultBuilder/src/WebHost.cs#L219

After I reverted this setting to "Development", the Blazor Server app was worked fine.

## Another workaround

If you have to use the ASP.NET Core static web assets feature in a not "Development" environment mode, you can enable that feature manually.

Usually, the `StaticWebAssetsFileProvider` is inserted to the application by the inside of the `ConfigureWebHostDefaults()` extension method that will be called at your `Program.Main()` method, only when the hosting environment mode is "Development".

You can insert the `StaticWebAssetsFileProvider` manually even if the hosting environment mode is not "Development", like this code:

```csharp
// Program.cs
...
public class Program
{
  ...
  public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
      .ConfigureWebHostDefaults(webBuilder =>
      {
        webBuilder.UseStartup<Startup>();

        // 👇 Add this "ConfigureAppConfiguration" method calling.
        webBuilder.ConfigureAppConfiguration((ctx, cb) =>
        {
          // 👇 Please specify the condition that is true only when
          //    the application is running on your development environment.
          //    Notice that excludes the case that the environment is "Development".
          if (!ctx.HostingEnvironment.IsDevelopment() &&
               /* your prefer condition*/)
          {
            // 👇 This call inserts "StaticWebAssetsFileProvider" into
            //    the static file middleware.
            StaticWebAssetsLoader.UseStaticWebAssets(
              ctx.HostingEnvironment, 
              ctx.Configuration);
          }
        });
        ...
```

# ― Conclusion ―

On Blazor Server App and Blazor Wasm ASP.NET Core host, the `StaticWebAssetsFileProvider` is used only when the hosting "ENVIRONMENT" configuration is "Development".

If you encounter like the `"HTTP 404 '_content/Foo/Bar.css' not found"` error when using Razor component library package on ASP.NET Core Blazor app development scene, I'll recommend you to **check the "ASPNETCORE_ENVIRONMENT" environment variable is "Development" or not.**

If you have to set non "Development" value to the "ASPNETCORE_ENVIRONMENT" environment variable and have to run it from Visual Studio or "dotnet run", please try to add `StaticWebAssetsLoader.UseStaticWebAssets(...)` method calling into the `Program.cs`.

Happy coding!