redirect

Trigger an HTTP redirect from any page, endpoint, middleware, or server function. This function throws internally and never returns — the framework catches the thrown RedirectError and converts it to the appropriate HTTP redirect response.

Import

import { redirect } from 'catmint/routing'

Signature

function redirect(url: string, opts?: RedirectOptions): never

Parameters

ParameterTypeRequiredDescription
urlstringYesThe URL to redirect to.
optsRedirectOptionsNoRedirect configuration.

RedirectOptions

interface RedirectOptions {
  status?: 301 | 302 | 303 | 307 | 308
  headers?: Record<string, string>
}
FieldTypeDefaultDescription
status301 | 302 | 303 | 307 | 308302HTTP redirect status code.
headersRecord<string, string>{}Additional headers on the redirect response.

Return Value

This function never returns. It always throws a RedirectError.

Behavior by Context

ContextBehavior
Page componentAborts rendering and responds with a redirect Response.
EndpointResponds with a redirect Response.
MiddlewareShort-circuits the chain and responds with a redirect Response.
Server functionThrows a RedirectError that propagates to the calling page or endpoint.
Client componentPerforms a client-side navigation via the router.

Errors

Throws a TypeError if an invalid status code is provided. Valid codes are: 301, 302, 303, 307, 308.

Related: RedirectError

class RedirectError extends Error {
  readonly url: string
  readonly status: number
  readonly headers: Record<string, string>

  toResponse(): Response
}

You can check for redirect errors using isRedirectError:

import { isRedirectError } from 'catmint/routing'

if (isRedirectError(error)) {
  return error.toResponse()
}

Examples

import { redirect } from 'catmint/routing'

// Default 302 temporary redirect
redirect('/login')

// Permanent redirect
redirect('/new-page', { status: 301 })

// With custom headers
redirect('/login', {
  status: 303,
  headers: { 'X-Reason': 'unauthenticated' },
})
// Redirect from a page
import { redirect } from 'catmint/routing'

export default async function DashboardPage() {
  const user = await getUser()
  if (!user) {
    redirect('/login')
  }
  return <div>Welcome, {user.name}</div>
}
// Redirect from middleware
import { middleware } from 'catmint/middleware'
import { redirect } from 'catmint/routing'

export default middleware(async (req, next) => {
  const session = await getSession(req)
  if (!session && req.url.startsWith('/dashboard')) {
    redirect('/login')
  }
  return next()
})

See Also