bug: vue router outlet throws when a superseded page mounts after the route moved on #31569
Description
Prerequisites
- I have read the Contributing Guidelines.
- I agree to follow the Code of Conduct.
- I have searched for existing issues that already report this problem, without success.
Ionic Framework Version
v8.x, v9.x
Current Behavior
When a page in IonRouterOutlet mounts its <ion-page> after the route has already moved on to a newer page, and before the newer page has mounted its own <ion-page>, the late page's registerCallback calls handlePageTransition(). That function reads the current route, so it runs the transition for the newer page, whose ionPageElement is still undefined. It logs the "does not have the required <ion-page> component" warning for the newer page and then throws:
TypeError: Cannot read properties of undefined (reading 'classList')
at isViewVisible (IonRouterOutlet.ts)
at handlePageTransition (IonRouterOutlet.ts)
at enteringViewItem.registerCallback (IonRouterOutlet.ts)
at registerIonPage (IonRouterOutlet.ts)
at IonPage.mounted (IonPage.ts)
This can happen whenever pages mount asynchronously (async components, async setup) and the user navigates again before the first page has finished.
Expected Behavior
A page that registers after the route moved on should not run the transition for the newer page. The newer page should run its own transition once its <ion-page> registers, without the warning or the error.
Steps to Reproduce
- Render an
IonRouterOutletwith the routes/,/listand/detail, where/listand/detailare async components (defineAsyncComponent) that resolve on demand. - Navigate to
/list, then to/detailbefore either component has loaded. - Let
/listfinish loading before/detail. - Observe the missing
<ion-page>warning for/detailand the TypeError above.
Code Reproduction URL
No standalone reproduction app yet. The linked PR adds a unit test to packages/vue/test/base/tests/unit/routing.spec.ts that follows these steps with the real router and outlet and fails on main with this TypeError.
Ionic Info
Seen with @ionic/vue 8.8.5 in a Nuxt + Capacitor app (not an Ionic CLI project, so no ionic info output). The same code is unchanged on main (@ionic/vue 9.0.7).
Additional Information
Suggested fix: in the registerCallback set up by setupViewItem, only call handlePageTransition() when the view item for the current route is the entering item, or when that item has no pending registerCallback. I will open a PR with this change and the test.
Activity
thetaPC commentedon Oct 22, 2026
Thanks for the report, and for the PR!
Verified on 9.0.9. When a page's
<ion-page>registers after the route has already moved on,IonRouterOutletruns the transition for the current route, which is the newer page that has no<ion-page>yet. That causes the warning and theTypeError. It also leaves the page you navigated from visible underneath the newer page once that page loads. This happens withdefineAsyncComponentroute components, with asyncsetup()pages rendered under a<Suspense>(as in Nuxt), and with pages that render<ion-page>behind av-if.Tracked as a bug in
@ionic/vue.