Serving different CSS files
This is a guide on how to serve different CSS files based on a passed on styling
header that is all made up. So, if the user passes a header called basic
, one CSS file will be used, and if the header is called advanced
, another CSS file is passed to an Angular application.
This approach can be used with many different scenarios - you could for example use query strings - but this example will use a custom styling
header.
Also, this applies to any type of SPA application used with ASP.NET Core (Vue, React, etc), but this example is used with Angular. Worth mentioning is that you can serve any types of static files, it does not have to be different CSS files. I can be logos, favicons or pictures.
Creating the files
First, we need the different CSS files. I have created a folder called StaticFiles
in the root of the ASP.NET Core project, and created a folder for each file that I want.
All files that we want to change depending on the header, need to have the same name. For example, the CSS file will always be named index.css
.
Creating the middleware
I will create a middleware called StatisFilesHelper.cs
, and the whole file looks like this.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.FileProviders;
using System.IO;
namespace DifferentCSS.Helpers
{
public static class StaticFilesHelper
{
public static void AddCompanySpecificFiles(this IApplicationBuilder app, params string[] companies)
{
foreach (string company in companies)
{
// Add static files based on styling header for a specific company
app.UseWhen(
context => context.Request.Headers["styling"] == company,
appBuilder => appBuilder.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "staticfiles", company)),
RequestPath = new PathString("/staticfiles")
}));
}
// add base fíles if no header is specified
app.UseWhen(
context => !context.Request.Headers.ContainsKey("styling"),
appBuilder => appBuilder.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "staticfiles", "base")),
RequestPath = new PathString("/staticfiles")
}));
}
}
}
The AddCompanySpecificFiles
method needs a list of strings as a parameter, in which each string represents a company (and each company should have its own CSS).
// ...
foreach (string company in companies)
{
// Add static files based on styling header for a specific company
app.UseWhen(
context => context.Request.Headers["styling"] == company,
appBuilder => appBuilder.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "staticfiles", company)),
RequestPath = new PathString("/staticfiles")
}));
}
//...
In this part, I loop through each string to see if it matches the styling
header. If it does, I will use the UseStaticFiles
method and point it to the path of the CSS with the same name. So if the header is basic
, it points /staticfiles
to the path StaticFiles/basic
, which one of our CSS is located within.
If the styling header would be advanced
, the url /staticfiles
would point to StaticFiles/advanced
.
// ...
// add base fíles if no header is specified
app.UseWhen(
context => !context.Request.Headers.ContainsKey("styling"),
appBuilder => appBuilder.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "staticfiles", "base")),
RequestPath = new PathString("/staticfiles")
}));
If no header is specified, it will use the base
folder and use that instead.
Adding to Startup
We need to add our middleware to the Startup.cs
file. I put my middleware in a Helpers
folder, so I have the include it with the using
keyword to apply the middleware.
using DifferentCSS.Helpers;
// ...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
app.AddCompanySpecificFiles(new string[] { "basic", "advanced" });
}
I am passing in a list of strings, each string with the same name as the folders we declared earlier.
Adding to HTML
We need to add the reference in main HTML file as well. In my case, this file is served within the ClientApp
, which the Angular application resides in. For me, its located in the src
application, and called index.html
.
In the head, I simply add a link referencing the /staticfiles
url.
<link rel="stylesheet" href="/staticfiles/index.css" type="text/css" />
This will apply the CSS file based on the styling header that is passed on.
Be sure to clear your cache if you change header in the middle of a session, or else the CSS won’t change.