Updating from Ionic 8 to 9
This guide assumes that you have already updated your app to the latest version of Ionic 8. Make sure you have followed the Upgrading to Ionic 8 Guide before starting this guide.
For a complete list of breaking changes from Ionic 8 to Ionic 9, please refer to the breaking changes document in the Ionic Framework repository.
Getting Started
Angular
-
Ionic 9 supports Angular 17+. Update to the latest version of Angular by following the Angular Update Guide.
-
Update to the latest version of Ionic 9:
npm install @ionic/angular@latest
If you are using Ionic Angular Server and Ionic Angular Toolkit, be sure to update those as well:
npm install @ionic/angular@latest @ionic/angular-server@latest @ionic/angular-toolkit@latest
React
- Ionic 9 supports React 18+. Update to the latest version of React:
npm install react@latest react-dom@latest
- Update to the latest version of Ionic 9:
npm install @ionic/react@latest @ionic/react-router@latest
- Update to React Router v6:
npm install react-router@6 react-router-dom@6
If you have @types/react-router or @types/react-router-dom installed, remove them. React Router v6 includes its own TypeScript definitions:
npm uninstall @types/react-router @types/react-router-dom
React Router v6 Migration
Ionic React now requires React Router v6, which has a different API from v5. Below are the key changes you'll need to make:
Route Definition Changes
The component and render props have been replaced with the element prop, which accepts JSX:
- <Route path="/home" component={Home} exact />
+ <Route path="/home" element={<Home />} />
Routes can no longer render content via nested children. All route content must be passed through the element prop:
- <Route path="/">
- <Home />
- </Route>
+ <Route path="/" element={<Home />} />
Redirect Changes
The <Redirect> component has been replaced with <Navigate>:
- import { Redirect } from 'react-router-dom';
+ import { Navigate } from 'react-router-dom';
- <Redirect to="/home" />
+ <Navigate to="/home" replace />
Nested Route Paths
Routes that contain nested routes or child IonRouterOutlet components need a /* suffix to match sub-paths:
- <Route path="/tabs" element={<Tabs />} />
+ <Route path="/tabs/*" element={<Tabs />} />
Accessing Route Parameters
Route parameters are now accessed via the useParams hook instead of props:
- import { RouteComponentProps } from 'react-router-dom';
+ import { useParams } from 'react-router-dom';
- const MyComponent: React.FC<RouteComponentProps<{ id: string }>> = ({ match }) => {
- const id = match.params.id;
+ const MyComponent: React.FC = () => {
+ const { id } = useParams<{ id: string }>();
RouteComponentProps Removed
The RouteComponentProps type and its history, location, and match props are no longer available in React Router v6. Use the equivalent hooks instead:
history->useNavigate(see below) oruseIonRoutermatch.params->useParams(covered above)location->useLocation
- import { RouteComponentProps } from 'react-router-dom';
+ import { useNavigate, useLocation } from 'react-router-dom';
+ import { useIonRouter } from '@ionic/react';
- const MyComponent: React.FC<RouteComponentProps> = ({ history, location }) => {
- history.push('/path');
- history.replace('/path');
- history.goBack();
- console.log(location.pathname);
+ const MyComponent: React.FC = () => {
+ const navigate = useNavigate();
+ const router = useIonRouter();
+ const location = useLocation();
+ // In an event handler or useEffect:
+ navigate('/path');
+ navigate('/path', { replace: true });
+ router.goBack();
+ console.log(location.pathname);
Exact Prop Removed
The exact prop is no longer needed. React Router v6 routes match exactly by default. To match sub-paths, use a /* suffix on the path:
- <Route path="/home" exact />
+ <Route path="/home" />
Render Prop Removed
The render prop has been replaced with the element prop:
- <Route path="/foo" render={(props) => <Foo {...props} />} />
+ <Route path="/foo" element={<Foo />} />
Programmatic Navigation
The useHistory hook has been replaced with useNavigate:
- import { useHistory } from 'react-router-dom';
+ import { useNavigate } from 'react-router-dom';
+ import { useIonRouter } from '@ionic/react';
- const history = useHistory();
+ const navigate = useNavigate();
+ const router = useIonRouter();
- history.push('/path');
+ navigate('/path');
- history.replace('/path');
+ navigate('/path', { replace: true });
- history.goBack();
+ router.goBack();
Custom History Prop Removed
The history prop has been removed from IonReactRouter, IonReactHashRouter, and IonReactMemoryRouter. React Router v6 routers no longer accept custom history objects.
- import { createBrowserHistory } from 'history';
- const history = createBrowserHistory();
- <IonReactRouter history={history}>
+ <IonReactRouter>
For IonReactMemoryRouter (commonly used in tests), use initialEntries instead:
- import { createMemoryHistory } from 'history';
- const history = createMemoryHistory({ initialEntries: ['/start'] });
- <IonReactMemoryRouter history={history}>
+ <IonReactMemoryRouter initialEntries={['/start']}>
IonRedirect Removed
The IonRedirect component has been removed. Use React Router's <Navigate> component instead:
- import { IonRedirect } from '@ionic/react';
- <IonRedirect path="/old" to="/new" exact />
+ import { Navigate } from 'react-router-dom';
+ <Route path="/old" element={<Navigate to="/new" replace />} />
Path Regex Constraints Removed
React Router v6 no longer supports regex constraints in path parameters (e.g., /:tab(sessions)). Use literal paths instead:
- <Route path="/:tab(sessions)" component={SessionsPage} />
- <Route path="/:tab(sessions)/:id" component={SessionDetail} />
+ <Route path="/sessions" element={<SessionsPage />} />
+ <Route path="/sessions/:id" element={<SessionDetail />} />
IonRoute API Changes
The IonRoute component follows the same API changes as React Router's <Route>. The render prop has been replaced with element, and the exact prop has been removed:
- <IonRoute path="/foo" exact render={(props) => <Foo {...props} />} />
+ <IonRoute path="/foo" element={<Foo />} />
For more information on migrating from React Router v5 to v6, refer to the React Router v6 Upgrade Guide.
Vue
- Ionic 9 supports Vue 3.0.6+. Update to the latest version of Vue:
npm install vue@latest vue-router@latest
- Update to the latest version of Ionic 9:
npm install @ionic/vue@latest @ionic/vue-router@latest
Core
- Update to the latest version of Ionic 9:
npm install @ionic/core@latest
Need Help Upgrading?
Be sure to look at the Ionic 9 Breaking Changes Guide for the complete list of breaking changes. This upgrade guide only covers changes that require action from developers.
If you need help upgrading, please post a thread on the Ionic Forum.