Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure ASP.net Core server routing for multiple SPAs hosted with SpaServices

I have an Angular 5 application that I want to host with Angular Universal on ASP.net Core using the latest Angular template RC. I've followed the docs and have the application up and running. The problem is that I am also using Angular's i18n tools, which produce multiple compiled applications, 1 per locale. I need to be able to host each from https://myhost.com/{locale}/.

I know that I can spin up an instance of the ASP.net Core app for each locale, and set up hosting in the webserver to have the appropriate paths route to the associated app, but this seems excessive to me.

Routes are configured with:

// app is an instance of Microsoft.AspNetCore.Builder.IApplicationBuilder app.UseMvc(routes => {     routes.MapRoute(         name: "default",         template: "{controller}/{action=Index}/{id?}"); }); 

SpaServices are configured with:

app.UseSpa(spa => {     // To learn more about options for serving an Angular SPA from ASP.NET Core,     // see https://go.microsoft.com/fwlink/?linkid=864501      spa.Options.SourcePath = "ClientApp";      spa.UseSpaPrerendering(options =>     {         options.BootModulePath = $"{spa.Options.SourcePath}/dist-server/main.bundle.js";         options.BootModuleBuilder = env.IsDevelopment()             ? new AngularCliBuilder(npmScript: "build:ssr:en")             : null;         options.ExcludeUrls = new[] { "/sockjs-node" };         options.SupplyData = (context, data) =>         {             data["foo"] = "bar";         };     });      if (env.IsDevelopment())     {         spa.UseAngularCliServer(npmScript: "start");     } }); 

I've looked through the documentation and the source on Github, and I cannot find how to configure ASP.net Core to associate a specific route with a given SPA. Anyone have any ideas?

like image 580
asgallant Avatar asked Jan 11 '18 22:01

asgallant


1 Answers

Thanks to SteveSandersonMS and chris5287 over on Github for pointing me towards the solution on this.

IApplicationBuilder.Map can segregate paths into different areas of concern. If you wrap a call to app.UseSpa in a call to app.Map, the SPA will be handled only for the path specified by the Map call. The app.UseSpa call ends up looking like:

app.Map("/app1", app1 => {     app1.UseSpa(spa =>     {         // To learn more about options for serving an Angular SPA from ASP.NET Core,         // see https://go.microsoft.com/fwlink/?linkid=864501          spa.Options.SourcePath = "ClientApp";          spa.UseSpaPrerendering(options =>         {             options.BootModulePath = $"{spa.Options.SourcePath}/dist-server/main.bundle.js";             options.BootModuleBuilder = env.IsDevelopment()                 ? new AngularCliBuilder(npmScript: "build:ssr:en")                 : null;             options.ExcludeUrls = new[] { "/sockjs-node" };             options.SupplyData = (context, data) =>             {                 data["foo"] = "bar";             };         });          if (env.IsDevelopment())         {             spa.UseAngularCliServer(npmScript: "start --app=app1 --base-href=/app1/ --serve-path=/");         }     }); }); 

You can make as many calls to app.Map as necessary to configure your SPAs. Also note the modification to the spa.UseAngularCliServer call at the end: you will need to set --base-href and --serve-path to match your particular config.

like image 169
asgallant Avatar answered Sep 22 '22 21:09

asgallant