A function that takes two arguments: a string path, and an optional number status.
import { redirect } from 'one'
export function redirectToLogin() {
return redirect('/login')
}
It accepts relative paths by using the getURL helper internally.
On the server (including in loaders) it returns a Response.redirect object. On the client it calls router.navigate and returns void.
Use redirect() in loaders to protect routes. When a user navigates via <Link>, the loader runs on the server and the redirect is detected on the client before the protected page ever renders — no flash of unauthorized content, no data leaks.
app/dashboard+ssr.tsx
import { redirect, useLoader } from 'one'
import type { LoaderProps } from 'one'
export function loader({ request }: LoaderProps) {
const session = getSession(request)
if (!session) {
throw redirect('/login')
}
return { user: session.user }
}
export default function Dashboard() {
const { user } = useLoader(loader)
return <Text>Welcome, {user.name}</Text>
}
Both throw redirect() and return redirect() work. throw is often cleaner since it stops execution immediately.
This works for both direct page loads (server returns a 302) and client-side <Link> navigation (server returns a redirect signal that the client intercepts before rendering).
During client-side navigation, loaders run on the server and the client fetches the result as a JavaScript module. When a loader returns redirect():
REPLACE — the protected page never appearsThis means no sensitive data reaches the client when a redirect occurs. The server only sends back the redirect path.
Edit this page on GitHub.