How do I configure IIS for URL Rewriting an AngularJS application in HTML5 mode? How do I configure IIS for URL Rewriting an AngularJS application in HTML5 mode? angularjs angularjs

How do I configure IIS for URL Rewriting an AngularJS application in HTML5 mode?


I write out a rule in web.config after $locationProvider.html5Mode(true) is set in app.js.

Hope, helps someone out.

  <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" />            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />          </conditions>          <action type="Rewrite" url="/" />        </rule>      </rules>    </rewrite>  </system.webServer>

In my index.html I added this to <head>

<base href="/">

Don't forget to install IIS URL Rewrite on server.

Also if you use Web API and IIS, this will work if your API is at www.yourdomain.com/api because of the third input (third line of condition).


The IIS inbound rules as shown in the question DO work. I had to clear the browser cache and add the following line in the top of my <head> section of the index.html page:

<base href="/myApplication/app/" />

This is because I have more than one application in localhost and so requests to other partials were being taken to localhost/app/view1 instead of localhost/myApplication/app/view1

Hopefully this helps someone!


The issue with only having these two conditions:

  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />

is that they work only as long as the {REQUEST_FILENAME} exists physically on disk. This means that there can be scenarios where a request for an incorrectly named partial view would return the root page instead of a 404 which would cause angular to be loaded twice (and in certain scenarios it can cause a nasty infinite loop).

Thus, some safe "fallback" rules would be recommended to avoid these hard to troubleshoot issues:

  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.html$" negate="true" />  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.js$" negate="true" />  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.css$" negate="true" />

or a condition that matches any file ending:

<conditions>  <!-- ... -->  <add input="{REQUEST_FILENAME}" pattern=".*\.[\d\w]+$" negate="true" /></conditions>