Utilities
LinkProvider
A provider that sends each link of ferry-ui through the link component of your router.
Utilities
A provider that sends each link of ferry-ui through the link component of your router.
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
LinkProvider,
toast,
type LinkComponent,
} from 'ferry-ui'
// In a real app, the adapter renders the link of the router: <Link to={href} {...props} />.
// This adapter stays on the page and shows the target of the link.
const DemoLink: LinkComponent = ({ href, onClick, ...props }) => (
<a
href={href}
{...props}
onClick={(event) => {
onClick?.(event)
event.preventDefault()
toast('The link component got a click', { description: `Target: ${href}` })
}}
/>
)
export default function LinkProviderHero() {
return (
// A real app mounts the provider one time, near its root.
<LinkProvider component={DemoLink}>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#customers">Customers</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="#acme">Acme</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>INV-2041</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</LinkProvider>
)
}ferry-ui does not import a router. A component with a link takes an href string and renders an <a> element. LinkProvider replaces this element with the link of your router. Then a click does not load a full page.
Write an adapter at module level. Mount the provider one time, near the root of the app.
import type { ReactNode } from 'react'
import { Link } from 'react-router'
import { LinkProvider, type LinkComponent } from 'ferry-ui'
// Module level: the component keeps the same identity between renders.
const RouterLink: LinkComponent = ({ href, ...props }) => <Link to={href} {...props} />
export function Providers({ children }: { children: ReactNode }) {
return <LinkProvider component={RouterLink}>{children}</LinkProvider>
}href and the attributes of an anchor, for example className, onClick and aria-current. Give them all to the link.<a> elements.The adapter gives href to the link of your router. ferry-ui gives a plain string. If your router has typed routes, cast href in the adapter.
| Router | Adapter |
|---|---|
| React Router | ({ href, ...props }) => <Link to={href} {...props} /> |
| Next.js | ({ href, ...props }) => <NextLink href={href} {...props} /> |
| TanStack Router | ({ href, ...props }) => <Link to={href} {...props} /> |
The Routing page shows the full setup.
These components render their links through the provider. Each one also has a linkComponent prop.
| Page | Components |
|---|---|
| Breadcrumb | BreadcrumbLink |
| Page | PageBackLink |
| Resource Card | ResourceCard |
| Description List | DescriptionItem |
| Top Bar | TopBarLogo, TopBarSegment, TopBarIconButton |
| Icon Rail | IconRail, IconRailItem |
| Mobile Nav | MobileNav |
| Inner Menu | InnerMenu |
| Command Menu | CommandMenu |
| Resource Switcher | ResourceSwitcher |
A navigation item with external does not use the link component. It is a plain <a> element that opens a new tab.
The linkComponent prop of a component overrides the provider for this component.
const PlainLink: LinkComponent = (props) => <a {...props} />
<PageBackLink href="/customers" linkComponent={PlainLink}>
Customers
</PageBackLink>Does your component render a link? Call useLinkComponent() to get the link component. Give it the linkComponent prop of your component.
import type { ReactNode } from 'react'
import { cn, useLinkComponent, type LinkComponent } from 'ferry-ui'
interface DocsLinkProps {
href: string
children: ReactNode
className?: string
/** Overrides the `LinkProvider` of the app for this link. */
linkComponent?: LinkComponent
}
export function DocsLink({ href, children, className, linkComponent }: DocsLinkProps) {
const Link = useLinkComponent(linkComponent)
return (
<Link href={href} className={cn('text-primary underline-offset-4 hover:underline', className)}>
{children}
</Link>
)
}| Prop | Type | Default |
|---|---|---|
componentRequired | LinkComponent | - |
The link to render for every ferry-ui link below (a router adapter). Must forward all props to an anchor. Define it at module level so it keeps the same identity between renders. | ||
children | ReactNode | - |
The part of the app whose ferry-ui links go through | ||
useLinkComponent(override) returns a LinkComponent. If you give override, the hook returns it. If not, the hook returns the component of the nearest provider, or a plain <a>.
| Parameter | Type | Role |
|---|---|---|
override | LinkComponent, optional | The linkComponent prop of your component. |
| Type | Definition |
|---|---|
LinkComponent | React.ComponentType<LinkComponentProps> |
LinkComponentProps | The attributes of the <a> element, with a required href string. |
LinkProviderProps | The props of LinkProvider. |