DEV Community

HarmonyOS
HarmonyOS

Posted on

How to determine whether the route comes from Navigation or router on the target page?

Read the original article:How to determine whether the route comes from Navigation or router on the target page?

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

  1. Redirect from main page:

    • Use NavPathStack.pushPathByName() for Navigation-based routing.
    • Use router.pushUrl() for router-based routing.
  2. Target page logic:
    In the onReady callback of the NavDestination component:

    • If UIContext.router.getParams() returns undefined, the route originated from Navigation. Retrieve parameters via NavPathStack.getParamByName() and display them.
    • Otherwise, the route came from router. Use getParams() to fetch parameters.
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')
  }
}
Enter fullscreen mode Exit fullscreen mode
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')
      }
    })
  }

Enter fullscreen mode Exit fullscreen mode

input22.gif

Key Takeaways

  • Route source identification: Check UIContext.router.getParams() in NavDestination.onReady():
    • undefined → Navigation origin (use NavPathStack.getParamByName()).
    • Defined → router origin (use getParams()).
  • Parameter handling: Navigation and router require distinct methods to retrieve passed parameters.
  • Framework recommendation: Prefer Navigation over router + @Entry for complex animations and shared element interactions due to inherent page isolation limitations in the latter.

Written by Emrecan Karakas

Top comments (0)