UseDefaultFiles() vs UseStaticFiles() vs UseSpaStaticFiles() vs UseSpa()

A brief introduction to UseDefaultFiles, UseStaticFiles, UseSpaStaticFiles and UseSpa

UseDefaultFiles() vs UseStaticFiles() vs UseSpaStaticFiles() vs UseSpa()

Overview

So you're building some kind of frontend and hosting it from your ASP.NET Core 2.1+ application. Most likely you've experienced the same issue I have - what the heck is the difference between UseDefaultFiles, UseStaticFiles,  UseSpaStaticFiles and UseSpa? I'll share my findings here.

I'll assume you have basic knowledge of what the wwwroot folder is and how middleware works (they execute in order). All these methods are closely related to handling static files and the wwwroot folder. We'll go through all of them, in the order which you shall execute them, and find out their true purpose, answering questions as why you must call them, and why the order matters.

First one first:

UseDefaultFiles()

Some answers say that you must use UseDefaultFiles first, which is true, and here is the reason:

I think it's time for a print screen here, since it shows very clearly what actually happens. Assume you navigate to /, take a look here what happens before UseDefaultFiles:

and here what happens after:

The path is rewritten. Now all this makes sense from the official docs:

UseDefaultFiles is a URL rewriter that doesn't actually serve the file

That's good, so no matter where we happen to place our call to UseDefaultFiles, we know it's single responsibility is to re-write the path to fit perfectly into what will come...

UseStaticFiles()

By default a wwwroot folder is created where your static files (js, css, html etc) is stored. Static files means that no further processing is required, and we shall instead just exit here and send the files back as-is to the client.

The responsibility of UseStaticFiles is to look a the path (for example /index.html), and serve content from this wwwroot folder.

Assuming you've placed your SPA files (js, css, html etc) under wwwroot, then it'll work with these lines of code in this order:

Now you know what UseStaticFiles does, it serves the files from this folder, and you know the reason it must be placed after UseDefaultFiles. This is enough to serve our SPA app, so what's the purpose of the other methods?

UseSpaStaticFiles()

Assuming you're actually building your frontend files (js, css, html, svg, icons etc) into wwwroot i've found little use of UseSpaStaticFiles, but let's explore it anyway...

Since UseStaticFiles serves files from wwwroot, it seems this method is used when your files for your SPA application is placed somewhere else, like another folder besides wwwroot or inside, like wwwroot/myspa. This  method doesn't by itself actually know where your files are located, but rather delegates that responsibility to another service, and therefore require you to call AddSpaStaticFiles when you register your other services. It looks like this:

Actually...UseSpaStaticFiles performs some checks and eventually calls UseStaticFiles.

So why is UseSpaStaticFiles needed?

The best I can find is that it just seems the way forward for ASP.NET Core is that the term "SPA" will take place inside the actual ASP.NET Core naming world. They have these methods for applications that might have content not just inside wwwroot. One could also think that more functionality will be added for these services as the ASP.NET Core framework evolves. (There is actually one thing that you'll see below when we talk about UseSpa that's pretty cool.)

UseSpa()

Let's take a short recap first, so we know where we are:

We have called UseDefaultFiles to re-write the path, then UseStaticFiles and maybe UseSpaStaticFiles to serve files from wwwroot. So when a user visits / for example it will be re-written to /index.html and then served back successfully.  This is good. Why would you need something else?

Turns out this method is supposed to be placed very late in your middleware chain. Sort of as a fallback incase we have passed all other middleware and still not found a page to serve. If we read from the official docs it says:

Handles all requests from this point in the middleware chain by returning the default page for the Single Page Application (SPA). This middleware should be placed late in the chain, so that other middleware for serving static files, MVC actions, etc., takes precedence.

So this will be placed last. But hey, what does it do? It does a few things:

  1. Re-write the path to the default SPA path, which is hardcoded to /index.html.
  2. Serves the static files (using UseStaticFiles under the hood). This is pretty much the same as we have talked about previously, the only difference being that we now also fallback to webroot files.
  3. Throws an exception with a message if something seems wrong.

The really cool feature with UseSpa: But the great feature I found with UseSpa was more daily-development-related. I found this piece of code mentioned on the official docs for an angular app (code below has nothing with angular itself to do):

Of course you only apply it if running locally. This is very powerful! Finally my frontend colleagues can setup their frontend stuff in whatever way they prefer, do the npm run dev dance to watch the source code (js, html, css).

Summary

I'll keep it simple here, but roughly speaking, a reasonable order seem to be the following:

That's it, hope you learned something new at least. This seem to be the behavior of ASP.NET Core 2.1 till 3.1 at least, but might change afterwards in newer versions. Happy Coding!