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

TanStackLinkAdapter

componentAdvancedserverbrowserlive demo

The anchor behind the engine's Link under TanStack Router: it adds the current language to internal paths and passes intent preloading on.

import { TanStackLinkAdapter, createTanStackLinkAdapter } from '@salla.sa/twilight-theme-engine/tanstack';

In plain words

The engine's Link component does not render an anchor itself; it asks a link adapter to. Under TwilightProvider with TanStack Router that adapter is TanStackLinkAdapter.

What it adds to TanStack's own Link: on an Arabic page, to="/cart" becomes /ar/cart, so the shopper stays in their language. A path that already starts with a language, and an address on another site, are left as they are.

Theme code uses Link from @salla.sa/twilight-theme-engine/components/common. Import the adapter only to mount a LinkProvider of your own.

Signature

const TanStackLinkAdapter: React.ForwardRefExoticComponent<
  LinkProps & React.RefAttributes<HTMLAnchorElement>
>
// LinkProps (from /components/common): to, href, children, className, style, title,
// target, rel, onClick, preload ('intent' | 'render' | false), replace, 'aria-label', itemProp

function createTanStackLinkAdapter(): typeof TanStackLinkAdapter   // returns the same component

Try it live

Five destinations rendered through TanStackLinkAdapter. The href column is read from each real anchor.Try this: type /brands, then /en/brands: the adapter adds the current language only when the path has none. On localhost the store segment comes first; the router adds that part.
Storefront canvas · ar · RTL
torendered href
/brandsopen
/open
/cartopen
/en/cartopen
https://salla.comopen
Controls
What a theme writes
import { Link } from '@salla.sa/twilight-theme-engine/components/common';

// Theme code uses Link. Under TwilightProvider it renders TanStackLinkAdapter.
export function BrandsLink() {
  return <Link to="/brands">Brands</Link>;
}

Example

app/components/RouterLinks.tsx
import type { ReactNode } from 'react';
import { LinkProvider } from '@salla.sa/twilight-theme-engine/providers';
import { TanStackLinkAdapter } from '@salla.sa/twilight-theme-engine/tanstack';

// For a subtree rendered inside the router but outside TwilightProvider.
// Below TwilightProvider this is already set up for you.
export function RouterLinks({ children }: { children: ReactNode }) {
  return <LinkProvider adapter={TanStackLinkAdapter}>{children}</LinkProvider>;
}

How it behaves

  • The destination is to, else href, else /. When the current route has a locale param and the destination starts with a single /, the locale is prefixed, unless the first segment is already one of the 39 supported locale codes; / becomes /<locale>, such as /ar. Anything else (https://…, //…, #top) passes through.

  • On localhost and the preview host, the store segment (/<username>) is added by the router's rewrite, not by the adapter, so TanStack's own Link gets it too.

  • Only preload="intent" is passed on. "render", false and no value all leave TanStack's default, which createRouter() sets to intent.

  • Every other prop (id, data-*, itemProp…) is spread onto TanStack's Link, and the ref reaches the anchor.

  • createTanStackLinkAdapter() takes no options and returns TanStackLinkAdapter itself.

Gotchas

  • preload={false} does not turn preloading off: the adapter drops it and TanStack falls back to defaultPreload: 'intent', so hovering still loads the next page's data. Where that must not happen, render Link from @tanstack/react-router with preload={false} and a full to, locale included.

Related

Source and docs