angular: Angular 2 Router can't handle refresh if base href is not / (root) in virtual directory in IIS

I’m submitting a … (check one with “x”)

[ x ] bug report

Current behavior When a site is not hosted at http://localhost/ , but is hosted at http://localhost/SomeVirtualDirectory, then the router gets confused on refresh. This is when the base href is set to something other than /

Expected/desired behavior Router should work correctly hosted in IIS with Url Rewrite correctly configured. It should work initially and on a refreshed request.

Reproduction of the problem Host your dist folder in IIS in a virtual directory called “SiteA”. This angular 2 app should have routes, i.e. site/dashboard. Install Url Rewite in IIS. Configure Url Rewrite with these rules (put web.config with these contents next to index.html):

<?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>

Change index.html to set base href <base href="/SiteA/"> Browse to http://localhost/SiteA. See that the site comes up correctly at the default route, say, localhost/SiteA/site/dashboard. Click refresh in the browser. See that it is redirected to the IIS home page.

What is the expected behavior? Angular 2 and IIS should work together. Angular should be able to route appropriately inside of IIS in something other than the root web site.

What is the motivation / use case for changing the behavior? Hosting multiple, named sites on a single machine in an environment with other IIS hosted sites. Do not want to add the overhead of an additional web server.

Please tell us about your environment:

  • Angular version: 2.0.0-rc.5
  • Browser: all
  • Language: TypeScript -> ES5
  • * IIS Version:* 8.5 with Url Rewrite installed

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 8
  • Comments: 18

Most upvoted comments

Please let me know if it helps, as we are about to migrate our app. The URL for redirection should include the Virtual Directory alias, or else you would be redirecting to the website root path. I also included a condition to skip redirection when the URI is already OK.

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

Also, we are providing the APP_BASE_REF on bootstrap:

provide(APP_BASE_HREF, { useValue: '/SiteA' }),

For nginx:

    location /subfolder/myapp/ {
        try_files $uri /subfolder/myapp/index.html;
    }

    location /subfolder2/myapp/ {
        try_files $uri /subfolder2/myapp/index.html;
    }