Advanced
Routing
The library never hard-codes a router. Components that render an href — NavItem, HeaderNavItem, UserMenuItem — ask one provider which link component to use, and fall back to a plain <a>.
The problem it solves
Without a router integration, href items render a plain <a> — every click is a full page reload, losing client-side transitions, prefetching, and state. LinkProvider fixes that once, at the root: wrap your app, pass your router’s link component, and every href-rendering component in the tree — sidebar items, header nav links, user-menu rows — navigates through your router. All styling, active states, tooltips, and rail behavior carry over unchanged.
import Link from "next/link";
import { LinkProvider, AppShell, Sidebar, NavGroup, NavItem } from "appshell-react";
export default function RootLayout({ children }) {
return (
<LinkProvider component={Link}>
<AppShell safeArea>
<Sidebar variant="docked">
<NavGroup title="Browse" defaultOpen>
{/* Renders a Next.js <Link> — client-side navigation, prefetching */}
<NavItem href="/today" label="Today" active />
<NavItem href="/library" label="Library" />
</NavGroup>
</Sidebar>
{children}
</AppShell>
</LinkProvider>
);
}Other routers
The provider accepts any component that takes { href, className, children, onClick }. Next.js Link matches directly; routers whose link takes to plug in through a one-line adapter:
// React Router / TanStack Router take "to" instead of "href" —
// adapt with one line and pass the adapter to the provider.
import { Link } from "react-router";
const RouterLink = ({ href, ...rest }) => <Link to={href} {...rest} />;
<LinkProvider component={RouterLink}>
<App />
</LinkProvider><a>, so static sites and MPA setups keep working with zero configuration. Custom components can read the active link component themselves via useLinkComponent().API
| Prop | Type | Default | Description |
|---|---|---|---|
| component* | ElementType | — | The component to render for href-based items, e.g. Next.js Link. Any component accepting { href, className, children, onClick } works; adapt routers whose link takes a different prop (React Router's "to") with a one-line wrapper. |
| children* | ReactNode | — | The app. |