Skip to main content
Version: v9

Updating from Ionic 8 to 9

note

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.

Breaking Changes

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

  1. Ionic 9 supports Angular 17+. Update to the latest version of Angular by following the Angular Update Guide.

  2. 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

  1. Ionic 9 supports React 18+. Update to the latest version of React:
npm install react@latest react-dom@latest
  1. Update to the latest version of Ionic 9:
npm install @ionic/react@latest @ionic/react-router@latest

React Router

  1. Ionic 9 supports React Router 6. Update to version 6 of React Router:
npm install react-router@6 react-router-dom@6
  1. If you have @types/react-router or @types/react-router-dom installed, remove them. React Router 6 includes its own TypeScript definitions:
npm uninstall @types/react-router @types/react-router-dom

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) or useIonRouter
  • match.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

  1. Ionic 9 supports Vue 3.0.6+. Update to the latest version of Vue:
npm install vue@latest vue-router@latest
  1. Update to the latest version of Ionic 9:
npm install @ionic/vue@latest @ionic/vue-router@latest

Core

  1. 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.