React Router and TanStack Router

Merid's navigation parts render an <a> by default and accept an as prop for a router's link component. The router then handles the click, and Merid keeps the classes, aria-current and focus styles.

ComponentRouter propNotes
SidebarNav.ItemasPass active yourself; it sets aria-current="page".
Breadcrumb.LinkasThe last crumb is Breadcrumb.Page, not a link.
CardasUse with interactive for a clickable card.
Button, Link—No as yet: put the classes on the router link (below).

React Router

tsx
import { Link as RouterLink, NavLink, useLocation } from "react-router";
import { Breadcrumb, SidebarNav } from "@merid/react";

function AppNav() {
  const { pathname } = useLocation();
  return (
    <SidebarNav aria-label="Main">
      <SidebarNav.Item as={RouterLink} to="/" href="/" active={pathname === "/"}>Overview</SidebarNav.Item>
      <SidebarNav.Item as={RouterLink} to="/settings" href="/settings" active={pathname.startsWith("/settings")}>
        Settings
      </SidebarNav.Item>
    </SidebarNav>
  );
}

<Breadcrumb.Link as={RouterLink} to="/projects">Projects</Breadcrumb.Link>

React Router's Link takes to; passing href as well keeps TypeScript happy with Merid's anchor props and is ignored by the router. Avoid NavLink here: its className function signature conflicts with Merid's string class. Compute active from useLocation or useMatch instead.

TanStack Router

tsx
import { Link, useMatchRoute } from "@tanstack/react-router";
import { SidebarNav } from "@merid/react";

function AppNav() {
  const matchRoute = useMatchRoute();
  return (
    <SidebarNav aria-label="Main">
      <SidebarNav.Item as={Link} to="/projects" active={Boolean(matchRoute({ to: "/projects", fuzzy: true }))}>
        Projects
      </SidebarNav.Item>
    </SidebarNav>
  );
}

TanStack's Link renders an <a href> itself, so to is enough. Its typed route checking does not flow through as; if you want it, wrap the link once:

tsx
import { createLink } from "@tanstack/react-router";
import { SidebarNavItem } from "@merid/react";

export const NavItem = createLink(SidebarNavItem);
// <NavItem to="/projects/$id" params={{ id }} active={…}>Northwind</NavItem>

Buttons that navigate

Button renders a <button>. For navigation, use a link with Merid's button classes so middle-click, "open in new tab" and prefetching keep working:

tsx
<RouterLink to="/projects/new" className="mrd-button" data-variant="primary" data-size="md">
  <span className="mrd-button__content">New project</span>
</RouterLink>

Pagination

Pagination takes onPageChange; drive it from the URL:

tsx
const [params, setParams] = useSearchParams();
const page = Number(params.get("page") ?? 1);

<Pagination pageCount={20} page={page} onPageChange={(p) => setParams({ page: String(p) })} />