Skip to content
GitHub
Test Failures

TanStack Router Link render tests need router context or a focused mock

TanStack Router Link Render Tests Need Router Context or a Focused Mock

Severity: P2 (blocks render-only frontend tests; simple focused workaround)

Problem

After replacing raw <a> elements with TanStack Router <Link> components, render-only tests using renderToStaticMarkup() can fail before assertions run.

Symptoms:

  • Test stderr includes Warning: useRouter must be used inside a <RouterProvider> component!
  • The failure is TypeError: Cannot read properties of null (reading 'isServer')
  • The production component is correct, but the test renders it outside router context

Root Cause

TanStack Router Link calls router hooks internally. A component-level SSR/render test that imports the real Link without a RouterProvider creates a null router context, so Link fails during render.

Solution

For tests that only assert static shell markup, mock Link narrowly and preserve the real module exports:

vi.mock("@tanstack/react-router", async (importOriginal) => {
const actual = await importOriginal<typeof import("@tanstack/react-router")>();
return {
...actual,
Link: ({
to,
children,
activeProps,
}: {
readonly to: string;
readonly children: ReactNode;
readonly activeProps?: Record<string, string>;
}) => (
<a href={to} {...activeProps}>
{children}
</a>
),
};
});

Keep separate router-registration tests against the real route tree so the mock does not become the only navigation coverage.

Prevention

  • Use real RouterProvider tests when validating navigation behavior.
  • Use a focused Link mock only for render-only shell tests.
  • Pair shell markup tests with route-tree tests that assert paths, loaders, and unauthenticated redirect targets.

References

  • Fixed during SPEC-543 review fixes in apps/dashboard/src/routes/dashboard-shell.test.tsx.