How to make Angular CLI built app work from a subfolder

Angular CLI, along with many boilerplate generating tools for other frameworks, insists on outputting the built code in a way that will work only on the top-level domain. I can't understand the reason for this, and definitively is not working well with quick&drity example apps you would like to show anywhere easily.

In this article, I'll show you how to make angular build code in a way that you can just drop on any level of subfolders & it will work.

The problem

After generating your application with:

$ npx -p @angular/cli ng new my-app

when you build your app with:

$ npm run build

you will get the dist/my-app/index.html file with:

<!DOCTYPE html><html lang="en"><head>
  <meta charset="utf-8">
  <title>MyApp</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.31d6cfe0d16ae931b73c.css"></head>
<body>
  <app-root></app-root>
<script src="runtime.97e25c2126edd0d76e43.js" defer></script><script src="polyfills.cb52f48ffd1aee6e8d09.js" defer></script><script src="main.f5cfb581cea2faefeeff.js" defer></script>

</body></html>

Although src="runtime... looks OK, and it seems it should be working in the browser, when we visit localhost/my-app/dist/my-app, we see nothing else but a white screen. That's because there is:

  <base href="/">

Which sets the context for all location references to the absolute location on our current domain. If you change it manually to <base href="./">, all should work fine - now the only thing is to set it in a way that will not require manual tweaks after every build.

The solution

There are 2 possible solutions - use the CLI parameter, or set the value in the angular.json file.

CLI parameter

angular build accepts --base-href param that allows us to override this value. Adding it manually every time would be a lot of a hassle, so the best to set it in the package.json:

{
  ...
  "scripts": {
    ...
    "build": "ng build --base-href='./'",
    ...
  }
  ...

Then, whenever we run npm run build, the value is set correctly.

Angulars json configuration

If the CLI param feels a bit hacky to you, you can set the value in the angular.json config:

{
  ...
  "projects": {
    "my-app": {
      ...
      "architect": {
        "build": {
          ...
          "options": {
            ...
            "baseHref": "./"
            }
  ...

I cannot find it in the official documentation, but it's working & it's recognized by angular.json validation.

Summary

In this article, we have seen how to set up Angular CLI generate app to work from a subfolder. With one or the other solution in place, your built app should look like:

Screenshot 2021-07-18 at 08-11-15 MyApp.png