콘텐츠로 이동

함수: redirect

Source URL: https://nextjs.org/docs/app/api-reference/functions/redirect

마지막 업데이트 2026년 2월 20일

redirect 함수는 사용자를 다른 URL로 리디렉션할 수 있게 해 줍니다. redirect서버 및 클라이언트 컴포넌트, 라우트 핸들러, 서버 함수에서 렌더링 중에 사용할 수 있습니다.

스트리밍 컨텍스트에서 사용하면 클라이언트 측에서 리디렉션을 발생시키는 메타 태그를 삽입합니다. 서버 액션에서 사용하면 호출자에게 303 HTTP 리디렉션 응답을 반환합니다. 그 밖의 경우에는 호출자에게 307 HTTP 리디렉션 응답을 반환합니다.

리소스가 존재하지 않을 때는 notFound 함수를 대신 사용할 수 있습니다.

redirect 함수는 두 개의 인수를 받습니다:

redirect(path, type)
ParameterTypeDescription
pathstring리디렉션할 URL입니다. 상대 경로나 절대 경로 모두 사용할 수 있습니다.
type'replace'(기본값) 또는 'push'(서버 액션의 기본값)수행할 리디렉션 유형입니다.

기본적으로 redirect서버 액션에서는 push(브라우저 히스토리 스택에 새 항목 추가)를 사용하고, 그 외 모든 곳에서는 replace(브라우저 히스토리 스택의 현재 URL 교체)를 사용합니다. type 매개변수를 지정해 이 동작을 재정의할 수 있습니다.

RedirectType 객체는 type 매개변수에 사용 가능한 옵션을 포함합니다.

import { redirect, RedirectType } from 'next/navigation'
redirect('/redirect-to', RedirectType.replace)
// or
redirect('/redirect-to', RedirectType.push)

type 매개변수는 서버 컴포넌트에서 사용할 때는 아무 효과가 없습니다.

redirect는 값을 반환하지 않습니다.

  • 서버 액션과 라우트 핸들러에서 try/catch 문을 사용할 때는 리디렉션을 try 블록 외부에서 호출해야 합니다.
  • 307(임시) 대신 308(영구) HTTP 리디렉션을 반환하고 싶다면 permanentRedirect 함수를 사용하세요.
  • redirect는 에러를 던지므로 try/catch 문을 쓸 때는 반드시 try 블록 외부에서 호출해야 합니다.
  • redirect는 클라이언트 컴포넌트의 렌더링 과정에서 호출할 수 있지만 이벤트 핸들러에서는 사용할 수 없습니다. 대신 useRouter을 사용할 수 있습니다.
  • redirect는 절대 URL도 허용하며 외부 링크로 리디렉션하는 데 사용할 수 있습니다.
  • 렌더 과정 이전에 리디렉션하고 싶다면 next.config.js 또는 프록시를 사용하세요.

redirect() 함수를 호출하면 NEXT_REDIRECT 오류가 발생하고, 오류가 발생한 라우트 세그먼트의 렌더링이 종료됩니다.

app/team/[id]/page.tsx

JavaScriptTypeScript

import { redirect } from 'next/navigation'
async function fetchTeam(id: string) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
const team = await fetchTeam(id)
if (!team) {
redirect('/login')
}
// ...
}

알아두면 좋은 점 : redirect는 TypeScript never 타입을 사용하므로 return redirect() 형태로 쓸 필요가 없습니다.

redirect는 클라이언트 컴포넌트에서도 바로 사용할 수 있습니다.

components/client-redirect.tsx

JavaScriptTypeScript

'use client'
import { redirect, usePathname } from 'next/navigation'
export function ClientRedirect() {
const pathname = usePathname()
if (pathname.startsWith('/admin') && !pathname.includes('/login')) {
redirect('/admin/login')
}
return <div>Login Page</div>
}

알아두면 좋은 점 : 클라이언트 컴포넌트에서 서버 사이드 렌더링(SSR) 중 초기 페이지 로드 시 redirect를 사용하면 서버 측 리디렉션이 수행됩니다.

redirect는 서버 액션을 통해 클라이언트 컴포넌트에서 사용할 수도 있습니다. 이벤트 핸들러에서 사용자를 리디렉션해야 한다면 useRouter 훅을 사용하세요.

app/client-redirect.tsx

JavaScriptTypeScript

'use client'
import { navigate } from './actions'
export function ClientRedirect() {
return (
<form action={navigate}>
<input type="text" name="id" />
<button>Submit</button>
</form>
)
}

app/actions.ts

JavaScriptTypeScript

'use server'
import { redirect } from 'next/navigation'
export async function navigate(data: FormData) {
redirect(`/posts/${data.get('id')}`)
}

redirect는 307과 308을 사용하나요?

섹션 제목: “왜 redirect는 307과 308을 사용하나요?”

redirect()를 사용할 때 상태 코드가 임시 리디렉션에는 307, 영구 리디렉션에는 308이라는 점을 확인할 수 있습니다. 전통적으로는 임시 리디렉션에 302, 영구 리디렉션에 301을 사용했지만, 많은 브라우저가 302를 사용할 때 원래 요청 메서드와 상관없이 리디렉션 요청 메서드를 POST에서 GET으로 변경했습니다.

/users에서 /people로 리디렉션하는 아래 예시에서, 새로운 사용자를 만들기 위해 /usersPOST 요청을 보내고 302 임시 리디렉션을 따르면, 요청 메서드는 POST에서 GET으로 바뀝니다. 그러나 새 사용자를 만들려면 /peoplePOST 요청을 보내야 하며, GET 요청으로는 의미가 없습니다.

307 상태 코드가 도입되면서 요청 메서드를 POST 그대로 유지할 수 있게 되었습니다.

  • 302 - 임시 리디렉션이며 요청 메서드를 POST에서 GET으로 변경합니다.
  • 307 - 임시 리디렉션이며 요청 메서드를 POST로 유지합니다.

redirect() 메서드는 기본적으로 302 대신 307 임시 리디렉션을 사용하므로, 요청이 항상 POST로 유지됩니다.

HTTP 리디렉션에 대해 더 알아보기.

VersionChanges
v13.0.0redirect가 도입되었습니다.