How to determine whether the route comes from Navigation or router on the target page?
Context
When an app uses both Navigation (NavPathStack) and router.pushUrl to jump to the same destination page, developers need a way inside that destination page to know which mechanism triggered the navigation.
Description
When using both Navigation and Router for route redirection, how to determine the route source on the target page?
-
Navigation: A root view container for route navigation, typically serving as the root container for Page components. It includes a title bar, content area, and toolbar by default. The content area displays either the home page (direct child components of Navigation) or non-home pages (child components of
NavDestination), with switching managed via routes. - router: A HarmonyOS module enabling navigation through URLs, supporting page jumps within the app, page replacement, and backward navigation.
Solution / Approach
-
Redirect from main page:
- Use
NavPathStack.pushPathByName()for Navigation-based routing. - Use
router.pushUrl()for router-based routing.
- Use
-
Target page logic:
In theonReadycallback of theNavDestinationcomponent:- If
UIContext.router.getParams()returnsundefined, the route originated from Navigation. Retrieve parameters viaNavPathStack.getParamByName()and display them. - Otherwise, the route came from router. Use
getParams()to fetch parameters.
- If
export class RouterParams {
text: string;
constructor(str: string) {
this.text = str;
}
}
@Entry
@Component
struct Index {
pageInfos: NavPathStack = new NavPathStack();
build() {
Navigation(this.pageInfos) {
Scroll() {
Column({ space: 20 }) {
Button('Navigation Jump', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.onClick(() => {
// Navigation route redirection
const info = new RouterParams('Redirect using Navigation method')
this.pageInfos.pushPathByName('PageD', info)
})
Button('Router redirection', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.onClick(() => {
// Router route redirection
this.getUIContext()
.getRouter()
.pushUrl({ url: 'pages/PageD', params: new RouterParams('Switching from a router to a router') })
.catch(() => {
})
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.padding('20vp')
}
}
.title('Checking the Route Source During Navigation-Router Switching')
}
}
import { RouterParams } from './Index';
@Builder
export function PageDBuilder() {
PageD()
}
@Entry
@Component
struct PageD {
pageInfos: NavPathStack = new NavPathStack();
@State message: string = 'test';
build() {
NavDestination() {
Column({ space: 20 }) {
Text(this.message)
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.height('100%')
.width('100%')
.margin({ left: 5 })
}
.title('PageD')
.onReady((context: NavDestinationContext) => {
this.pageInfos = context.pathStack;
if (JSON.stringify(this.getUIContext().getRouter().getParams()) === undefined) {
this.message = JSON.stringify(this.pageInfos.getParamByName('PageD'))
console.info('Navigation jump')
} else {
this.message = (this.getUIContext().getRouter().getParams() as RouterParams).text
console.info('Router redirection')
}
})
}
Key Takeaways
-
Route source identification: Check
UIContext.router.getParams()inNavDestination.onReady():-
undefined→ Navigation origin (useNavPathStack.getParamByName()). - Defined → router origin (use
getParams()).
-
- Parameter handling: Navigation and router require distinct methods to retrieve passed parameters.
-
Framework recommendation: Prefer Navigation over
router + @Entryfor complex animations and shared element interactions due to inherent page isolation limitations in the latter.

Top comments (0)