redirect

redirect 函式允許您將使用者重新導向至另一個 URL。redirect 可用於伺服器元件 (Server Components)路由處理器 (Route Handlers)伺服器動作 (Server Actions)

串流情境 (streaming context) 中使用時,此函式會插入一個 meta 標籤以在客戶端觸發重新導向。在伺服器動作中使用時,它會向呼叫者返回 303 HTTP 重新導向回應。其他情況下則會返回 307 HTTP 重新導向回應。

若資源不存在,您可以使用 notFound 函式 替代。

須知事項:

  • 在伺服器動作和路由處理器中,redirect 應在 try/catch 區塊後呼叫。
  • 若您希望返回 308 (永久) HTTP 重新導向而非 307 (暫時),可使用 permanentRedirect 函式 替代。

參數

redirect 函式接受兩個參數:

redirect(path, type)
參數類型說明
pathstring要重新導向的 URL,可以是相對或絕對路徑。
type'replace' (預設) 或 'push' (在伺服器動作中預設)重新導向的類型。

預設情況下,redirect伺服器動作 (Server Actions) 中會使用 push (在瀏覽器歷史堆疊中添加新項目),在其他地方則使用 replace (替換瀏覽器歷史堆疊中的當前 URL)。您可以透過指定 type 參數來覆蓋此行為。

type 參數在伺服器元件中使用時無效。

返回值

redirect 不返回任何值。

範例

伺服器元件

呼叫 redirect() 函式會拋出 NEXT_REDIRECT 錯誤,並終止所在路由區段的渲染。

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 不需要使用 return redirect(),因為它使用了 TypeScript 的 never 類型。

客戶端元件

redirect 可直接在客戶端元件中使用。

'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 鉤子。

'use client'

import { navigate } from './actions'

export function ClientRedirect() {
  return (
    <form action={navigate}>
      <input type="text" name="id" />
      <button>Submit</button>
    </form>
  )
}

常見問題

為什麼 redirect 使用 307 和 308?

使用 redirect() 時,您可能會注意到它使用 307 表示暫時重新導向,308 表示永久重新導向。傳統上,302 用於暫時重新導向,301 用於永久重新導向,但許多瀏覽器在使用 302 時會將重新導向的請求方法從 POST 更改為 GET,無論原始請求方法為何。

以從 /users 重新導向至 /people 為例,若您向 /users 發送 POST 請求以建立新使用者,並遵循 302 暫時重新導向,請求方法將從 POST 變更為 GET。這並不合理,因為建立新使用者應向 /people 發送 POST 請求,而非 GET 請求。

307 狀態碼的引入確保了請求方法會保留為 POST

  • 302 - 暫時重新導向,會將請求方法從 POST 更改為 GET
  • 307 - 暫時重新導向,會保留請求方法為 POST

redirect() 方法預設使用 307 而非 302 暫時重新導向,這意味著您的請求將始終保留為 POST 請求。

深入了解 HTTP 重新導向。

版本歷史

版本變更
v13.0.0引入 redirect

On this page