Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deploying an Angular SPA under a subfolder

I have an ASP.net Core 2.1 Web API + Angular 6 web application created using Visual Studio 2017 Angular project template. Both the api and the Angular app are in the same web project. In development it runs inside IIS Express, while in production it uses IIS.

The app itself is working fine, but I'm having a hard time deploying it in a subfolder of an existing Web Site, configured as a new Web Application in IIS.

When I invoke the URLs as:

  • http://localhost:52000/AngularWebApp/
  • http://myserver.domain/AngularWebApp/

Angular is able to build the relative paths correctly and the application loads fine.

When I visit the URLs as (note the missing trailing slash):

  • http://localhost:52000/AngularWebApp
  • http://myserver.domain/AngularWebApp

IIS serves the index.html web page (why? I would expect a 404!), but then Angular can't compute correctly the relative paths to the JS/CSS resources.

I tried using the Microsoft.AspNetCore.Rewrite module to Redirect the ^$ path to /index.html and it works, but it also rewrites the originally working requests, giving an ugly flash in the address bar:

http://localhost:52000/AngularWebApp/ => http://localhost:52000/AngularWebApp/index.html => http://localhost:52000/AngularWebApp/#/dashboard

I tried to redirect to #/ but Chrome stops the requests with ERR_TOO_MANY_REDIRECTS.

Is there any solution to this problem? Please note that I would like a general solution which will allow me to publish the web app either under the subfolder or under its own domain without rebuilding the application.

Relevant snippets:

Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
...
app.UseRewriter(new RewriteOptions()
   .AddRedirect(@"^$", "/index.html", (int)HttpStatusCode.MovedPermanently));

app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(...);
app.UseSpa(...);
...
}

index.html

<base href="./">

Thanks in advance for your help

like image 252
Luca Leonardo Scorcia Avatar asked Nov 07 '18 20:11

Luca Leonardo Scorcia


People also ask

What is src folder in angular?

src folder: This is the folder which contains the main code files related to your angular application. app folder: The app folder contains the files, you have created for app components.

How do I bundle an angular app for production?

ng build: This command compiles an angular application/library into an output directory named dist at the given path. This command is used when you're ready to build our application and deploy it. The CLI analyzes the application and makes the files while optimizing it to its best.

Can we deploy angular app in Tomcat?

To deploy an angular application in tomcat we need to build the application using the ng tool. For this demo, I am going to build a simple default angular application using below command. To create an angular application run the following command in command prompt as shown below.

Where can I deploy my angular app?

Deploy to GitHub Pageslink To deploy your Angular application to GitHub Pages, complete the following steps: Create a GitHub repository for your project. When you paste these commands from GitHub, they run automatically. Create and check out a git branch named gh-pages .


1 Answers

After examining the code of the Redirect middleware at https://github.com/aspnet/BasicMiddleware/blob/268290a8b56fe44d0e03cbd69d78ba7a17b4f2c1/src/Microsoft.AspNetCore.Rewrite/Internal/RedirectRule.cs#L47 it is clear that the provided Redirect middleware does not allow redirecting the empty path ('') without also redirecting the root ('/') path.

However taking inspiration from that code it was easy to build a custom rewrite rule that does just what I need:

// Load the index.html page when the url is invoked without the ending '/'
// Avoids problems with Angular when loading http://domain/AngularWebApp instead of http://domain/AngularWebApp/
app.UseRewriter(new RewriteOptions().Add(rewriteContext =>
    {
        var request = rewriteContext.HttpContext.Request;
        if (request.Path == PathString.Empty)
        {
            rewriteContext.HttpContext.Response.Redirect(request.PathBase + '/', true);
            rewriteContext.Result = RuleResult.EndResponse;
        }
    }));

Now the Angular web app loads correctly either when deployed on its own root domain or under a subfolder, even if the user invokes it without the trailing slash character.

like image 113
Luca Leonardo Scorcia Avatar answered Sep 24 '22 05:09

Luca Leonardo Scorcia