[]previous and next page

Navigation

Navigation in the Next.js to ShadowJS guide.

For agentsUpdated

next/link becomes A. It renders a real <a>, navigates on a plain click, and leaves modified clicks, target, download, rel="external", absolute URLs and unsafe schemes to the browser. activeClass and aria-current="page" mark the active link (end limits it to the exact location). It preloads its target on hover (after 50 ms), focus or touch by default (preload="intent"); preload="viewport" and preload={false} change that. The client entry that Dusk generates additionally preloads the loader data of any same-origin link the pointer reaches.

jsx
<Link href={`/posts/${post.id}`} prefetch={false} className="nav">{post.title}</Link>
src/links.tsxtsx
import { A, createMemoryHistory, createRouter, defineRoute, RouterProvider } from "@shadow-js/router";

const router = createRouter({
  routes: [defineRoute("/posts/:id")],
  history: createMemoryHistory({ initialEntries: ["/"] }),
});

export function Links() {
  return (
    <RouterProvider router={router}>
      <nav>
        <A to="/posts/:id" params={{ id: "7" }} search={{ tab: "comments" }} hash="top" class="nav">
          Post 7
        </A>
        <A href="https://example.com/">Docs</A>
      </nav>
    </RouterProvider>
  );
}
next/navigation, next/router @shadow-js/router Notes
useRouter().push(to) useNavigate()(to) or useRouter().navigate(to) Returns a promise of the outcome; redirects, not-found and canceled navigations resolve, they do not throw
useRouter().replace(to) navigate(to, { replace: true })
useRouter().back(), forward() useRouter().history.back(), history.forward(), history.go(n)
useRouter().refresh() useRouter().invalidate() Reloads loader data
useRouter().prefetch(to) useRouter().preload(to)
usePathname() useLocation().pathname App-relative, without the base
useSearchParams() useSearch() for validated values, useLocation().search for the raw string Read-only; change it with navigate
useParams() useParams() A view with one memo per key
useSelectedLayoutSegment() useMatches() or useMatch() Accessors of the rendered chain
redirect(to), permanentRedirect(to) throw redirect(to, { status }) from @shadow-js/dusk in beforeLoad or a loader; <Navigate to> in a component Status 302 by default; 301, 303, 307, 308 allowed
notFound() throw notFound()
router.events useNavigation().pending, useBeforeLeave, useBlocker (from @shadow-js/router/blockers) In-app transitions only

The hooks throw outside a RouterProvider; A does too.