NavigationProvider
Supplies the function useNavigate() returns to everything below it; TwilightProvider mounts one for TanStack Router, and tests can mount their own.
import { NavigationProvider } from '@salla.sa/twilight-theme-engine/providers';In plain words
useNavigate() does not know your router. NavigationProvider hands it the function that really changes the page, and TwilightProvider mounts one for you.
Mount your own to record navigation in a test, or to plug in a different router.
Signature
function NavigationProvider(props: { navigate: NavigateFn; children: ReactNode }): JSX.ElementTry it live
import { render, screen, fireEvent } from '@testing-library/react';
import { NavigationProvider } from '@salla.sa/twilight-theme-engine/providers';
import { CheckoutButton } from './CheckoutButton';
it('navigates to /cart', () => {
const navigate = vi.fn();
render(
<NavigationProvider navigate={navigate}>
<CheckoutButton />
</NavigationProvider>
);
fireEvent.click(screen.getByRole('button'));
expect(navigate).toHaveBeenCalledWith('/cart', { replace: false });
});
Example
import { fireEvent, render, screen } from '@testing-library/react';
import { NavigationProvider } from '@salla.sa/twilight-theme-engine/providers';
import { CheckoutButton } from '../app/components/CheckoutButton';
it('goes to the cart', () => {
const navigate = vi.fn();
render(
<NavigationProvider navigate={navigate}>
<CheckoutButton />
</NavigationProvider>
);
fireEvent.click(screen.getByRole('button'));
expect(navigate).toHaveBeenCalledWith('/cart');
});
How it behaves
The TanStack setup passes
(to, opts) => navigate({ to: localizeDestination(to, locale), replace: opts?.replace }); that is where the automatic locale comes from.It affects
useNavigate()andNavigationInterceptoronly. The engineLinkrenders throughLinkProviderand ignores it.With no provider,
useNavigate()returns the default, which assignstotowindow.location(or callslocation.replace(to)withreplace): a full page load.The provider builds a new context value on every render, so its consumers render again whenever it does. Pass a stable function (
useCallback) and keep the provider high in the tree.
Related
Returns a navigate(path) function that moves to another store page from code, without reloading the whole page.
NavigationInterceptorTurns clicks on ordinary links to this store, including links inside Salla web components, into in-app navigation instead of full reloads.
LinkProviderTells the engine's Link which real anchor component to render; TwilightProvider supplies TanStack Router's, and tests can supply a plain one.
Source and docs
- Engine source:
packages/theme-engine/src/providers/NavigationProvider.ts