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