Why UseSpa() is still needed if UseSpaStaticFiles() should serve the Angular page?

Viewed 2209

I read some articles/blog posts and questions here but I am still confused about the usage of UseSpaStaticFiles() and UseSpa() middlewares in ASP.NET Core 2.1. (References: What is the difference between UseStaticFiles, UseSpaStaticFiles, and UseSpa in ASP.NET Core 2.1? https://blog.steadycoding.com/usedefaultfiles-usestaticfiles-usespastaticfiles-usespa/)

I am using the Angular project template with ASP.NET Core 2.1 which comes with a predefined set of middlewares added to the pipeline in the Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSpaStaticFiles(configuration =>
               {
                   configuration.RootPath = "ClientApp/dist";
               });      
}

public void Configure(IApplicationBuilder app)
{   

    app.UseStaticFiles();
    app.UseSpaStaticFiles();

   
    app.UseSpa(spa =>
    {
        if (env.IsDevelopment())
        {
            spa.UseProxyToSpaDevelopmentServer("http://localhost:4000");
        }
    });
    
}

My confusion is the following: The Angular project is compiled externally and the compiled js files are located in the ClientApp/dist folder, the environment is also set to production, so I would assume that the UseSpaStaticFiles() will serve the Angular page since the ClientApp/dist folder has the proper content for that. Also, the UseSpa() middleware is useless in this situation so I could remove that one.

However, if the UseSpa() is removed, the Angular page is not loaded at all, despite of the fact that the UseSpaStaticFiles() should serve the page based on the content of the ClientApp/dist. (If the UseSpaStaticFiles() and UseSpa() both added to the middleware pipeline, the Angular page is successfully served from the ClientApp/dist folder which means that the UseSpaStaticFiles() serves it.)

If the environment is set to production, the UseSpa() is not configured at all, it is just added to the middleware pipeline.

Can you help me to clarify why the UseSpaStaticFiles() cannot serve the page without the UseSpa() and why UseSpa() should be always added to the pipeline even if it doesn't serve anything? Do I miss something from my configuration that causes this behaviour?

1 Answers

The UseSpa is essentially a catch-all route handler that forwards all previously unhandled routes to your single page application. That way, your SPA can do things like client-side routing without your server application having to know all the routes the client application understands.

In contrast, UseSpaStaticFiles is a static files handler that only serves the compiled application files, e.g. application bundles like app.js or vendor.js, under their respective name, just like UseStaticFiles works for static files in the wwwroot folder.

Related