Errors, Redirects, and Search Utilities

Purpose and Scope

This reference groups the Router APIs that deliberately interrupt normal route work or normalize URL search state. In TanStack Router, a route can return or throw a not-found object to select a notFoundComponent, return or throw a redirect object to move to another location, and use search middleware to keep or remove query values as links and navigations are built. These APIs often appear inside beforeLoad, loader, route definitions, and error-handling code, so the most important decision is whether you are representing a missing resource, an intentional navigation, or URL cleanup.

Sources: docs/router/api/router/notFoundFunction.md, docs/router/api/router/redirectFunction.md, docs/router/api/router/retainSearchParamsFunction.md, docs/router/api/router/stripSearchParamsFunction.md

The APIs on this page are intentionally small, but they carry routing semantics. A NotFoundError is not just a generic exception; Router uses it to locate the route-level not-found boundary that should render. A Redirect is not just a string URL; it extends navigation options and may include server-oriented metadata such as headers or status code. Search middlewares are not validators; they run as transformation helpers that decide which validated search keys should remain in the URL. Keeping those roles separate makes route code easier to reason about.

Sources: docs/router/api/router/NotFoundErrorType.md, docs/router/api/router/RedirectType.md, docs/router/api/router/retainSearchParamsFunction.md, docs/router/api/router/stripSearchParamsFunction.md

Relevant Source Files

  • docs/router/api/router/notFoundFunction.md documents the notFound function, its optional options object, return-versus-throw behavior, and examples from route loaders.
  • docs/router/api/router/NotFoundErrorType.md defines the public NotFoundError shape, including data, throw, routeId, headers, and the deprecated global flag.
  • docs/router/api/router/redirectFunction.md documents the standalone redirect function, route-bound redirect helpers, and internal versus external redirect examples.
  • docs/router/api/router/RedirectType.md defines the public Redirect shape, its relationship to NavigateOptions, and the distinction between to and href.
  • docs/router/api/router/isNotFoundFunction.md documents isNotFound(input) as the type guard-style helper for recognizing not-found objects.
  • docs/router/api/router/isRedirectFunction.md documents isRedirect(input) as the helper for recognizing redirect objects.
  • docs/router/api/router/retainSearchParamsFunction.md documents search middleware that preserves selected or all search parameters.
  • docs/router/api/router/stripSearchParamsFunction.md documents search middleware that removes selected, default-valued, or all removable search parameters.

Not Found API

Use notFound when a route successfully matched the URL pattern but the resource or route-specific condition cannot be satisfied. The docs show it being used from route loader callbacks, including one case where a missing post triggers the current route not-found handling and another where a missing team targets the root route by passing routeId: rootRouteId. The function accepts an optional Partial<NotFoundError>. If the throw property is true, the function throws during the call; otherwise it returns the not-found object so the caller can throw or return it explicitly.

Sources: docs/router/api/router/notFoundFunction.md, docs/router/api/router/NotFoundErrorType.md

NotFoundError carries routing data rather than only an error message. data is custom payload delivered to the not-found component. routeId chooses the route that first attempts to handle the not-found state, after which the error can bubble to parents if that route has no notFoundComponent. headers supplies HTTP headers when the not-found is handled on the server side. The global property is documented as deprecated; route code should prefer routeId: rootRouteId when the whole page should be handled by the root route not-found UI.

Sources: docs/router/api/router/NotFoundErrorType.md

import { notFound, createFileRoute, rootRouteId } from '@tanstack/react-router'
 
const Route = createFileRoute('/posts/$postId')({
  loader: ({ context: { post } }) => {
    if (!post) throw notFound()
  },
  beforeLoad: ({ context: { team } }) => {
    if (!team) throw notFound({ routeId: rootRouteId })
  },
})

Redirect API

Use redirect when route work decides that the user should navigate somewhere else. The standalone function accepts a required Redirect options object and follows the same return-versus-throw convention as notFound: throw: true throws inside the helper, while an omitted or false throw returns the redirect object. The examples distinguish internal redirects, which use to, from external redirects, which use href. That distinction matters because to is for Router-managed application routes, while href is the documented escape hatch for URLs such as external authentication providers.

Sources: docs/router/api/router/redirectFunction.md, docs/router/api/router/RedirectType.md

Redirect is defined as server-aware navigation metadata plus NavigateOptions. Its direct properties are statusCode, throw, and headers; navigation properties come from the extended navigation options. The docs also describe route-bound redirect helpers through Route.redirect in file-based route files and getRouteApi().redirect outside the route definition file. Those helpers automatically set the origin route, so relative redirect targets such as ../login and ./migrate can be checked against the route tree without manually supplying from. Prefer these helpers when redirecting relative to a known route.

Sources: docs/router/api/router/redirectFunction.md, docs/router/api/router/RedirectType.md

import { redirect } from '@tanstack/react-router'
 
const route = createRoute({
  beforeLoad: () => {
    if (!user) {
      throw redirect({ to: '/login' })
    }
    if (needsExternalAuth) {
      throw redirect({ href: 'https://authprovider.com/login' })
    }
  },
})

Detection Helpers

isNotFound and isRedirect are recognition helpers for code that receives an unknown thrown or returned value. isNotFound(input) accepts one required unknown input and returns true when the value is a NotFoundError, otherwise false. isRedirect(input) follows the same shape for redirect objects. These helpers are useful in shared error handling, test assertions, middleware, logging, and framework integration code where catching all thrown values is unavoidable but downstream behavior should still branch on Router-specific control objects instead of fragile ad hoc property checks.

Sources: docs/router/api/router/isNotFoundFunction.md, docs/router/api/router/isRedirectFunction.md

The detection helpers complement the throw options on notFound and redirect. If your route code directly throws notFound() or redirect(...), Router can consume those values through its route lifecycle. If your own boundary, utility, or integration catches an unknown, use isNotFound or isRedirect before reading Router-specific fields. This preserves the difference between ordinary exceptions, not-found routing states, and redirect routing states, and it keeps TypeScript-facing code aligned with the documented API contract of taking unknown rather than assuming an error class.

Sources: docs/router/api/router/isNotFoundFunction.md, docs/router/api/router/isRedirectFunction.md

Search Middleware Utilities

retainSearchParams and stripSearchParams are search middleware functions for controlling what remains in the URL after validation and navigation. retainSearchParams either accepts true, meaning all search params should be retained, or a list of keys that should be retained. The documented examples place it under a route search.middlewares array next to validateSearch, including a root route that preserves rootValue and a file route that retains all search parameters. Use it when a parent route owns search state that should survive child navigation.

Sources: docs/router/api/router/retainSearchParamsFunction.md

stripSearchParams removes search values and supports three documented input forms. Passing true strips all search params when the schema has no required params. Passing a list of keys removes only those optional search params. Passing an object compares current search values against that partial input schema and removes deeply equal values, which is the recommended pattern for stripping default values from the URL. This lets a route validate defaults for application code while keeping canonical URLs clean and avoiding noisy query strings.

Sources: docs/router/api/router/stripSearchParamsFunction.md

import { z } from 'zod'
import { createFileRoute, stripSearchParams } from '@tanstack/react-router'
 
const defaultValues = { one: 'abc', two: 'xyz' }
 
const searchSchema = z.object({
  one: z.string().default(defaultValues.one),
  two: z.string().default(defaultValues.two),
})
 
export const Route = createFileRoute('/')({
  validateSearch: searchSchema,
  search: {
    middlewares: [stripSearchParams(defaultValues)],
  },
})

Compact Reference

APIInputOutput or behaviorPrimary use
notFound(options?)Optional Partial<NotFoundError>Returns a NotFoundError, or throws it when options.throw is trueTrigger route not-found handling from loaders or beforeLoad
NotFoundErrorObject with global, data, throw, routeId, headersRouter-specific not-found control objectSelect not-found UI, attach data, and support server headers
redirect(options)Required Redirect objectReturns a redirect object, or throws it when options.throw is trueNavigate internally with to or externally with href
RedirectstatusCode, throw, headers, plus NavigateOptionsRouter-specific redirect actionCarry navigation and server redirect metadata
isNotFound(input)Required unknownbooleanIdentify a NotFoundError safely
isRedirect(input)Required unknownbooleanIdentify a redirect object safely
retainSearchParams(input)true or a list of keysSearch middlewarePreserve all or selected search params
stripSearchParams(input)true, a list of optional keys, or a partial default-value objectSearch middlewareRemove all removable, selected, or default-valued search params

Implementation Guidance

Choose the smallest control object that describes the route outcome. A missing database row for a matched route is a notFound, not a redirect. A user who must authenticate before viewing a route is usually a redirect to a login route, often from beforeLoad. Search middleware belongs in route configuration because it describes how that route wants URL state to be preserved or normalized. Detection helpers belong at boundaries where the input type is unknown. Keeping these responsibilities in their documented places produces clearer route lifecycles and cleaner URLs.

Sources: docs/router/api/router/notFoundFunction.md, docs/router/api/router/redirectFunction.md, docs/router/api/router/isNotFoundFunction.md, docs/router/api/router/isRedirectFunction.md, docs/router/api/router/retainSearchParamsFunction.md, docs/router/api/router/stripSearchParamsFunction.md

When adding new route code, start by deciding whether the condition should render UI, move the user, or rewrite search state. For UI, define or reuse a notFoundComponent and throw notFound with routeId only when a specific ancestor should handle it. For navigation, prefer Route.redirect or getRouteApi().redirect when a relative route origin is known, and reserve standalone redirect for cases where that binding is not available. For query strings, pair validateSearch with retain or strip middleware so validated defaults and retained parent state are intentional rather than accidental.