7

I'm trying to serve 2 angular apps from my .net core service like this:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "wwwroot/app";
    });

    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "wwwroot/admin";
    });

    ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...

    app.UseSpaStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = ctx =>
        {
            ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=0");
        }
    });

    app.UseMvc();

    app.Map("/app", client =>
    {
        client.UseSpa(spa =>
        {
            spa.Options.SourcePath = "wwwroot/app";
        });
    }).Map("/admin", admin =>
    {
        admin.UseSpa(spa =>
        {
            spa.Options.SourcePath = "wwwroot/admin";
        });
    });
}

in the file system, I only have the dist output of these apps (since they are developed by another team). So it looks like this:

  • C:[MY PROJECT PATH]\wwwroot\app
  • C:[MY PROJECT PATH]\wwwroot\admin

But for some reason, the admin app works and the app doesn't and also it doesn't support a default page so I need to enter the URL with /index.html.

Any ideas on how to solve this?

Liran Friedman
  • 4,027
  • 13
  • 53
  • 96

2 Answers2

16

Well, I finally solved it and it works like this:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddSpaStaticFiles();

    ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...

    app.UseSpaStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"))
    });

    app.UseMvc();

    app.Map("/app", client =>
    {
        client.UseSpa(spa =>
        {
            spa.Options.SourcePath = "wwwroot/app";
            spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/app"))
            };
        });
    }).Map("/admin", admin =>
    {
        admin.UseSpa(spa =>
        {
            spa.Options.SourcePath = "wwwroot/admin";
            spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/admin"))
            };
        });
    });
}

Also, don't forget to go into the index.html file of each app and set the base tag accordingly like this:

//for the client application:
<base href="/app/">

//for the admin application
<base href="/admin/">
Liran Friedman
  • 4,027
  • 13
  • 53
  • 96
  • Thanks for taking the time to post the answer. I would guess this saved me many hours. – BinarySolo Jun 06 '19 at 16:04
  • You are most welcome. I'm glad to hear that it came out useful for others as well. – Liran Friedman Jun 06 '19 at 17:05
  • in my mind better answer than [this](https://stackoverflow.com/questions/48216929/how-to-configure-asp-net-core-server-routing-for-multiple-spas-hosted-with-spase) because it mentions the `base href` – Chaim Eliyah Jun 26 '19 at 05:16
2

Liran answered his own question. In my case I had multiple entry points for a vue cli site. The fix is identical to the correct answer, but also setting spa.Options.DefaultPage.

    app
         .Map("/login", admin =>
         {
             admin.UseSpa(spa =>
             {
                 spa.Options.SourcePath = "ClientApp";
                 spa.Options.DefaultPage = "/login.html";
             });
         })
        .Map("", client =>
    {
        client.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";
            spa.Options.DefaultPage = "/index.html";
        });
    });
MGDavies
  • 1,024
  • 1
  • 17
  • 30