1# Component Navigation (Navigation) (Recommended)
2
3[Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md) component serves as the root view container for route navigation and is commonly used as the root container for pages decorated with @Entry. It supports three display modes: Stack, Split, and Auto. This component is designed for both intra-module and cross-module routing, leveraging component-level routing to provide a more natural and seamless transition between pages. It also offers multiple title bar styles to enhance the cascading between titles and content. In one-time development for multi-device deployment scenarios, the **Navigation** component can automatically adapt to the window size. When the window is large enough, it automatically displays content in columns.
4
5The **Navigation** component consists of a navigation page (**NavBar**) and subpages (**NavDestination**). The navigation page consists of the title bar (with the menu bar), content area, and toolbar, and can be hidden through the [hideNavBar](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#hidenavbar9) attribute. Unlike other pages, the navigation page does not reside in the page stack. Routing is used to manage transitions between the navigation page and its subpages, as well as between subpages themselves.
6
7In API version 9, the **Navigation** component must be used together with the [NavRouter](../reference/apis-arkui/arkui-ts/ts-basic-components-navrouter.md) component for page routing. Since API version 10, whenever possible, use [NavPathStack](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathstack10) instead to implement page routing.
8
9
10## Setting the Page Display Mode
11
12The **Navigation** component uses the **mode** attribute to set the page display mode.
13
14- Adaptive Mode
15
16  By default, the **Navigation** component is in adaptive mode. In this case, the **mode** attribute is **NavigationMode.Auto**. In adaptive mode, when the device width is greater than or equal to the threshold (520 vp for API version 9 and earlier and 600 vp for API version 10 and later), the **Navigation** component uses the column mode. Otherwise, the **Navigation** component uses the single-page mode.
17
18
19  ```
20  Navigation() {
21    // ...
22  }
23  .mode(NavigationMode.Auto)
24  ```
25
26- Single-page mode
27
28    **Figure 1** Single-page mode
29
30  ![en-us_image_0000001511740532](figures/en-us_image_0000001511740532.png)
31
32  Set **mode** to **NavigationMode.Stack** so that the **Navigation** component is displayed on a single page.
33
34
35  ```ts
36  Navigation() {
37    // ...
38  }
39  .mode(NavigationMode.Stack)
40  ```
41
42  ![single-page-1](figures/single-page-1.jpg)
43
44- Column mode
45
46  **Figure 2** Column mode
47
48  ![en-us_image_0000001562820845](figures/en-us_image_0000001562820845.png)
49
50  Set **mode** to **NavigationMode.Split** so that the **Navigation** component is displayed in columns.
51
52
53  ```ts
54  @Entry
55  @Component
56  struct NavigationExample {
57    @State TooTmp: ToolbarItem = {'value': "func", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}}
58    @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack()
59    private arr: number[] = [1, 2, 3];
60
61    @Builder
62    PageMap(name: string) {
63      if (name === "NavDestinationTitle1") {
64        pageOneTmp()
65      } else if (name === "NavDestinationTitle2") {
66        pageTwoTmp()
67      } else if (name === "NavDestinationTitle3") {
68        pageThreeTmp()
69      }
70    }
71
72    build() {
73      Column() {
74        Navigation(this.pageInfos) {
75          TextInput({ placeholder: 'search...' })
76            .width("90%")
77            .height(40)
78            .backgroundColor('#FFFFFF')
79
80          List({ space: 12 }) {
81            ForEach(this.arr, (item:number) => {
82              ListItem() {
83                Text("NavRouter" + item)
84                  .width("100%")
85                  .height(72)
86                  .backgroundColor('#FFFFFF')
87                  .borderRadius(24)
88                  .fontSize(16)
89                  .fontWeight(500)
90                  .textAlign(TextAlign.Center)
91                  .onClick(()=>{
92                    this.pageInfos.pushPath({ name: "NavDestinationTitle" + item})
93                  })
94              }
95            }, (item:number) => item.toString())
96          }
97          .width("90%")
98          .margin({ top: 12 })
99        }
100        .title ("Main Title")
101        .mode(NavigationMode.Split)
102        .navDestination(this.PageMap)
103        .menus([
104          {value: "", icon: "./image/ic_public_search.svg", action: ()=> {}},
105          {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}},
106          {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}},
107          {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}},
108          {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}}
109        ])
110        .toolbarConfiguration([this.TooTmp, this.TooTmp, this.TooTmp])
111      }
112      .height('100%')
113      .width('100%')
114      .backgroundColor('#F1F3F5')
115    }
116  }
117
118  // PageOne.ets
119  @Component
120  export struct pageOneTmp {
121    @Consume('pageInfos') pageInfos: NavPathStack;
122    build() {
123      NavDestination() {
124        Column() {
125          Text("NavDestinationContent1")
126        }.width('100%').height('100%')
127      }.title("NavDestinationTitle1")
128      .onBackPressed(() => {
129        const popDestinationInfo = this.pageInfos.pop() // Pop the top element out of the navigation stack.
130        console.log('pop' + 'Return value' + JSON.stringify(popDestinationInfo))
131        return true
132      })
133    }
134  }
135
136  // PageTwo.ets
137  @Component
138  export struct pageTwoTmp {
139    @Consume('pageInfos') pageInfos: NavPathStack;
140    build() {
141      NavDestination() {
142        Column() {
143          Text("NavDestinationContent2")
144        }.width('100%').height('100%')
145      }.title("NavDestinationTitle2")
146      .onBackPressed(() => {
147        const popDestinationInfo = this.pageInfos.pop() // Pop the top element out of the navigation stack.
148        console.log('pop' + 'Return value' + JSON.stringify(popDestinationInfo))
149        return true
150      })
151    }
152  }
153
154  // PageThree.ets
155  @Component
156  export struct pageThreeTmp {
157    @Consume('pageInfos') pageInfos: NavPathStack;
158    build() {
159      NavDestination() {
160        Column() {
161          Text("NavDestinationContent3")
162        }.width('100%').height('100%')
163      }.title("NavDestinationTitle3")
164      .onBackPressed(() => {
165        const popDestinationInfo = this.pageInfos.pop() // Pop the top element out of the navigation stack.
166        console.log('pop' + 'Return value' + JSON.stringify(popDestinationInfo))
167        return true
168      })
169    }
170  }
171  ```
172
173  ![column](figures/column.jpg)
174
175
176## Setting the Title Bar Mode
177
178The title bar is on the top of the page and is used to display the page name and operation entry. The **Navigation** component uses the **titleMode** attribute to set the title bar mode.
179
180- Mini mode
181
182  Applicable when the title of a level-1 page does not need to be highlighted.
183
184  **Figure 3** Title bar in Mini mode
185
186  ![mini](figures/mini.jpg)
187
188
189  ```ts
190  Navigation() {
191    // ...
192  }
193  .titleMode(NavigationTitleMode.Mini)
194  ```
195
196
197- Full mode
198
199  Applicable when the title of a level-1 page needs to be highlighted.
200
201    **Figure 4** Title bar in Full mode
202
203  ![free1](figures/free1.jpg)
204
205
206  ```ts
207  Navigation() {
208    // ...
209  }
210  .titleMode(NavigationTitleMode.Full)
211  ```
212
213
214## Setting the Menu Bar
215
216The menu bar is in the upper right corner of the **Navigation** component. You can set the menu bar through the **menus** attribute, which supports two parameter types: Array&lt;[NavigationMenuItem](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navigationmenuitem)&gt; and [CustomBuilder](../reference/apis-arkui/arkui-ts/ts-types.md#custombuilder8). When the Array\<NavigationMenuItem> type is used, a maximum of three icons can be displayed in portrait mode and a maximum of five icons can be displayed in landscape mode. Extra icons will be placed in the automatically generated More icons.
217
218**Figure 5** Menu bar with three icons
219
220![menu-bar-2](figures/menu-bar-2.jpg)
221
222```ts
223let TooTmp: NavigationMenuItem = {'value': "", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}}
224Navigation() {
225  // ...
226}
227.menus([TooTmp,
228  TooTmp,
229  TooTmp])
230```
231
232You can also reference images in the **resources** folder.
233
234```ts
235let TooTmp: NavigationMenuItem = {'value': "", 'icon': "resources/base/media/ic_public_highlights.svg", 'action': ()=> {}}
236Navigation() {
237  // ...
238}
239.menus([TooTmp,
240  TooTmp,
241  TooTmp])
242```
243
244**Figure 6** Menu bar with four icons
245
246![menu-bar](figures/menu-bar.jpg)
247
248```ts
249let TooTmp: NavigationMenuItem = {'value': "", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}}
250Navigation() {
251  // ...
252}
253.menus([TooTmp,
254  TooTmp,
255  TooTmp,
256  TooTmp])
257```
258
259
260## Setting the Toolbar
261
262Use the [toolbarConfiguration](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#toolbarconfiguration10) attribute to customize the toolbar, which is located at the bottom of the **Navigation** component.
263
264
265  **Figure 7** Toolbar
266
267![free3](figures/free3.jpg)
268
269```ts
270let TooTmp: ToolbarItem = {'value': "func", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}}
271let TooBar: ToolbarItem[] = [TooTmp,TooTmp,TooTmp]
272Navigation() {
273  // ...
274}
275.toolbarConfiguration(TooBar)
276```
277
278## Route Operations
279
280Navigation-related routing operations are all based on the APIs provided by [NavPathStack](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathstack10). For each **Navigation** component, a **NavPathStack** object must be created and passed in to manage pages. The router operations mainly involve page navigation, page return, page replacement, page deletion, parameter acquisition, and route interception.
281
282**NavPathStack** can be inherited since API version 12. You can customize attributes and methods in derived classes or override methods of the parent class. Derived class objects can be used in place of the base class **NavPathStack** objects. For details about the sample code, see [Example 10](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#example-10).
283
284```ts
285@Entry
286@Component
287struct Index {
288  // Create a NavPathStack object and pass it to Navigation.
289  pageStack: NavPathStack = new NavPathStack()
290
291  build() {
292    Navigation(this.pageStack) {
293    }
294    .title('Main')
295  }
296}
297```
298
299### Page Navigation
300
301**NavPathStack** implements the following types of page navigation through **Push** related APIs:
302
3031. Normal navigation: Navigation is conducted by page name and allows for passing of **param**.
304
305    ```ts
306    this.pageStack.pushPath({ name: "PageOne", param: "PageOne Param" })
307    this.pageStack.pushPathByName("PageOne", "PageOne Param")
308    ```
309
3102. Navigation with a return callback: An **onPop** callback is added during navigation to obtain return information and process it upon page popping.
311
312    ```ts
313    this.pageStack.pushPathByName('PageOne', "PageOne Param", (popInfo) => {
314      console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result))
315    });
316    ```
317
3183. Navigation with an error code: An asynchronous callback is triggered at the end of navigation, returning error code information.
319
320    ```ts
321    this.pageStack.pushDestinationByName('PageOne', "PageOne Param")
322    .catch((error: BusinessError) => {
323      console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
324    }).then(() => {
325      console.info('Push destination succeed.');
326    });
327    ```
328
329### Page Return
330
331**NavPathStack** implements the page return feature through **Pop** related APIs.
332
333```ts
334// Return to the previous page.
335this.pageStack.pop()
336// Return to the previous PageOne page.
337this.pageStack.popToName("PageOne")
338// Return to the page whose index is 1.
339this.pageStack.popToIndex(1)
340// Return to the root home page (clear all pages in the stack).
341this.pageStack.clear()
342```
343
344### Page Replacement
345
346NavPathStack implements the page replacement feature through **Replace** related APIs.
347
348```ts
349// Replace the top page of the stack with PageOne.
350this.pageStack.replacePath({ name: "PageOne", param: "PageOne Param" })
351this.pageStack.replacePathByName("PageOne", "PageOne Param")
352```
353
354### Page Deletion
355
356**NavPathStack** implements the page deletion feature through **Remove** related APIs.
357
358```ts
359// Remove all pages whose name is PageOne from the stack.
360this.pageStack.removeByName("PageOne")
361// Remove the page with the specified index.
362this.pageStack.removeByIndexes([1,3,5])
363```
364
365### Parameter Acquisition
366
367**NavPathStack** obtains parameters of the page through **Get** related APIs.
368
369```ts
370// Obtain all page names in the stack.
371this.pageStack.getAllPathName()
372// Obtain the parameters of the page whose index is 1.
373this.pageStack.getParamByIndex(1)
374// Obtain the parameters of the PageOne page.
375this.pageStack.getParamByName("PageOne")
376// Obtain the index set of the PageOne page.
377this.pageStack.getIndexByName("PageOne")
378```
379
380### Route Interception
381
382**NavPathStack** provides the [setInterception](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#setinterception12) API to set callbacks for page navigation interception of **Navigation**. This API requires passing in a **NavigationInterception** object, which contains three callback functions described below.
383
384| Name      | Description                                                |
385| ------------ | ------------------------------------------------------ |
386| willShow   | Callback invoked when the page is about to be navigated, allowing for stack operations, which are effective in the current navigation.      |
387| didShow    | Callback invoked after the page is navigated. Stack operations in this callback are effective in the next navigation.|
388| modeChange | Callback invoked when the display mode of the **Navigation** component switches between single-column and dual-column. |
389
390> **NOTE**
391>
392> The navigation stack has already changed when any of the preceding callbacks is invoked.
393
394You can implement the capability to intercept and redirect in the **willShow** callback by modifying the route stack.
395
396```ts
397this.pageStack.setInterception({
398  willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
399    operation: NavigationOperation, animated: boolean) => {
400    if (typeof to === "string") {
401      console.log("target page is navigation home page.");
402      return;
403    }
404    // Redirect navigation to PageTwo to PageOne.
405    let target: NavDestinationContext = to as NavDestinationContext;
406    if (target.pathInfo.name === 'PageTwo') {
407      target.pathStack.pop();
408      target.pathStack.pushPathByName('PageOne', null);
409    }
410  }
411})
412```
413
414## Subpage
415
416[NavDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md) is the root container for **Navigation** subpages, used to hold some special attributes as well as lifecycles of subpages. You can set separate attributes such as the title bar and menu bar for **NavDestination**, in the same way you set attributes for **Navigation**. You can also set different display modes for **NavDestination** through the **mode** attribute to meet different page requirements.
417
418### Page Display Mode
419
420- Standard mode
421
422  By default, subpages in the **NavDestination** component are in standard mode, which corresponds to the **NavDestinationMode.STANDARD** value of the **mode** attribute. The lifecycle of a standard type **NavDestination** follows the changes in its position in the **NavPathStack**.
423
424- Dialog mode
425
426  With **mode** set to **NavDestinationMode.DIALOG**, a **NavDestination** The appearance and disappearance of the dialog-type **NavDestination** will not affect the display and lifecycle of the underlying standard-type **NavDestination**, and the two can be displayed at the same time.
427
428  ```ts
429  // Dialog NavDestination
430  @Entry
431  @Component
432   struct Index {
433     @Provide('NavPathStack') pageStack: NavPathStack = new NavPathStack()
434
435     @Builder
436     PagesMap(name: string) {
437       if (name == 'DialogPage') {
438         DialogPage()
439       }
440     }
441
442     build() {
443       Navigation(this.pageStack) {
444         Button('Push DialogPage')
445           .margin(20)
446           .width('80%')
447           .onClick(() => {
448             this.pageStack.pushPathByName('DialogPage', '');
449           })
450       }
451       .mode(NavigationMode.Stack)
452       .title('Main')
453       .navDestination(this.PagesMap)
454     }
455   }
456
457   @Component
458   export struct DialogPage {
459     @Consume('NavPathStack') pageStack: NavPathStack;
460
461     build() {
462       NavDestination() {
463         Stack({ alignContent: Alignment.Center }) {
464           Column() {
465             Text("Dialog NavDestination")
466               .fontSize(20)
467               .margin({ bottom: 100 })
468             Button("Close").onClick(() => {
469               this.pageStack.pop()
470             }).width('30%')
471           }
472           .justifyContent(FlexAlign.Center)
473           .backgroundColor(Color.White)
474           .borderRadius(10)
475           .height('30%')
476           .width('80%')
477         }.height("100%").width('100%')
478       }
479       .backgroundColor('rgba(0,0,0,0.5)')
480       .hideTitleBar(true)
481       .mode(NavDestinationMode.DIALOG)
482     }
483   }
484  ```
485  ![dialog_navdestination](figures/dialog_navdestination.png)
486
487### Page Lifecycle
488
489**Navigation**, as a routing container, hosts its lifecycle within the **NavDestination** component and exposes lifecycle events as component events.
490
491The lifecycle of **Navigation** can be divided into three categories: custom component lifecycle, universal component lifecycle, and its own exclusive lifecycle. [aboutToAppear](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#abouttoappear) and [aboutToDisappear](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#abouttodisappear) are the lifecycle callbacks of custom components (custom components contained in the outer layer of **NavDestination**); [OnAppear](../reference/apis-arkui/arkui-ts/ts-universal-events-show-hide.md#onappear) and [OnDisappear](../reference/apis-arkui/arkui-ts/ts-universal-events-show-hide.md#ondisappear) are universal component lifecycle callbacks. The remaining six lifecycle events are unique to **NavDestination**.
492
493The sequence of these lifecycle events is illustrated in the figure below.
494
495![navigation_lifecycle](figures/navigation_lifecycle.png)
496
497- **aboutToAppear**: Invoked when the custom component is about to appear. Specifically, it is invoked after a new instance of the custom component is created and before its **build()** function is executed (before the creation of **NavDestination**). You can change state variables in this callback, and the changes take effect in the subsequent execution of **build()**.
498- **onWillAppear**: invoked after the **NavDestination** component is created and before it is mounted to the component tree. Changing the state variable in this callback takes effect in the current frame.
499- **onAppear**: invoked when the **NavDestination** component is mounted to the component tree. It is a universal lifecycle event.
500- **onWillShow**: invoked before the **NavDestination** component layout is displayed. In this case, the page is invisible. (This callback is not invoked when the application is switched to the foreground.)
501- **onShown**: invoked after the **NavDestination** component layout is displayed. At this time, the page layout is complete.
502- **onWillHide**: invoked when the **NavDestination** component is about to be hidden (it is not invoked when the application is switched to the background).
503- **onHidden**: invoked after the **NavDestination** component is hidden (when a non-top page is pushed into the stack, the top page pops out of the stack, or the application is switched to the background).
504- **onWillDisappear**: invoked before the **NavDestination** component is about to be destroyed. If there is a transition animation, this callback is invoked before the animation (when the top page of the stack pops out of the stack).
505- **onDisappear**: invoked when the **NavDestination** component is unloaded and destroyed from the component tree. It is a universal lifecycle event.
506- **aboutToDisappear**: invoked before the custom component is destroyed. The state variable cannot be changed in this callback.
507
508### Page Listening and Query
509
510To facilitate the decoupling of components from pages, custom components within **NavDestination** subpages can listen for or query some page status information through global APIs.
511
512- Page information query
513
514  Custom components provide the [queryNavDestinationInfo](../reference/apis-arkui/arkui-ts/ts-custom-component-api.md#querynavdestinationinfo) API, which can be used to query the information of the current page within **NavDestination**. The return value is [NavDestinationInfo](../reference/apis-arkui/js-apis-arkui-observer.md#navdestinationinfo). If the query fails, the return value is **undefined**.
515
516  ```ts
517   import { uiObserver } from '@kit.ArkUI';
518
519   // Custom components within NavDestination
520   @Component
521   struct MyComponent {
522     navDesInfo: uiObserver.NavDestinationInfo | undefined
523
524     aboutToAppear(): void {
525       this.navDesInfo = this.queryNavDestinationInfo();
526     }
527
528     build() {
529         Column() {
530           Text("Page name: " + this.navDesInfo?.name)
531         }.width('100%').height('100%')
532     }
533   }
534  ```
535- Page status listening
536
537  You can register a listener for **NavDestination** lifecycle changes using the [observer.on('navDestinationUpdate')](../reference/apis-arkui/js-apis-arkui-observer.md#observeronnavdestinationupdate) API.
538
539  ```ts
540  uiObserver.on('navDestinationUpdate', (info) => {
541       console.info('NavDestination state update', JSON.stringify(info));
542   });
543  ```
544
545  You can also register a callback for page transition states to obtain page information during route changes using [NavDestinationSwitchInfo](../reference/apis-arkui/js-apis-arkui-observer.md#navdestinationswitchinfo12). This registration supports different scopes: UIAbilityContext and UIContext.
546
547  ```ts
548   // Used in UIAbility
549   import { UIContext, uiObserver } from '@kit.ArkUI';
550
551   // callBackFunc is a callback defined by you.
552   function callBackFunc(info: uiObserver.NavDestinationSwitchInfo) {}
553   uiObserver.on('navDestinationSwitch', this.context, callBackFunc);
554
555   // The getUIContext() API of the window can be used to obtain the corresponding UIContent.
556   uiContext: UIContext | null = null;
557   uiObserver.on('navDestinationSwitch', this.uiContext, callBackFunc);
558  ```
559
560## Page Transition
561
562The **Navigation** component provides default transition animations for switching between pages. These animations are activated when operations are performed on the navigation stack, producing different transition effects. Note that for dialog box pages, the default transition animations are available only since API version 13. The **Navigation** component also offers advanced features such as disabling the default transitions and implementing custom transitions as well as shared element transitions.
563
564### Disabling Transitions
565
566- On a Global Basis
567
568  To enable or disable all transition animations in the current **Navigation** component, you can use the [disableAnimation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#disableanimation11) API provided in **NavPathStack**.
569  ```ts
570  pageStack: NavPathStack = new NavPathStack()
571
572  aboutToAppear(): void {
573    this.pageStack.disableAnimation(true)
574  }
575  ```
576- On a One-time Basis
577
578  To disable the transition animation for a single operation (implemented by APIs provided by **NavPathStack**, such as **Push**, **Pop**, and **Replace**), set the **animated** parameter in the API to **false**. This setting does not affect the next transition.
579  ```ts
580  pageStack: NavPathStack = new NavPathStack()
581
582  this.pageStack.pushPath({ name: "PageOne" }, false)
583  this.pageStack.pop(false)
584  ```
585
586### Customizing a Transition
587
588You can customize transition animations through the [customNavContentTransition](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#customnavcontenttransition11) event. Specifically, you can define a custom transition animation in the following steps:
589
5901. Build a custom transition animation utility class **CustomNavigationUtils**, which manages custom transition animation **CustomTransition** objects for each page through a Map. A page registers its **CustomTransition** object when created and unregisters it when destroyed.
5912. Implement a transition protocol object [NavigationAnimatedTransition](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navigationanimatedtransition11). The **timeout** property indicates the transition timeout duration, with a default value of 1000 ms. The **transition** property is where you implement your custom transition animation logic; it is the method that the system calls when the transition starts. The **onTransitionEnd** is the callback for when the transition ends.
5923. Call the **customNavContentTransition** API to return the **NavigationAnimatedTransition** object. If **undefined** is returned, the system default transition is used.
593
594For details about the sample code, see [Example 3](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#example-3).
595
596### Defining a Shared Element Transition
597
598You can implement shared element transitions between navigation destination pages using [geometryTransition](../reference/apis-arkui/arkui-ts/ts-transition-animation-geometrytransition.md#geometrytransition). Ensure that the default transition animations are disabled for pages configured with shared element transitions.
5991. Add the **geometryTransition** attribute to the components that need to implement shared element transitions, ensuring that the **id** parameter is consistent between the two **NavDestination** components.
600
601    ```ts
602    // Set id of the source page.
603    NavDestination() {
604    Column() {
605        // ...
606        Image($r('app.media.startIcon'))
607        .geometryTransition('sharedId')
608        .width(100)
609        .height(100)
610    }
611    }
612    .title('FromPage')
613
614    // Set id of the destination page.
615    NavDestination() {
616    Column() {
617        // ...
618        Image($r('app.media.startIcon'))
619        .geometryTransition('sharedId')
620        .width(200)
621        .height(200)
622    }
623    }
624    .title('ToPage')
625    ```
626
6272. Place the page routing operation in the **animateTo** animation closure, set the corresponding animation parameters, and disable the default transition.
628
629    ```ts
630    NavDestination() {
631    Column() {
632        Button('Go to Destination Page')
633        .width('80%')
634        .height(40)
635        .margin(20)
636        .onClick(() => {
637            this.getUIContext()?.animateTo({ duration: 1000 }, () => {
638              this.pageStack.pushPath({ name: 'ToPage' }, false)
639            })
640        })
641    }
642    }
643    .title('FromPage')
644    ```
645
646## Cross-Package Dynamic Routing
647
648Using static imports for page routing can lead to coupling between different modules and prolonged home page loading times.
649
650The purpose of dynamic routing is to allow multiple modules (HARs/HSPs) to reuse the same business logic, with decoupling between different modules and integration of routing functionality.
651
652**Advantages of dynamic routing**
653
654- In addition to the URL for navigation, you can configure various information, such as the default orientation (landscape or portrait) and whether authentication is required. The configuration is processed in a unified manner during routing
655- You can assign a name to each routing page and navigate by name instead of file path.
656- Dynamic imports (on-demand loading) can be used to load pages to prevent the first page from loading a large amount of code, which can cause stuttering.
657
658Dynamic routing provides two modes: [System Routing Table](#system-routing-table) and [Custom Routing Table](#custom-routing-table).
659
660- The system routing table is easier to use than the custom routing table. It only requires adding the corresponding page navigation configuration items to implement page navigation.
661
662- The custom route table is more complex to use, but can be customized to meet specific service requirements.
663
664The custom route table and system route table can be used together.
665
666### System Routing Table
667
668**Navigation** supports the system routing table for dynamic routing since API version 12. Each service module (HSP/HAR) requires an individual **route_map.json** file. When routing is triggered, the application only needs to pass the name of the page that needs to be routed through the routing API provided by **NavPathStack**. The system then automatically completes the dynamic loading of the target module, page component construction, and route redirection. This way, module decoupling is achieved at the development level. The main steps are as follows:
669
6701. Add the route table configuration to the **module.json5** file of the redirection target module.
671
672   ```json
673     {
674       "module" : {
675         "routerMap": "$profile:route_map"
676       }
677     }
678   ```
6792. Create the **route_map.json** file in **resources/base/profile** of the project directory. Add the following configuration information:
680
681   ```json
682     {
683       "routerMap": [
684         {
685           "name": "PageOne",
686           "pageSourceFile": "src/main/ets/pages/PageOne.ets",
687           "buildFunction": "PageOneBuilder",
688           "data": {
689             "description" : "this is PageOne"
690           }
691         }
692       ]
693     }
694   ```
695
696    The configuration is described as follows.
697
698   | Item| Description|
699   |---|---|
700   | name | Name of the target page to be redirected to.|
701   | pageSourceFile | Path of the target page in the package, relative to the **src** directory.|
702   | buildFunction | Name of the entry point function for redirection to the target page, which must be decorated by @Builder.|
703   | data | Custom data. You can obtain the value through the **getConfigInRouteMap** API.|
704
7053. On the target page, configure the @Builder decorated entry point function. The function name must be the same as the value of **buildFunction** in the **route_map.json** file. Otherwise, an error is reported at compile time.
706
707   ```ts
708     // Entry point function for redirection to the target page
709     @Builder
710     export function PageOneBuilder() {
711       PageOne()
712     }
713
714     @Component
715     struct PageOne {
716       pathStack: NavPathStack = new NavPathStack()
717
718       build() {
719         NavDestination() {
720         }
721         .title('PageOne')
722         .onReady((context: NavDestinationContext) => {
723            this.pathStack = context.pathStack
724         })
725       }
726     }
727   ```
7284. Use routing APIs such as **pushPathByName** to navigate to the target page. (Note: In this case, you do not need to configure the **navDestination** attribute in **Navigation**.)
729
730   ```ts
731     @Entry
732     @Component
733     struct Index {
734       pageStack : NavPathStack = new NavPathStack();
735
736       build() {
737         Navigation(this.pageStack){
738         }.onAppear(() => {
739           this.pageStack.pushPathByName("PageOne", null, false);
740         })
741         .hideNavBar(true)
742       }
743     }
744   ```
745
746### Custom Routing Table
747
748You can implement cross-package dynamic routing through a custom routing table.
749
750**Implementation:**
751
7521. Define page navigation configuration items.
753   - Use resource files for definitions and use the [@ohos.resourceManager](../reference/apis-localization-kit/js-apis-resource-manager.md) module to parse the resource files at runtime.
754   - Configure the route loading options in the .ets file, including the route page name (that is, the alias of the page in APIs like **pushPath**), name of the module where the file is located (name of the HSP/HAR module), and path to the target page in the module (relative to the **src** directory).
7552. Use [dynamic import](../arkts-utils/arkts-dynamic-import.md) to load the module containing the target page at runtime. Once the module is loaded, call a method within the module that uses **import** to load and display the target page, then return the **Builder** function defined after the page has finished loading.
7563. Execute the **Builder** function loaded in step 2 on the [navDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navdestination10) attribute of the **Navigation** component to navigate to the target page.
757<!--RP2--><!--RP2End-->
758<!--no_check-->
759