-
Notifications
You must be signed in to change notification settings - Fork 13.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug: angular, moving elements inside of ion-router-outlet causes dom tree mismatch during hydration #28534
Comments
Thanks for the issue! This issue has been labeled as Please reproduce this issue in an Ionic starter application and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed. If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue. For a guide on how to create a good reproduction, see our Contributing Guide. |
Can you provide a reproduction we can run? SSR issues can be a bit tricky, so having a full sample will save us a lot of time. |
Hi @liamdebeasi , thanks for your quick response! I have created a repo here: https://github.com/bashoogzaad/ionic-ssr-test |
Does the issue persist if you use |
I am not able to use that, that one is based on ngModules and I am using Angular Standalone (as the preferred solution nowadays). And Angular SSR should work out of the box in v17 (maybe this is related: https://forum.ionicframework.com/t/angular-universal-update/213522/2) |
You should be able to use NgModules in a standalone application still: https://angular.io/guide/standalone-components#using-existing-ngmodules-in-a-standalone-component. The module would be passed to the imports array in your app component. Also, I'm not able to reproduce the issue in your sample repo:
Can you make sure there's an |
Excuse me, I have added it now! |
Thanks! So the problem appears to be that we are moving children inside of To work around this, we move the element inside of ionic-framework/packages/angular/common/src/directives/navigation/stack-controller.ts Line 278 in 9d57758
This causes a DOM tree mismatch during hydration because Angular was expecting the view's component to be a sibling of However, this would mean setting |
Also wanted to set appropriate expectations: Unfortunately, this is not something we can address as the Angular team needs to add support for Web Components to the |
Relevant link: angular/angular#52275 |
@liamdebeasi might be worth noting that the Lit framework team, which also uses web components, is claiming that they are working on SSR support now, according to here. https://lit.dev/docs/ssr/overview/ Maybe the Ionic Team could consider a similar approach? |
We'd probably still advocate for getting Web Component support in |
Does this mean that server side rendering is not yet possible? |
Issue number: resolves #28534 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> Page views in Ionic need to be rendered as a child of `ion-router-outlet` in order for page transitions and swipe to go back to function correctly. However, Angular always inserts components as siblings of the insertion point. Previously, the insertion point was `ion-router-outlet` (the host element). This meant that page views were mounted as siblings of `ion-router-outlet`. We then added code to move the component inside of `ion-router-outlet`. This caused two issues: 1. A DOM tree mismatch during hydration (the linked issue) because hydration is expecting the page view to be a sibling of the router outlet, but Ionic moves the view around in the DOM. 2. A performance issue where all components effectively have `connectedCallback` fired twice. This callback runs when the component is added to the DOM. On initial mount, `connectedCallback` for each component runs. Once the page view is moved, the elements are removed from the DOM (thus causing `disconnectedCallback` to run), and then added to the correct location in the DOM which causes `connectedCallback` to run again. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - IonRouterOutlet now renders a `ng-container`. This appears as a comment in the DOM inside of `ion-router-outlet`. This comment is used as the injection point for adding new views. The new views are added as siblings of the comment, but since the comment is inside of `ion-router-outlet` then the views themselves are inside of `ion-router-outlet` too. ## Does this introduce a breaking change? - [ ] Yes - [x] No This doesn't cause any known breaking changes. However, the placement of views is pretty critical to the functionality of Ionic, so I wanted to ship this in a major release so we have a solid public testing period before the code is considered stable. We already have test coverage that verifies page views are mounted in the correct order, so I did not add more tests for this. <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev build: 7.6.2-dev.11704390532.1202188d Testing: 1. Clone and install dependencies for https://github.com/bashoogzaad/ionic-ssr-test 2. Run `npm run dev:ssr`. 3. Open app in a browser. Observe that error noted in #28534 (comment) appears. 4. Install dev build. 5. Run `npm run dev:ssr`. Observe that the error noted in the original issue does not appear. Note: The Angular SSR package does not support Web Components. As a result, there are other errors you will encounter. However, I still think it's worth fixing this issue a) in the event that the Angular SSR package adds support for Web Components and b) to get the performance gain of not having to re-mount components.
Thanks for the issue. This has been resolved via #28544, and a fix will be available in an upcoming release of Ionic Framework. We chose to ship this in a major release of Ionic Framework to account for any unexpected behavior changes. There should be no behavior changes, but how views are mounted are important to the functionality of page transitions and swipe to go back, so we'd like a public testing period.
You can use the |
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out. |
Prerequisites
Ionic Framework Version
v7.x
Current Behavior
When starting a new project with
ionic start
with the optionAngular Standalone
, then@angular/ssr
is not working correctly. When adding@angular/ssr
, the Angular CLI is adding files, such asapp.config.server.ts
. This file is referring toapp.config.ts
. This file is however not present, so you have to create is. Not a big deal.However, after
npm run dev:serve
, the application is running, but gets an error:This is just a starter project with 'list' prefill.
Expected Behavior
The application should run correctly, and must be able to hydrate the components.
Steps to Reproduce
Code Reproduction URL
No response
Ionic Info
Ionic:
Ionic CLI : 7.1.5 (/usr/local/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 7.5.4
@angular-devkit/build-angular : 17.0.0
@angular-devkit/schematics : 17.0.0
@angular/cli : 17.0.0
@ionic/angular-toolkit : 9.0.0
Capacitor:
Capacitor CLI : 5.5.1
@capacitor/android : not installed
@capacitor/core : 5.5.1
@capacitor/ios : not installed
Utility:
cordova-res : not installed globally
native-run (update available: 2.0.0) : 1.7.4
System:
NodeJS : v18.18.2 (/usr/local/Cellar/node@18/18.18.2/bin/node)
npm : 9.8.1
OS : macOS Unknown
Additional Information
No response
The text was updated successfully, but these errors were encountered: