Skip to content

Backport navigate() method to NavigationProvider on react-18 branch #4325

@odinr

Description

@odinr

Story

As a Fusion app developer on the react-18 branch, I want the NavigationProvider (Navigator) to expose a navigate(to?, options?) method, so that I can use the same navigation API available on main without upgrading to React 19.

Context

The react-18 branch of equinor/fusion-framework preserves React 18 compatibility for apps that have not yet migrated to React 19. On main, @equinor/fusion-framework-module-navigation v7.0.0 introduced a unified navigate(to?, options?) method on the NavigationProvider class (NavigationProvider.ts). This method combines the behavior of push() and replace() with explicit NavigateOptions (replace flag, state), and both push() and replace() now delegate to it internally.

On the react-18 branch (@equinor/fusion-framework-module-navigation v6.0.1), the Navigator class in navigator.ts only exposes push(to, state?) and replace(to, state?). There is no navigate() method. This means:

  • Apps that target the react-18 branch cannot use navigate() and must use the lower-level push/replace pair directly.
  • Code written against the main branch API is not portable to react-18 without changes.
  • Portal/framework consumers that expect navigate() on the provider (e.g., context-change navigation patterns in useAppContextNavigation) cannot be backported cleanly.

Source references

Branch Package Version Provider class File
main @equinor/fusion-framework-module-navigation 7.0.0 NavigationProvider packages/modules/navigation/src/NavigationProvider.ts
react-18 @equinor/fusion-framework-module-navigation 6.0.1 Navigator packages/modules/navigation/src/navigator.ts

Functional requirements

  • Add a navigate(to?: To, options?: Partial<NavigateOptions>) method to the Navigator class on the react-18 branch.
  • The method should accept an optional To target and optional NavigateOptions with at least replace (boolean) and state (unknown).
  • When options.replace is true, the method should call the underlying replace(); otherwise it should call push().
  • The existing push() and replace() methods should remain unchanged (no delegation refactor required on this branch — keep the change minimal).
  • Export a NavigateOptions type from the package so consumers can import it.
  • The method signature should be compatible with the main branch INavigationProvider.navigate() contract to ease future migration.

Scenarios

  • Given an app using @equinor/fusion-framework-module-navigation v6.x on the react-18 branch, When the developer calls navigator.navigate('/users'), Then a new history entry is pushed for /users.
  • Given the same setup, When the developer calls navigator.navigate('/login', { replace: true }), Then the current history entry is replaced with /login.
  • Given the same setup, When the developer calls navigator.navigate('/detail', { state: { id: 42 } }), Then the state { id: 42 } is associated with the new history entry.
  • Given the same setup, When the developer calls navigator.navigate() with no arguments, Then it should navigate to the current path (no-op or refresh semantics, matching main behavior).
  • Given code that calls provider.navigate(to, opts) on main, When the same call is made on react-18 after this change, Then the navigation result is equivalent (push or replace with state).

Non-goals

  • Refactoring push() and replace() to delegate to navigate() internally (the main branch does this, but it is not required for the backport — keep the diff small).
  • Backporting the full NavigationProvider class rewrite, telemetry integration, or BaseModuleProvider base class from main.
  • Changing the INavigator interface inheritance (Observable + History) on react-18.
  • Adding the @equinor/fusion-framework-react-router package to the react-18 branch.

Validation

  • Unit test: Navigator.navigate(to) pushes a history entry.
  • Unit test: Navigator.navigate(to, { replace: true }) replaces the current entry.
  • Unit test: Navigator.navigate(to, { state }) forwards state correctly.
  • Type check: NavigateOptions is exported and importable.
  • Existing push() and replace() tests continue to pass unchanged.

Notes

  • Target branch: react-18 in equinor/fusion-framework
  • Target package: @equinor/fusion-framework-module-navigation (currently v6.0.1)
  • Reference implementation on main: NavigationProvider.ts

Metadata

Metadata

Assignees

No one assigned
    No fields configured for User Story.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions