SteGriff

Blog

Next & Previous

Host a static site and an API on one IIS site with sub applications

If you want a static site frontend and an API at the same domain, you can do it with IIS.

Just IIS Things:

IIS has Sites, Applications, and Virtual Directories.

The docs for hosting and deploying ASP.Net mention:

IIS Virtual Directories aren’t supported with ASP.NET Core apps. An app can be hosted as a sub-application.

Where to set it up

You can set it up in the IIS GUI, but the source of truth is actually the global IIS config in applicationHost.config, which by default lives in C:\Windows\System32\inetsrv\config\applicationHost.config

(If you have set up IIS shared config then you probably already know where your config lives instead).

Take this snippet:

<site name="dinosaurs.local" id="5">
    <application path="/" applicationPool="dinosaurs.local">
        <virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot\dinosaurs.local" />
    </application>
    <application path="/api" applicationPool="dinosaurs.local">
        <virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot\dinosaurs.local\api" />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:80:dinosaurs.local" />
    </bindings>
</site>

Here we have a site called dinosaurs.local, containing two Applications: one at the root path, one at the /api path. Each app contains just one virtual directory (the root) which points to the folder on disk.

What can you do with it?

You can deploy static site files, like an index.htm to wwwroot\dinosaurs.local, and deploy an ASP.Net (±Core) site to the wwwroot\dinosaurs.local\api dir, and you will be able to call the /api route from your frontend code with no mess, no fuss, no octopus.

If you have a SPA which requires a “redirect all” kind of rule, you will need to tune it to exclude /api/* routes! Exercise left to the reader.

Why

The big reason to deploy this way is to eliminate problems with CORS and cross-site cookies. Safari on iOS is really stingy about so-called “third party cookies”, which are blocked by default; it’s even caused me mysterious problems with two sites with different subdomains on the same host. Beware!

Architecturally, if you’re doing a backend for frontend, it’s nice to keep it at the same host so you can do samesite cookies and stuff.

Okay, that’s the post. Later, nerds! 📬🏓