35

I have simple app with one component that expects certain parameters from url. there is only one route in the application:

const appRoutes: Routes = 
                       path: 'hero/:userId/:languageId',component: HeroWidgetComponent }];

In the Index.html, I have this in the header <base href="/">

I am using webpack and the application runs fine on development environment, when browsing the url: http://localhost:4000/hero/1/1.

However, when building the app for production and getting the distribution files, then hosting that on IIS. I get the following Error when trying to browse the same url:

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

The application works fine if I remove all the routing and just browse: http:localhost:4200 on the IIS.

2
  • 1
    Your IIS server needs to be configured properly so that all angular routes are redirected to index.html (or the html file where the angular app is triggered from). Unfortunately I'm no IIS server expert, so I can't give you a real answer how to do that exactly. Commented May 4, 2017 at 14:43
  • It's also worth noting that many hosting providers allow you to set up custom error pages using their dashboards in which case you can simply add / as the path for 404 errors so all routes are handled by your Angular app. Commented Oct 3, 2023 at 9:23

6 Answers 6

79

We have to make IIS fall back to index.html by adding a rewrite rule.

Step 1: Install IIS URL Rewrite Module

Step 2: Add a rewrite rule to web.config

   <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="AngularJS Routes" stopProcessing="true">
              <match url=".*" />
              <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />   
              </conditions>
              <action type="Rewrite" url="/" />
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
    </configuration>
Sign up to request clarification or add additional context in comments.

9 Comments

I am hosting on Godaddy. I followed this, but didn't have to install IIS URL Rewrite, and it just works.
@mapussah, probably because this module is already installed.
Hi, I follow the same step, but it still goes to 404 error in my local IiS. I downloaded the URL rewrite from the given link in answer, After executing it says already installed. Can you please share what I am missing? I have develop application using Angular 4, @angular/cli, C# Web API, VS 2015.
@mapussah may be because you created Visual Studio angular template which comes with web.config file
how to make this change under IIS website configuration instead of having to have web.config file
|
7

STEP 3: add web.config link to angular.json: (because after ng build it will skipped)

"architect": {
                "build": {
                    "builder": "@angular-devkit/build-angular:browser",
                    "options": {
                         ..........
                        "assets": [
                            "src/favicon.ico",
                            "src/assets",
                            **"src/web.config"**
                        ]

Comments

5

Without installing IIS URL Rewrite

As @tftd explained in the comment to the question, IIS needs to know how to handle the request when it cannot find a matching file or folder.

You can configure IIS to return index.html whenever a route with path and/or parameters (also known as a deep link) is requested.

Manually in IIS

  1. Select your site In IIS Manager
  2. Open Error Pages icon in IIS section
  3. Open Status Code 404 list item
  4. Select Execute URL on this site radio button
  5. Enter your SPA root path, ex: '/index.html'
  6. Click OK Edit Custom Error

There is no need to restart the application pool, just browse to your deep link. The server will respond with status code 200. (tested on Windows Server 2016 with IIS 10 in 2021).

If your SPA is not rooted at /index.html, enter the folder or file where your app is rooted in step 5.

The manual process described above adds or changes httpErrors section of the web.config:

<configuration>
    <system.webServer>
        <httpErrors>
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" prefixLanguageFilePath="" path="/index.html" responseMode="ExecuteURL" />
        </httpErrors>
    </system.webServer>
</configuration>

To avoid losing this change after the next deployment, make sure your release pipeline keeps the httpErrors section like above in the web.config.

This works for both Angular and React apps.

1 Comment

worked for me with a simple addition I am having web-dev application under default website and just replaced /index.html with /web-dev/ and worked now when refresh browser it keeps me on same route/page
4

If you are using an IIS application like myApp below your default web site (then the URL to your application should have the syntax http://localhost/myApp/my-angular-route), then you should try to modify the action to

<action type="Rewrite" url="/myApp/"/>;

Then it works for my environment without any problems.

Step by step instructions can be found here: https://blogs.msdn.microsoft.com/premier_developer/2017/06/14/tips-for-running-an-angular-app-in-iis/

Comments

3

Modify angular routing by adding # after baseurl:

http://localhost:4200/yourApp#/subPageRoute

In app-routing.module.ts on line with RouterModule.forRoot add ", { useHash: true }"

RouterModule.forRoot(routes, { useHash: true })

This way IIS thinks everything after # is some id on page and ignores it.

1 Comment

Although this solution is outdated, it can in any case be integrated into a project that is on a shared server that you will not be able to install "Rewrite"
2

Copy and paste this web.config to your root folder

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
 
  <rewrite>
    <rules>
      <rule name="Angular Routes" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="./index.html" />
      </rule>
    </rules>
  </rewrite>
 
</system.webServer>
</configuration>

2 Comments

This answer could be improved. Can you provide why OP should paste this config? Why should this work and solve the problem?
The bundle built does not have a web.config. Create one and copy the code in this post over. It is the same as the web.config in your source code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.