skills/harlan-zw/vue-ecosystem-skills/tanstack-vue-router-skilld

tanstack-vue-router-skilld

SKILL.md

TanStack/router @tanstack/vue-router

Modern and scalable routing for Vue applications

Version: 1.167.0 (Mar 2026) Deps: @tanstack/vue-store@^0.9.1, @vue/runtime-dom@^3.5.25, isbot@^5.1.22, jsesc@^3.0.2, tiny-invariant@^1.3.3, tiny-warning@^1.0.3, @tanstack/history@1.161.4, @tanstack/router-core@1.167.0 Tags: latest: 1.167.0 (Mar 2026)

References: Docs — API reference, guides

API Changes

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: protocolAllowlistcreateRouter 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: defaultViewTransitioncreateRouter option accepting boolean | ViewTransitionOptions to enable native View Transitions API (document.startViewTransition()) during navigation; supports types array via ViewTransitionOptions source

  • NEW: rewritecreateRouter 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 & InnerWrapcreateRouter 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

Also changed: rootRouteWithContext deprecated → use createRootRouteWithContext · useCanGoBack() new experimental hook · defaultRemountDeps new router option · defaultStructuralSharing new router option · search.strict new router option · disableGlobalCatchBoundary new router option · scrollToTopSelectors new router option · composeRewrites new export · ClientOnly / ScriptOnce / HeadContent / Asset new components · SearchSchemaInput tag for optional search params · state.__TSR_key replaces deprecated state.key

Best Practices

  • 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

Weekly Installs
26
GitHub Stars
141
First Seen
Feb 19, 2026
Installed on
github-copilot23
opencode22
claude-code22
codex22
kimi-cli22
gemini-cli22