1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271---
title: 'ion-route'
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Props from '@ionic-internal/component-api/v7/route/props.md';
import Events from '@ionic-internal/component-api/v7/route/events.md';
import Methods from '@ionic-internal/component-api/v7/route/methods.md';
import Parts from '@ionic-internal/component-api/v7/route/parts.md';
import CustomProps from '@ionic-internal/component-api/v7/route/custom-props.mdx';
import Slots from '@ionic-internal/component-api/v7/route/slots.md';
<head>
<title>ion-route: API Route Component for Ionic Framework Apps</title>
<meta
name="description"
content="The ion-route component takes a component and renders it when the Browser URL matches the URL property. Learn more about the API route component for Ionic Apps."
/>
</head>
import EncapsulationPill from '@components/page/api/EncapsulationPill';
The route component takes a component and renders it when the Browser URL matches the url property.
:::note
Note: this component should only be used with vanilla and Stencil JavaScript projects. For Angular projects, use [`ion-router-outlet`](router-outlet.md) and the Angular router.
:::
## Navigation Hooks
Navigation hooks can be used to perform tasks or act as navigation guards. Hooks are used by providing functions to the `beforeEnter` and `beforeLeave` properties on each `ion-route`. Returning `true` allows navigation to proceed, while returning `false` causes it to be cancelled. Returning an object of type `NavigationHookOptions` allows you to redirect navigation to another page.
## Interfaces
```typescript
interface NavigationHookOptions {
/**
* A valid path to redirect navigation to.
*/
redirect: string;
}
```
## Usage
<Tabs groupId="framework" defaultValue="javascript" values={[{ value: 'javascript', label: 'Javascript' }, { value: 'stencil', label: 'Stencil' }, { value: 'vue', label: 'Vue' }]}>
<TabItem value="javascript">
```html
<ion-router>
<ion-route url="/home" component="page-home"></ion-route>
<ion-route url="/dashboard" component="page-dashboard"></ion-route>
<ion-route url="/new-message" component="page-new-message"></ion-route>
<ion-route url="/login" component="page-login"></ion-route>
</ion-router>
```
```javascript
const dashboardPage = document.querySelector('ion-route[url="/dashboard"]');
dashboardPage.beforeEnter = isLoggedInGuard;
const newMessagePage = document.querySelector('ion-route[url="/dashboard"]');
newMessagePage.beforeLeave = hasUnsavedDataGuard;
const isLoggedInGuard = async () => {
const isLoggedIn = await UserData.isLoggedIn(); // Replace this with actual login validation
if (isLoggedIn) {
return true;
} else {
return { redirect: '/login' }; // If a user is not logged in, they will be redirected to the /login page
}
};
const hasUnsavedDataGuard = async () => {
const hasUnsavedData = await checkData(); // Replace this with actual validation
if (hasUnsavedData) {
return await confirmDiscardChanges();
} else {
return true;
}
};
const confirmDiscardChanges = async () => {
const alert = document.createElement('ion-alert');
alert.header = 'Discard Unsaved Changes?';
alert.message = 'Are you sure you want to leave? Any unsaved changed will be lost.';
alert.buttons = [
{
text: 'Cancel',
role: 'Cancel',
},
{
text: 'Discard',
role: 'destructive',
},
];
document.body.appendChild(alert);
await alert.present();
const { role } = await alert.onDidDismiss();
return role === 'Cancel' ? false : true;
};
```
</TabItem>
<TabItem value="stencil">
```typescript
import { Component, h } from '@stencil/core';
import { alertController } from '@ionic/core';
@Component({
tag: 'router-example',
styleUrl: 'router-example.css',
})
export class RouterExample {
render() {
return (
<ion-router>
<ion-route url="/home" component="page-home"></ion-route>
<ion-route url="/dashboard" component="page-dashboard" beforeEnter={isLoggedInGuard}></ion-route>
<ion-route url="/new-message" component="page-new-message" beforeLeave={hasUnsavedDataGuard}></ion-route>
<ion-route url="/login" component="page-login"></ion-route>
</ion-router>
);
}
}
const isLoggedInGuard = async () => {
const isLoggedIn = await UserData.isLoggedIn(); // Replace this with actual login validation
if (isLoggedIn) {
return true;
} else {
return { redirect: '/login' }; // If a user is not logged in, they will be redirected to the /login page
}
};
const hasUnsavedDataGuard = async () => {
const hasUnsavedData = await checkData(); // Replace this with actual validation
if (hasUnsavedData) {
return await confirmDiscardChanges();
} else {
return true;
}
};
const confirmDiscardChanges = async () => {
const alert = await alertController.create({
header: 'Discard Unsaved Changes?',
message: 'Are you sure you want to leave? Any unsaved changed will be lost.',
buttons: [
{
text: 'Cancel',
role: 'Cancel',
},
{
text: 'Discard',
role: 'destructive',
},
],
});
await alert.present();
const { role } = await alert.onDidDismiss();
return role === 'Cancel' ? false : true;
};
```
</TabItem>
<TabItem value="vue">
```html
<template>
<ion-router>
<ion-route url="/home" component="page-home"></ion-route>
<ion-route url="/dashboard" component="page-dashboard" :beforeEnter="isLoggedInGuard"></ion-route>
<ion-route url="/new-message" component="page-new-message" :beforeLeave="hasUnsavedDataGuard"></ion-route>
<ion-route url="/login" component="page-login"></ion-route>
</ion-router>
</template>
<script>
import { alertController } from '@ionic/vue';
const isLoggedInGuard = async () => {
const isLoggedIn = await UserData.isLoggedIn(); // Replace this with actual login validation
if (isLoggedIn) {
return true;
} else {
return { redirect: '/login' }; // If a user is not logged in, they will be redirected to the /login page
}
};
const hasUnsavedDataGuard = async () => {
const hasUnsavedData = await checkData(); // Replace this with actual validation
if (hasUnsavedData) {
return await confirmDiscardChanges();
} else {
return true;
}
};
const confirmDiscardChanges = async () => {
const alert = await alertController.create({
header: 'Discard Unsaved Changes?',
message: 'Are you sure you want to leave? Any unsaved changed will be lost.',
buttons: [
{
text: 'Cancel',
role: 'Cancel',
},
{
text: 'Discard',
role: 'destructive',
},
],
});
await alert.present();
const { role } = await alert.onDidDismiss();
return role === 'Cancel' ? false : true;
};
</script>
```
</TabItem>
</Tabs>
## Properties
<Props />
## Events
<Events />
## Methods
<Methods />
## CSS Shadow Parts
<Parts />
## CSS Custom Properties
<CustomProps />
## Slots
<Slots />