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  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  43 44- Column mode 45 46 **Figure 2** Column mode 47 48  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  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  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  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<[NavigationMenuItem](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navigationmenuitem)> 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 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 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 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  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 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