How to make ASP.NET/React app serve SPA from subpath?

Start with moving app to sub-path by adding this to top of package.json:


"homepage": "/myapp/", 

When running npm start inside ClientApp folder, app is now serving http://localhost:3000/myapp


Then change Startup.cs like this:


First remove


app.UseSpaStaticFiles()

then add


        const string spaPath = "/myapp";

        if (env.IsDevelopment())

        {

            app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments(spaPath)

                               || ctx.Request.Path.StartsWithSegments("/sockjs-node"),

                client =>

            {

                client.UseSpa(spa =>

                {

                    spa.Options.SourcePath = "ClientApp";

                    spa.UseReactDevelopmentServer(npmScript: "start");

                });

            });

        }

        else

        {

            app.Map(new PathString(spaPath), client =>

            {

                // `https://github.com/dotnet/aspnetcore/issues/3147`

                client.UseSpaStaticFiles(new StaticFileOptions()

                {

                    OnPrepareResponse = ctx =>

                    {

                        if (ctx.Context.Request.Path.StartsWithSegments($"{spaPath}/static"))

                        {

                            // Cache all static resources for 1 year (versioned file names)

                            var headers = ctx.Context.Response.GetTypedHeaders();

                            headers.CacheControl = new CacheControlHeaderValue

                            {

                                Public = true,

                                MaxAge = TimeSpan.FromDays(365)

                            };

                        }

                        else

                        {

                            // Do not cache explicit `/index.html` or any other files.  See also: `DefaultPageStaticFileOptions` below for implicit "/index.html"

                            var headers = ctx.Context.Response.GetTypedHeaders();

                            headers.CacheControl = new CacheControlHeaderValue

                            {

                                Public = true,

                                MaxAge = TimeSpan.FromDays(0)

                            };

                        }

                    }

                });


                client.UseSpa(spa =>

                {

                    spa.Options.SourcePath = "ClientApp";

                    spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions()

                    {

                        OnPrepareResponse = ctx => {

                            // Do not cache implicit `/index.html`.  See also: `UseSpaStaticFiles` above

                            var headers = ctx.Context.Response.GetTypedHeaders();

                            headers.CacheControl = new CacheControlHeaderValue

                            {

                                Public = true,

                                MaxAge = TimeSpan.FromDays(0)

                            };

                        }

                    };

                });

            });

        }

Don't forget to clear browser history before testing changes for the first time on e.g. Azure. 


org ans: https://stackoverflow.com/questions/56998912/how-to-make-asp-net-react-app-serve-spa-from-subpath/57000169

1 comment: