angular - How to dynamically change the content in the index.html file when running the ng-build command

In angular.json you can configure the index file to be used (I'm using Angular 8):

"projects": {
    "projectName": {
        "architect": {
            "build": {
                "options": {
                    "index": "src/index.html", // this is the default location (also for ng serve)
                    "configurations": {
                        "production": {
                            "index": "index-prod.html" // this is the prod version (you can also link it to /prod/index.html or whatever: it will be placed in the dist root folder with the provided name)
                        },
                        "development": {
                            "index": "index-whatever.html" // this is the version for ng build --configuration=development`
                        }
                    }
                }
            }/*, UPDATED: THIS DOESN'T WORK
            "serve": {
                "index": "dev/index.html" // file to be used in ng serve
            }*/
        }
    }
}

AFAIK none of those "index"s is mandatory, except the first

Sidenote: this is what I just tried with some tries, builds and ng serves. I didn't find it in any documentation.

Check it out and let me know.

===========

UPDATE 19 Oct '19: I noticed that the configuration reported above still uses src/index.html also for serve on "@angular/cli": "^8.3.6", "@angular/compiler-cli": "^8.2.8". Looks like there is no override for serve itself. My question is: should serve always inherit base index configuration?

Trying to dig a bit more I found this: https://github.com/angular/angular-cli/issues/14599

There is an example of how it should work with the new CLI, but attempting to replace the

"development": {
    index": "index-whatever.html"
}

with a

"development": {
    index": {
        "input": "index-whatever.html"
    }
}

and building, it gives me a Schema validation failed with the following errors: Data path ".index" should be string.

===========

UPDATE 10 Apr '20:

I just noticed that in October's update I missed a quote in the latest code snippet. I don't remember whether it was copied directly from my code - hence the reported error could be related to that - or it was a mistype when I attempted to rewrite the code. I'll check again whenever I'll have time


For current versions of Angular from v6.1.0-beta.2 on, you can use the fileReplacements value in the angular.json file configurations as detailed in this answer: https://stackoverflow.com/a/57274333/228429 by @massic80.

More info here: https://github.com/angular/angular-cli/issues/4451#issuecomment-395651237

For older versions before v6.1.0-beta.2, Angular CLI does not provide any such feature. But you can use environment variables to inject proper scripts dynamically on run time.

Eg:

main.ts

import { env } from './environments/environment';

if (env.production) {
   const script = document.createElement('script');
   script.src = https://my-site.net/prod.js
   document.head.appendChild(script);
} else {
   const script = document.createElement('script');
   script.src = https://my-site.net/dev.js
   document.head.appendChild(script);
}

Read more here: https://github.com/angular/angular-cli/issues/4451#issuecomment-285329985


If you want to stick with standard src/index.html while serving locally by want to have specialised index.html files per production / test configuration (as it was in my case, where different Google Analytics code chunks have been to be applied) do it simply:

  1. Create separate directories each holding a dedicated version of index.html. Eg.:

src/prod/index.html src/test/index.html

  1. Let angular.json know about them, per configuration:
"configurations": {
    "production": {
        "fileReplacements": [
            {
                "replace": "src/environments/environment.ts",
                "with": "src/environments/environment.prod.ts"
            }
        ],
        "index": "src/index/prod/index.html",
        // other stuff
    },
    "test": { 
        "fileReplacements": [
            {
                "replace": "src/environments/environment.ts",
                "with": "src/environments/environment.test.ts"
            }
        ],
        "index": "src/index/test/index.html",
        // other stuff
    }
    // other stuff
}