Skip to content
Twilight React Playground
ثيم رائدaren

NavigationInterceptor

componentAdvancedbrowser

Turns clicks on ordinary links to this store, including links inside Salla web components, into in-app navigation instead of full reloads.

import { NavigationInterceptor } from '@salla.sa/twilight-theme-engine/providers';

In plain words

Salla's web components (the menu, product lists) render plain links that would reload the whole page. NavigationInterceptor is an invisible component that listens for clicks on such links and, when a link points to this store, moves there through the router instead.

TwilightProvider mounts it for you; you only need to know it exists to switch it off, or to understand why a link still reloads.

Signature

function NavigationInterceptor(): null

Example

app/routes/__root.tsx (excerpt)
import { TwilightProvider } from '@salla.sa/twilight-theme-engine';

// Opt out: every plain link then does a normal browser navigation.
<TwilightProvider translations={themeTranslations} client={{ interceptLinks: false }}>
  <Outlet />
</TwilightProvider>;

How it behaves

  • It listens for click on document in the capture phase and finds the anchor with event.composedPath(), so links inside shadow DOM count.

  • A click is left to the browser when: it was already defaultPrevented; a modifier key was held; target is _blank, _parent or _top; the link has download or rel="external"; it has no href or a javascript: one; the pointer moved more than 10px between press and release (a swipe); or the link's origin differs from store.url's origin.

  • An accepted link becomes a store path (resolveRelativePath, which also removes the username segment Salla-hosted store URLs carry) and goes to navigate() from useNavigate().

  • It also tries to replace window.location.assign and window.location.replace with router-aware versions, restoring them on unmount. Browsers usually make those methods read-only; the failure is caught and the originals stay.

  • TwilightProvider mounts it once isReady, unless client is false or client.interceptLinks is false.

Gotchas

  • Assigning a new address to window.location directly can never be intercepted. In your own code use useNavigate() or the engine Link.

  • It compares a link with store.url, not with the page's own address. On a merchant's domain those are the same. On a local dev server or the preview host they differ: absolute store links from the API are routed in-app, while a relative link such as /ar/cart reloads the page.

Related

Source and docs