• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Page Routing (router)
2
3
4Page routing refers to the redirection and data transfer between different pages in an application. In OpenHarmony, page routing can be implemented through APIs of the **Router** module. Through different URLs, you can easily navigate users through pages. This document describes the functions provided by the **Router** module from the following aspects: [Page Redirection](#page-redirection), [Page Return](#page-return), [Adding a Confirmation Dialog Box Before Page Return](#adding-a-confirmation-dialog-box-before-page-return), and [Named Route](#named-route).
5
6The **Router** module is applicable to page redirection between modules and within a module. It uses page URLs to decouple modules. Regarding page redirection within a module, prefer [Navigation](./arkts-navigation-navigation.md) over this module to create better transition effects.
7
8## Page Redirection
9
10Page redirection is an important part of the development process. When using an application, you usually need to jump between different pages, and sometimes you need to pass data from one page to another.
11
12**Figure 1** Page redirection
13
14![router-jump-to-detail](figures/router-jump-to-detail.gif)
15
16The **Router** module provides two redirection modes: [router.pushUrl()](../reference/apis/js-apis-router.md#routerpushurl9) and [router.replaceUrl()](../reference/apis/js-apis-router.md#routerreplaceurl9). Whether the target page will replace the current page depends on the mode used.
17
18- **router.pushUrl()**: The target page is pushed into the [page stack](../application-models/page-mission-stack.md) and does not replace the current page. In this mode, the state of the current page is retained, and users can return to the current page by pressing the back button or calling the [router.back()](../reference/apis/js-apis-router.md#routerback) API.
19
20- **router.replaceUrl()**: The target page replaces and destroys the current page. In this mode, the resources of the current page can be released, and users cannot return to the current page.
21
22>**NOTE**
23>
24>- When creating a page, configure the route to this page by following instructions in [Building the Second Page](../quick-start/start-with-ets-stage.md).
25>
26>
27>- The maximum capacity of a page stack is 32 pages. If this limit is exceeded, the [router.clear()](../reference/apis/js-apis-router.md#routerclear) API can be called to clear the historical page stack and free the memory.
28
29The **Router** module also provides two instance modes: **Standard** and **Single**. Depending on the mode, the target URL is mapped to one or more instances.
30
31- **Standard**: multi-instance mode. It is the default instance mode. In this mode, the target page is added to the top of the page stack, regardless of whether a page with the same URL exists in the stack.
32
33- **Single**: singleton mode. In this mode, if the URL of the target page already exists in the page stack, the page closest to the top of the stack with the same URL is moved to the top of the stack and becomes the new page. If the URL of the target page does not exist in the page stack, the page is redirected in standard mode.
34
35Before using the **Router** module, import it first.
36
37
38```ts
39import router from '@ohos.router';
40import { BusinessError } from '@ohos.base';
41import promptAction from '@ohos.promptAction';
42```
43
44- Scenario 1: There is a home page (**Home**) and a details page (**Detail**). You want to click an offering on the home page to go to the details page. In addition, the home page needs to be retained in the page stack so that the status can be restored when the page is returned. In this scenario, you can use the **pushUrl()** API and use the **Standard** instance mode (which can also be omitted).
45
46
47  ```ts
48  import router from '@ohos.router';
49  // On the Home page
50  function onJumpClick(): void {
51    router.pushUrl({
52      url: 'pages/Detail' // Target URL.
53    }, router.RouterMode.Standard, (err) => {
54      if (err) {
55        console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
56        return;
57      }
58      console.info('Invoke pushUrl succeeded.');
59    });
60  }
61  ```
62
63  >**NOTE**
64  >
65  >In standard (multi-instance) mode, the **router.RouterMode.Standard** parameter can be omitted.
66
67- Scenario 2: There is a login page (**Login**) and a personal center page (**Profile**). After a user successfully logs in from the **Login** page, the **Profile** page is displayed. At the same time, the **Login** page is destroyed, and the application exits when the back button is pressed. In this scenario, you can use the **replaceUrl()** API and use the Standard instance mode (which can also be omitted).
68
69
70  ```ts
71  import router from '@ohos.router';
72  // On the Login page
73  function onJumpClick(): void {
74    router.replaceUrl({
75      url: 'pages/Profile' // Target URL.
76    }, router.RouterMode.Standard, (err) => {
77      if (err) {
78        console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
79        return;
80      }
81      console.info('Invoke replaceUrl succeeded.');
82    })
83  }
84  ```
85
86  >**NOTE**
87  >
88  >In standard (multi-instance) mode, the **router.RouterMode.Standard** parameter can be omitted.
89
90- Scenario 3: There is a **Setting** page and a **Theme** page. After a theme option on the **Setting** page is clicked, the **Theme** page is displayed. Only one **Theme** page exists in the page stack at the same time. When the back button is clicked on the **Theme** page, the **Setting** page is displayed. In this scenario, you can use the **pushUrl()** API and use the **Single** instance mode.
91
92
93  ```ts
94  import router from '@ohos.router';
95  // On the Setting page
96  function onJumpClick(): void {
97    router.pushUrl({
98      url: 'pages/Theme' // Target URL.
99    }, router.RouterMode.Single, (err) => {
100      if (err) {
101        console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
102        return;
103      }
104      console.info('Invoke pushUrl succeeded.');
105    });
106  }
107  ```
108
109- Scenario 4: There is a search result list page (**SearchResult**) and a search result details page (**SearchDetail**). You want to click a result on the **SearchResult** page to go to the **SearchDetail** page. In addition, if the result has been viewed before, clicking the result displays the existing details page, instead of creating a new one. In this scenario, you can use the **replaceUrl()** API and use the **Single** instance mode.
110
111
112  ```ts
113  import router from '@ohos.router';
114  // On the SearchResult page
115  function onJumpClick(): void {
116    router.replaceUrl({
117      url: 'pages/SearchDetail' // Target URL.
118    }, router.RouterMode.Single, (err) => {
119      if (err) {
120        console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
121        return;
122      }
123      console.info('Invoke replaceUrl succeeded.');})
124  }
125  ```
126
127The preceding scenarios do not involve parameter transfer.
128
129If you need to transfer data to the target page during redirection, you can add a **params** attribute and specify an object as a parameter when invoking an API of the **Router** module. Example:
130
131
132```ts
133import router from '@ohos.router';
134class DataModelInfo {
135  age: number = 0;
136}
137
138class DataModel {
139  id: number = 0;
140  info: DataModelInfo|null = null;
141}
142
143function onJumpClick(): void {
144  // On the Home page
145  let paramsInfo: DataModel = {
146    id: 123,
147    info: {
148      age: 20
149    }
150  };
151
152  router.pushUrl({
153    url: 'pages/Detail', // Target URL.
154    params: paramsInfo // Add the params attribute to transfer custom parameters.
155  }, (err) => {
156    if (err) {
157      console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
158      return;
159    }
160    console.info('Invoke pushUrl succeeded.');
161  })
162}
163```
164
165On the target page, you can call the [getParams()](../reference/apis/js-apis-router.md#routergetparams) API of the **Router** module to obtain the passed parameters. Example:
166
167
168```ts
169import router from '@ohos.router';
170class infoTmp{
171  age:number = 0
172}
173class rouTmp{
174  id:object = ()=>{}
175  info:infoTmp = new infoTmp()
176}
177const params:rouTmp = router.getParams() as rouTmp; // Obtain the passed parameter object.
178const id:object = params.id // Obtain the value of the id attribute.
179const age:number = params.info.age; // Obtain the value of the age attribute.
180```
181
182
183## Page Return
184
185Implement the page return feature so that users can return to the previous page or a specified page. You can pass parameters to the target page during the return process.
186
187  **Figure 2** Page return
188
189![router-back-to-home](figures/router-back-to-home.gif)
190
191Before using the **Router** module, import it first.
192
193
194```ts
195import router from '@ohos.router';
196```
197
198You can use any of the following methods to return to a page:
199
200- Method 1: Return to the previous page.
201
202
203  ```ts
204  import router from '@ohos.router';
205  router.back();
206  ```
207
208  This method allows you to return to the position of the previous page in the page stack. For this method to work, the previous page must exist in the page stack.
209
210- Method 2: Return to the specified page.
211
212
213  ```ts
214  import router from '@ohos.router';
215  router.back({
216    url: 'pages/Home'
217  });
218  ```
219
220  This method allows uesrs to return to a page with the specified path. For this method to work, the target page must exist in the page stack.
221
222- Method 3: Return to the specified page and transfer custom parameter information.
223
224
225  ```ts
226  import router from '@ohos.router';
227  router.back({
228    url: 'pages/Home',
229    params: {
230      info: 'From Home Page'
231    }
232  });
233  ```
234
235  This method not only allows you to return to the specified page, but also pass in custom parameter information during the return process. The parameter information can be obtained and parsed by invoking the **router.getParams()** API on the target page.
236
237On the target page, call the **router.getParams()** API at the position where parameters need to be obtained, for example, in the **onPageShow()** lifecycle callback:
238
239
240```ts
241import router from '@ohos.router';
242onPageShow() {
243  const params:Record<string,Object> = {'':router.getParams()}; // Obtain the passed parameter object.
244  const info:Object = params['']; // Obtain the value of the info attribute.
245}
246```
247
248>**NOTE**
249>
250>When the **router.back()** API is used to return to a specified page, the page is pushed to the top of the stack again, and all page stacks between the original top page (included) and the specified page (excluded) are destroyed.
251>
252> If the **router.back()** method is used to return to the original page, the original page will not be created repeatedly. Therefore, the variable declared using \@State will not be declared repeatedly, and the **aboutToAppear()** lifecycle callback of the page will not be triggered. If you want to use the custom parameters transferred from the returned page on the original page, you can parse the parameters in the required position. For example, parameter parsing can be performed in the **onPageShow()** lifecycle callback.
253
254
255## Adding a Confirmation Dialog Box Before Page Return
256
257During application development, to prevent misoperations or data loss, a dialog box needs to be displayed before a user returns from one page to another, asking the user whether to perform the operation.
258
259Such a dialog box can be in the [default style](#default-confirmation-dialog-box) or [custom style](#custom-confirmation-dialog-box).
260
261  **Figure 3** Adding a confirmation dialog box before page return
262
263![router-add-query-box-before-back](figures/router-add-query-box-before-back.gif)
264
265
266### Default Confirmation Dialog Box
267
268To implement this function, you can use the [router.showAlertBeforeBackPage()](../reference/apis/js-apis-router.md#routershowalertbeforebackpage9) and [router.back()](../reference/apis/js-apis-router.md#routerback) APIs provided by the **Router** module.
269
270Before using the **Router** module, import it first.
271
272
273```ts
274import router from '@ohos.router';
275```
276
277To enable the confirmation dialog box for page return, call the [router.showAlertBeforeBackPage()](../reference/apis/js-apis-router.md#routershowalertbeforebackpage9) API (for setting the information about the dialog box), then the [router.back()](../reference/apis/js-apis-router.md#routerback) API. For example, define a click event processing function for the back button on the payment page:
278
279
280```ts
281import router from '@ohos.router';
282import { BusinessError } from '@ohos.base';
283
284// Define a click event processing function for the back button.
285function onBackClick(): void {
286  // Invoke the router.showAlertBeforeBackPage() API to set the information about the confirmation dialog box.
287  try {
288    router.showAlertBeforeBackPage({
289      message: 'Payment not completed yet. Are you sure you want to return?' // Set the content of the confirmation dialog box.
290    });
291  } catch (err) {
292    let message = (err as BusinessError).message
293    let code = (err as BusinessError).code
294    console.error(`Invoke showAlertBeforeBackPage failed, code is ${code}, message is ${message}`);
295  }
296
297  // Invoke the router.back() API to return to the previous page.
298  router.back();
299}
300```
301
302The **router.showAlertBeforeBackPage()** API receives an object as a parameter. The object contains the following attributes:
303
304**message**: content of the dialog box. The value is of the string type.
305If the API is called successfully, the confirmation dialog box is displayed on the target page. Otherwise, an exception is thrown and the error code and error information is obtained through **err.code** and **err.message**.
306
307When the user clicks the back button, a confirmation dialog box is displayed, prompting the user to confirm their operation. If the user selects Cancel, the application stays on the current page. If the user selects OK, the **router.back()** API is triggered and the redirection is performed based on the parameters.
308
309### Custom Confirmation Dialog Box
310
311To implement a custom confirmation dialog box, use APIs in the [PromptAction](../reference/apis/js-apis-promptAction.md#promptactionshowdialog) module or customize a popup window.  This topic uses the APIs in the **PromptAction** module an example to describe how to implement a custom confirmation dialog box.
312
313Before using the **Router** module, import it first.
314
315
316```ts
317import router from '@ohos.router';
318```
319
320In the event callback, call the [promptAction.showDialog()](../reference/apis/js-apis-promptAction.md#promptactionshowdialog) API of the **PromptAction** module.
321
322
323```ts
324import router from '@ohos.router';
325import promptAction from '@ohos.promptAction';
326import { BusinessError } from '@ohos.base';
327
328function onBackClick() {
329  // Display a custom confirmation dialog box.
330  promptAction.showDialog({
331    message:'Payment not completed yet. Are you sure you want to return?',
332    buttons: [
333      {
334        text: 'Cancel',
335        color: '#FF0000'
336      },
337      {
338        text: 'OK',
339        color: '#0099FF'
340      }
341    ]
342  }).then((result:promptAction.ShowDialogSuccessResponse) => {
343    if (result.index === 0) {
344      // The user selects Cancel.
345      console.info('User canceled the operation.');
346    } else if (result.index === 1) {
347      // The user selects OK.
348      console.info('User confirmed the operation.');
349      // Invoke the router.back() API to return to the previous page.
350      router.back();
351    }
352  }).catch((err:Error) => {
353    let message = (err as BusinessError).message
354    let code = (err as BusinessError).code
355    console.error(`Invoke showDialog failed, code is ${code}, message is ${message}`);
356  })
357}
358```
359
360When the user clicks the back button, the custom confirmation dialog box is displayed, prompting the user to confirm their operation. If the user selects Cancel, the application stays on the current page. If the user selects OK, the **router.back()** API is triggered and the redirection is performed based on the parameters.
361
362## Named Route
363
364To redirect to a [page in a shared package](../quick-start/shared-guide.md), you can use [router.pushNamedRoute()](../reference/apis/js-apis-router.md#routerpushnamedroute10).
365
366Before using the **Router** module, import it first.
367
368
369```ts
370import router from '@ohos.router';
371```
372
373In the target page in the [shared package](../quick-start/shared-guide.md), name the [@Entry decorated custom component](../quick-start/arkts-create-custom-components.md#entryoptions10).
374
375```ts
376// library/src/main/ets/pages/Index.ets
377// library is the custom name of the new shared package.
378@Entry({ routeName : 'myPage' })
379@Component
380struct MyComponent {
381}
382```
383
384When the configuration is successful, import the named route page to the page from which you want to redirect.
385
386```ts
387import router from '@ohos.router';
388import { BusinessError } from '@ohos.base';
389const moudel = import('library/src/main/ets/pages/Index') // Import the named route page in the shared package.
390@Entry
391@Component
392struct Index {
393  build() {
394    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
395      Text('Hello World')
396        .fontSize(50)
397        .fontWeight(FontWeight.Bold)
398        .margin({ top: 20 })
399        .backgroundColor('#ccc')
400        .onClick(() => { // Click to go to a page in another shared package.
401          try {
402            router.pushNamedRoute({
403              name: 'myPage',
404              params: {
405                data1: 'message',
406                data2: {
407                  data3: [123, 456, 789]
408                }
409              }
410            })
411          } catch (err) {
412            let message = (err as BusinessError).message
413            let code = (err as BusinessError).code
414            console.error(`pushNamedRoute failed, code is ${code}, message is ${message}`);
415          }
416        })
417    }
418    .width('100%')
419    .height('100%')
420  }
421}
422```
423