You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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
Story
As a Fusion app developer on the
react-18branch, I want theNavigationProvider(Navigator) to expose anavigate(to?, options?)method, so that I can use the same navigation API available onmainwithout upgrading to React 19.Context
The
react-18branch ofequinor/fusion-frameworkpreserves React 18 compatibility for apps that have not yet migrated to React 19. Onmain,@equinor/fusion-framework-module-navigationv7.0.0 introduced a unifiednavigate(to?, options?)method on theNavigationProviderclass (NavigationProvider.ts). This method combines the behavior ofpush()andreplace()with explicitNavigateOptions(replace flag, state), and bothpush()andreplace()now delegate to it internally.On the
react-18branch (@equinor/fusion-framework-module-navigationv6.0.1), theNavigatorclass innavigator.tsonly exposespush(to, state?)andreplace(to, state?). There is nonavigate()method. This means:react-18branch cannot usenavigate()and must use the lower-levelpush/replacepair directly.mainbranch API is not portable toreact-18without changes.navigate()on the provider (e.g., context-change navigation patterns inuseAppContextNavigation) cannot be backported cleanly.Source references
main@equinor/fusion-framework-module-navigationNavigationProviderpackages/modules/navigation/src/NavigationProvider.tsreact-18@equinor/fusion-framework-module-navigationNavigatorpackages/modules/navigation/src/navigator.tsFunctional requirements
navigate(to?: To, options?: Partial<NavigateOptions>)method to theNavigatorclass on thereact-18branch.Totarget and optionalNavigateOptionswith at leastreplace(boolean) andstate(unknown).options.replaceistrue, the method should call the underlyingreplace(); otherwise it should callpush().push()andreplace()methods should remain unchanged (no delegation refactor required on this branch — keep the change minimal).NavigateOptionstype from the package so consumers can import it.mainbranchINavigationProvider.navigate()contract to ease future migration.Scenarios
@equinor/fusion-framework-module-navigationv6.x on thereact-18branch, When the developer callsnavigator.navigate('/users'), Then a new history entry is pushed for/users.navigator.navigate('/login', { replace: true }), Then the current history entry is replaced with/login.navigator.navigate('/detail', { state: { id: 42 } }), Then the state{ id: 42 }is associated with the new history entry.navigator.navigate()with no arguments, Then it should navigate to the current path (no-op or refresh semantics, matchingmainbehavior).provider.navigate(to, opts)onmain, When the same call is made onreact-18after this change, Then the navigation result is equivalent (push or replace with state).Non-goals
push()andreplace()to delegate tonavigate()internally (themainbranch does this, but it is not required for the backport — keep the diff small).NavigationProviderclass rewrite, telemetry integration, orBaseModuleProviderbase class frommain.INavigatorinterface inheritance (Observable + History) onreact-18.@equinor/fusion-framework-react-routerpackage to thereact-18branch.Validation
Navigator.navigate(to)pushes a history entry.Navigator.navigate(to, { replace: true })replaces the current entry.Navigator.navigate(to, { state })forwards state correctly.NavigateOptionsis exported and importable.push()andreplace()tests continue to pass unchanged.Notes
react-18inequinor/fusion-framework@equinor/fusion-framework-module-navigation(currently v6.0.1)main:NavigationProvider.ts