Repository: angular
Issue: Template HMR broken with Ionic, showing old template even after full page reload
Labels: area: compiler

### Which @angular/* package(s) are the source of the bug?

compiler, compiler-cli, core

### Is this a regression?

No

### Description

First off, I'm not sure if this is a bug with Angular, Ionic, or both. I've created the issue here because this is still an experimental feature.

I've created a default [Ionic](https://github.com/ionic-team/ionic-framework) starter project and enabled the experimental template HMR with `NG_HMR_TEMPLATES=1`. I marked 3 different places within the app to test HMR in, all showing different behavior:

- `folder.page.html`: Testcase 1: Page component (directly navigated to)
- `my-custom-component.component.html`: Testcase 2: Nested custom component
- `app.component.html`: Testcase 3: Outside of ion-router-outlet

Details of the behavior are below and in comments in the files themselves, but a quick summary:

- Within the `ion-router-outlet`
  - HMR does not work _live_ (for components currently visible on the page when the changes are made)
  - HMR does not work _the first time the component is rendered_ after a full page reload, instead showing an outdated version of the component from the compiled chunk
    - this may include multiple places within the application (due to component caching?)
- Outside the `ion-router-outlet` HMR works as expected, both live and after a full page reload

### Please provide a link to a minimal reproduction of the bug

https://github.com/ReneZeidler/hmr-ionic-bug

### Please provide the exception or error you saw

```true

```

### Please provide the environment you discovered this bug in (run `ng version`)

```true
Angular CLI: 19.0.6
Node: 20.18.1
Package Manager: npm 11.0.0
OS: linux x64

Angular: 19.0.5
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1900.6
@angular-devkit/build-angular   19.0.6
@angular-devkit/core            19.0.6
@angular-devkit/schematics      19.0.6
@angular/cli                    19.0.6
@schematics/angular             19.0.6
rxjs                            7.8.1
typescript                      5.6.3
zone.js                         0.15.0
```

### Anything else?

### Reproduction

1. Clone the minimal reproduction repo
2. Run `npm start`
3. Go through each test case in turn by opening the corresponding template file and uncommenting the marked line
4. To start again from a clean slate, comment out all of the lines again and restart the dev server

### Testcases

Open the details to view my observations and conclusions for each testcase:

<details><summary>Testcase 1 (folder.page.html): Page component (directly navigated to)</summary>
<p>

Observations:
* The text does NOT appear on the current page
* Navigating to a different page in the sidebar causes the text to appear
* After navigating back to the first page in the sidebar, the text is still there
* After a full page reload the text does NOT appear on the current page
* Navigating to a different page causes the text to appear again
* Forcing a full rebuild of the chunk by changing the corresponding .ts file of this component "bakes" in the current version of the template as the one that is visible after a full page reload

Conclusions:
* HMR template changes are not applied live to components currently visible on the page
* After a full page reload, the first time a component is rendered it uses the original template from the compiled chunk, missing HMR changes
* Subsequent renders of the component have the HMR changes applied
</p>
</details>

<details><summary>Testcase 2 (my-custom-component.component.html): Nested custom component</summary>
<p>

Observations:
* The text does NOT appear on the current page
* The text still does NOT appear after navigating to a different page in the sidebar
* The text still does NOT appear after a full page reload
* Forcing a full rebuild of the chunk by changing the corresponding .ts file of this component "bakes" in the current version of the template as the one that is visible after a full page reload

Conclusions:
* It seems like the nested component is only rendered once across all pages (caching?), and that render uses the outdated version of the template
</p>
</details>

<details><summary>Testcase 3 (app.component.html): Outside of ion-router-outlet</summary>
<p>

Observations:
* The text DOES appear live on the current page
* The text DOES appear after a full page reload

Conclusions:
* HMR works as expected outside of ion-router-outlet
</p>
</details>