Skip to content

Commit bee3752

Browse files
authored
docs(react-router): updating docs to reflect react router 6 changes (#4422)
* docs(react-router): working on v9 migration docs for react router * docs(react-router): update navigation guide and expand v5-to-v6 migration guide * chore(lint): running lint * fix(build): fixing build error * docs(react-router): fixing several issues * docs(react-router): converting playground example to rr6 * docs(react-router): updating dependencies, reverting phrasing change
1 parent 1307564 commit bee3752

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+1710
-914
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ docs/native
88
versioned_docs/version-v*/native
99
docs/cli/commands
1010
docs/reference/glossary.md
11+
versioned_docs/version-v*/reference/glossary.md
1112

1213
static/code/stackblitz
1314

docs/react/add-to-existing.md

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -302,21 +302,20 @@ Then, create `src/pages/Home.css`:
302302

303303
:::important
304304

305-
Ionic React Router currently only supports React Router v5. You must install the following specific versions of the router packages to set up routing with Ionic React.
305+
Ionic React requires React Router v6. Install the following specific versions of the router packages to set up routing with Ionic React.
306306

307307
:::
308308

309309
Install the router packages:
310310

311311
```bash
312-
npm install @ionic/react-router react-router@5 react-router-dom@5
313-
npm install @types/react-router-dom --save-dev
312+
npm install @ionic/react-router react-router@6 react-router-dom@6
314313
```
315314

316315
Then, update `src/App.tsx` to add the routes for the Home page:
317316

318317
```tsx title="src/App.tsx"
319-
import { Redirect, Route } from 'react-router-dom';
318+
import { Route, Navigate } from 'react-router-dom';
320319
import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react';
321320
import { IonReactRouter } from '@ionic/react-router';
322321
import Home from './pages/Home';
@@ -329,12 +328,8 @@ const App: React.FC = () => (
329328
<IonApp>
330329
<IonReactRouter>
331330
<IonRouterOutlet>
332-
<Route exact path="/home">
333-
<Home />
334-
</Route>
335-
<Route exact path="/">
336-
<Redirect to="/home" />
337-
</Route>
331+
<Route path="/home" element={<Home />} />
332+
<Route path="/" element={<Navigate to="/home" replace />} />
338333
</IonRouterOutlet>
339334
</IonReactRouter>
340335
</IonApp>

docs/react/navigation.md

Lines changed: 93 additions & 158 deletions
Large diffs are not rendered by default.

docs/react/quickstart.md

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Let's walk through these files to understand the app's structure.
7878
The root of your app is defined in `App.tsx`:
7979

8080
```tsx title="src/App.tsx"
81-
import { Redirect, Route } from 'react-router-dom';
81+
import { Route, Navigate } from 'react-router-dom';
8282
import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react';
8383
import { IonReactRouter } from '@ionic/react-router';
8484
import Home from './pages/Home';
@@ -91,12 +91,8 @@ const App: React.FC = () => (
9191
<IonApp>
9292
<IonReactRouter>
9393
<IonRouterOutlet>
94-
<Route exact path="/home">
95-
<Home />
96-
</Route>
97-
<Route exact path="/">
98-
<Redirect to="/home" />
99-
</Route>
94+
<Route path="/home" element={<Home />} />
95+
<Route path="/" element={<Navigate to="/home" replace />} />
10096
</IonRouterOutlet>
10197
</IonReactRouter>
10298
</IonApp>
@@ -113,12 +109,8 @@ Routes are defined within the `IonRouterOutlet` in `App.tsx`:
113109

114110
```tsx title="src/App.tsx"
115111
<IonRouterOutlet>
116-
<Route exact path="/home">
117-
<Home />
118-
</Route>
119-
<Route exact path="/">
120-
<Redirect to="/home" />
121-
</Route>
112+
<Route path="/home" element={<Home />} />
113+
<Route path="/" element={<Navigate to="/home" replace />} />
122114
</IonRouterOutlet>
123115
```
124116

@@ -240,15 +232,9 @@ Then, add its route in `IonRouterOutlet`:
240232

241233
```tsx title="src/App.tsx"
242234
<IonRouterOutlet>
243-
<Route exact path="/home">
244-
<Home />
245-
</Route>
246-
<Route exact path="/new">
247-
<New />
248-
</Route>
249-
<Route exact path="/">
250-
<Redirect to="/home" />
251-
</Route>
235+
<Route path="/home" element={<Home />} />
236+
<Route path="/new" element={<New />} />
237+
<Route path="/" element={<Navigate to="/home" replace />} />
252238
</IonRouterOutlet>
253239
```
254240

@@ -259,7 +245,7 @@ Once that is done, update the button in `Home.tsx`:
259245
```
260246

261247
:::info
262-
Navigating can also be performed programmatically using React Router's `history` prop. See the [React Navigation documentation](/docs/react/navigation.md#navigating-using-history) for more information.
248+
Navigating can also be performed programmatically using the `useIonRouter` hook. See the [React Navigation documentation](/docs/react/navigation.md#useionrouter) for more information.
263249
:::
264250

265251
## Add Icons to the New Page

docs/react/your-first-app.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export default Tab2;
234234
Next, open `src/App.tsx`. Change the label to "Photos" and the `ellipse` icon to `images` for the middle tab button.
235235

236236
```tsx
237-
import { Redirect, Route } from 'react-router-dom';
237+
import { Route, Navigate } from 'react-router-dom';
238238
import {
239239
IonApp,
240240
IonIcon,
@@ -259,18 +259,10 @@ const App: React.FC = () => (
259259
<IonReactRouter>
260260
<IonTabs>
261261
<IonRouterOutlet>
262-
<Route exact path="/tab1">
263-
<Tab1 />
264-
</Route>
265-
<Route exact path="/tab2">
266-
<Tab2 />
267-
</Route>
268-
<Route path="/tab3">
269-
<Tab3 />
270-
</Route>
271-
<Route exact path="/">
272-
<Redirect to="/tab1" />
273-
</Route>
262+
<Route path="/tab1" element={<Tab1 />} />
263+
<Route path="/tab2" element={<Tab2 />} />
264+
<Route path="/tab3" element={<Tab3 />} />
265+
<Route path="/" element={<Navigate to="/tab1" replace />} />
274266
</IonRouterOutlet>
275267
<IonTabBar slot="bottom">
276268
<IonTabButton tab="tab1" href="/tab1">

docs/updating/9-0.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,198 @@ npm install react@latest react-dom@latest
4444
npm install @ionic/react@latest @ionic/react-router@latest
4545
```
4646

47+
### React Router
48+
49+
1. Ionic 9 supports React Router 6. Update to version 6 of React Router:
50+
51+
```shell
52+
npm install react-router@6 react-router-dom@6
53+
```
54+
55+
2. If you have `@types/react-router` or `@types/react-router-dom` installed, remove them. React Router 6 includes its own TypeScript definitions:
56+
57+
```shell
58+
npm uninstall @types/react-router @types/react-router-dom
59+
```
60+
61+
Ionic React now requires React Router v6, which has a different API from v5. Below are the key changes you'll need to make.
62+
63+
#### Route Definition Changes
64+
65+
The `component` and `render` props have been replaced with the `element` prop, which accepts JSX:
66+
67+
```diff
68+
- <Route path="/home" component={Home} exact />
69+
+ <Route path="/home" element={<Home />} />
70+
```
71+
72+
Routes can no longer render content via nested children. All route content must be passed through the `element` prop:
73+
74+
```diff
75+
- <Route path="/">
76+
- <Home />
77+
- </Route>
78+
+ <Route path="/" element={<Home />} />
79+
```
80+
81+
#### Redirect Changes
82+
83+
The `<Redirect>` component has been replaced with `<Navigate>`:
84+
85+
```diff
86+
- import { Redirect } from 'react-router-dom';
87+
+ import { Navigate } from 'react-router-dom';
88+
89+
- <Redirect to="/home" />
90+
+ <Navigate to="/home" replace />
91+
```
92+
93+
#### Nested Route Paths
94+
95+
Routes that contain nested routes or child `IonRouterOutlet` components need a `/*` suffix to match sub-paths:
96+
97+
```diff
98+
- <Route path="/tabs" element={<Tabs />} />
99+
+ <Route path="/tabs/*" element={<Tabs />} />
100+
```
101+
102+
#### Accessing Route Parameters
103+
104+
Route parameters are now accessed via the `useParams` hook instead of props:
105+
106+
```diff
107+
- import { RouteComponentProps } from 'react-router-dom';
108+
+ import { useParams } from 'react-router-dom';
109+
110+
- const MyComponent: React.FC<RouteComponentProps<{ id: string }>> = ({ match }) => {
111+
- const id = match.params.id;
112+
+ const MyComponent: React.FC = () => {
113+
+ const { id } = useParams<{ id: string }>();
114+
```
115+
116+
#### RouteComponentProps Removed
117+
118+
The `RouteComponentProps` type and its `history`, `location`, and `match` props are no longer available in React Router v6. Use the equivalent hooks instead:
119+
120+
- `history` -> `useNavigate` (see below) or `useIonRouter`
121+
- `match.params` -> `useParams` (covered above)
122+
- `location` -> `useLocation`
123+
124+
```diff
125+
- import { RouteComponentProps } from 'react-router-dom';
126+
+ import { useNavigate, useLocation } from 'react-router-dom';
127+
+ import { useIonRouter } from '@ionic/react';
128+
129+
- const MyComponent: React.FC<RouteComponentProps> = ({ history, location }) => {
130+
- history.push('/path');
131+
- history.replace('/path');
132+
- history.goBack();
133+
- console.log(location.pathname);
134+
+ const MyComponent: React.FC = () => {
135+
+ const navigate = useNavigate();
136+
+ const router = useIonRouter();
137+
+ const location = useLocation();
138+
+ // In an event handler or useEffect:
139+
+ navigate('/path');
140+
+ navigate('/path', { replace: true });
141+
+ router.goBack();
142+
+ console.log(location.pathname);
143+
```
144+
145+
#### Exact Prop Removed
146+
147+
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:
148+
149+
```diff
150+
- <Route path="/home" exact />
151+
+ <Route path="/home" />
152+
```
153+
154+
#### Render Prop Removed
155+
156+
The `render` prop has been replaced with the `element` prop:
157+
158+
```diff
159+
- <Route path="/foo" render={(props) => <Foo {...props} />} />
160+
+ <Route path="/foo" element={<Foo />} />
161+
```
162+
163+
#### Programmatic Navigation
164+
165+
The `useHistory` hook has been replaced with `useNavigate`:
166+
167+
```diff
168+
- import { useHistory } from 'react-router-dom';
169+
+ import { useNavigate } from 'react-router-dom';
170+
+ import { useIonRouter } from '@ionic/react';
171+
172+
- const history = useHistory();
173+
+ const navigate = useNavigate();
174+
+ const router = useIonRouter();
175+
176+
- history.push('/path');
177+
+ navigate('/path');
178+
179+
- history.replace('/path');
180+
+ navigate('/path', { replace: true });
181+
182+
- history.goBack();
183+
+ router.goBack();
184+
```
185+
186+
#### Custom History Prop Removed
187+
188+
The `history` prop has been removed from `IonReactRouter`, `IonReactHashRouter`, and `IonReactMemoryRouter`. React Router v6 routers no longer accept custom `history` objects.
189+
190+
```diff
191+
- import { createBrowserHistory } from 'history';
192+
- const history = createBrowserHistory();
193+
- <IonReactRouter history={history}>
194+
+ <IonReactRouter>
195+
```
196+
197+
For `IonReactMemoryRouter` (commonly used in tests), use `initialEntries` instead:
198+
199+
```diff
200+
- import { createMemoryHistory } from 'history';
201+
- const history = createMemoryHistory({ initialEntries: ['/start'] });
202+
- <IonReactMemoryRouter history={history}>
203+
+ <IonReactMemoryRouter initialEntries={['/start']}>
204+
```
205+
206+
#### IonRedirect Removed
207+
208+
The `IonRedirect` component has been removed. Use React Router's `<Navigate>` component instead:
209+
210+
```diff
211+
- import { IonRedirect } from '@ionic/react';
212+
- <IonRedirect path="/old" to="/new" exact />
213+
+ import { Navigate } from 'react-router-dom';
214+
+ <Route path="/old" element={<Navigate to="/new" replace />} />
215+
```
216+
217+
#### Path Regex Constraints Removed
218+
219+
React Router v6 no longer supports regex constraints in path parameters (e.g., `/:tab(sessions)`). Use literal paths instead:
220+
221+
```diff
222+
- <Route path="/:tab(sessions)" component={SessionsPage} />
223+
- <Route path="/:tab(sessions)/:id" component={SessionDetail} />
224+
+ <Route path="/sessions" element={<SessionsPage />} />
225+
+ <Route path="/sessions/:id" element={<SessionDetail />} />
226+
```
227+
228+
#### IonRoute API Changes
229+
230+
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:
231+
232+
```diff
233+
- <IonRoute path="/foo" exact render={(props) => <Foo {...props} />} />
234+
+ <IonRoute path="/foo" element={<Foo />} />
235+
```
236+
237+
For more information on migrating from React Router v5 to v6, refer to the [React Router v6 Upgrade Guide](https://reactrouter.com/6.28.0/upgrading/v5).
238+
47239
### Vue
48240

49241
1. Ionic 9 supports Vue 3.0.6+. Update to the latest version of Vue:
@@ -65,3 +257,9 @@ npm install @ionic/vue@latest @ionic/vue-router@latest
65257
```shell
66258
npm install @ionic/core@latest
67259
```
260+
261+
## Need Help Upgrading?
262+
263+
Be sure to look at the [Ionic 9 Breaking Changes Guide](https://github.com/ionic-team/ionic-framework/blob/main/BREAKING.md#version-9x) for the complete list of breaking changes. This upgrade guide only covers changes that require action from developers.
264+
265+
If you need help upgrading, please post a thread on the [Ionic Forum](https://forum.ionicframework.com/).

static/code/stackblitz/v9/react/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@
88
"@types/node": "^24.0.0",
99
"@types/react": "^19.0.0",
1010
"@types/react-dom": "^19.0.0",
11-
"@types/react-router": "^5.1.11",
12-
"@types/react-router-dom": "^5.1.7",
1311
"@vitejs/plugin-react": "^5.0.0",
1412
"clsx": "^2.0.0",
1513
"react": "^19.0.0",
1614
"react-dom": "^19.0.0",
17-
"react-router": "^5.2.0",
18-
"react-router-dom": "^5.2.0",
15+
"react-router": "^6.0.0",
16+
"react-router-dom": "^6.0.0",
1917
"typescript": "~5.9.0",
2018
"vite": "^7.0.0",
2119
"web-vitals": "^5.0.0"

0 commit comments

Comments
 (0)