This section documents version-specific API changes — prioritize recent major/minor releases.
-
BREAKING: NotFoundRoute & routerOptions.notFoundRoute — deprecated in v1.x; use notFoundComponent in route options or defaultNotFoundComponent in createRouter instead source
-
DEPRECATED: Router Classes (Router, Route, RootRoute, FileRoute) — all class-based APIs are deprecated; use factory functions createRouter, createRoute, createRootRoute, and createFileRoute instead source
-
DEPRECATED: opts.navigate — the navigate argument inside beforeLoad and loader is deprecated; use throw redirect({ to: '...' }) for navigation-triggered redirects instead source
-
DEPRECATED: parseParams & stringifyParams — top-level route properties deprecated in favor of the nested params.parse and params.stringify objects source
-
DEPRECATED: preSearchFilters & postSearchFilters — deprecated in favor of search.middlewares array which provides a composable middleware pipeline for transforming search params source
-
DEPRECATED: <ScrollRestoration /> component — deprecated; configure scroll restoration via scrollRestoration: true in createRouter options instead source
-
NEW: protocolAllowlist — createRouter option accepting Array<string> of allowed URL protocols (e.g. 'https:', 'mailto:'); absolute URLs with unlisted protocols are blocked to prevent XSS; also exports DEFAULT_PROTOCOL_ALLOWLIST constant source
-
NEW: search.middlewares — route option accepting an array of middleware functions ({search, next}) => search for composable search param transformation when generating links; use with retainSearchParams and stripSearchParams helpers source
-
NEW: head, headers, scripts — route option methods for server-side document management; head() injects <meta>, <link>, <style> into <head>; headers() sets HTTP response headers; scripts() injects <script> tags source
-
NEW: Validation Adapters — @tanstack/zod-adapter, @tanstack/valibot-adapter, and @tanstack/arktype-adapter provide schema-based validation for search params and route params with distinct input/output type inference source
-
NEW: defaultViewTransition — createRouter option accepting boolean | ViewTransitionOptions to enable native View Transitions API (document.startViewTransition()) during navigation; supports types array via ViewTransitionOptions source
-
NEW: rewrite — createRouter option accepting { input?, output? } for bidirectional URL transformation between browser URL and router's internal URL; input transforms before matching, output transforms before writing to history source
-
NEW: Wrap & InnerWrap — createRouter options for injecting global providers; Wrap surrounds the entire router, InnerWrap wraps inner content and has access to router context and hooks source
-
NEW: codeSplitGroupings — route option Array<Array<'loader' | 'component' | 'pendingComponent' | 'notFoundComponent' | 'errorComponent'>> for fine-grained control over how lazy-loaded route assets are bundled into chunks source
-
Use zodValidator() adapter with fallback() instead of Zod's .catch() for search param validation — .catch() widens types to unknown, losing type inference, while fallback(z.number(), 1).default(1) retains correct types and makes search optional in <Link> props source
-
In loaderDeps, extract only the search params actually used in the loader — returning the entire search object causes the loader to re-run on any search param change, even unrelated ones like viewMode or sortDirection source
-
Use getRouteApi('/your/path') to access route hooks (useLoaderData, useSearch, useParams) in deeply nested components instead of importing the Route object — direct Route imports from child components create circular dependencies source
-
Enable defaultStructuralSharing: true on the router when using select in hooks like useSearch — without it, select returning a new object on every call triggers unnecessary re-renders even when values are unchanged source
-
Use createRootRouteWithContext<YourContextType>() instead of createRootRoute when injecting shared dependencies (auth, query client, etc.) — this enforces the context type at router creation time and makes context available with full type inference in all descendant beforeLoad and loader functions source
-
Property order inside createFileRoute, createRoute, and createRootRoute objects is inference-sensitive: params/validateSearch must come before loaderDeps, beforeLoad before loader, etc. — wrong order causes type errors where context from beforeLoad isn't visible in loader. Install @tanstack/eslint-plugin-router and enable the create-route-property-order rule (it's fixable) source
-
Use retainSearchParams(['key']) and stripSearchParams(defaultValues) as search.middlewares on a route rather than manually forwarding params in every <Link> — middlewares run automatically on all descendant links and on navigation, keeping the URL clean without repetitive spread patterns source
-
When throwing redirect() inside beforeLoad error handlers, always re-throw errors identified by isRedirect() before converting other errors — otherwise intentional redirects are swallowed as route errors source
-
Use linkOptions({ to, search, ... }) to define reusable navigation targets instead of plain object literals — bare object literals infer to as string (matching every route) and defer type errors until the object is spread into <Link>. linkOptions validates the destination at definition time and the same value works in <Link>, navigate(), and redirect() source
-
Set defaultPreload: 'intent' on the router to preload route data and code-split chunks on link hover — preloaded data is cached for 30 seconds (configurable via defaultPreloadMaxAge) and prevents loader waterfalls on navigation without any per-link configuration source