إعادة التوجيه (redirect)

تسمح لك وظيفة redirect بإعادة توجيه المستخدم إلى عنوان URL آخر. يمكن استخدام redirect في مكونات الخادم (Server Components)، معالجات المسارات (Route Handlers)، وأفعال الخادم (Server Actions).

عند استخدامها في سياق البث (streaming context)، سيتم إدراج وسم meta لإصدار إعادة التوجيه على جانب العميل. عند استخدامها في فعل خادم، ستقدم استجابة إعادة توجيه HTTP 303 إلى المتصل. وإلا، ستقدم استجابة إعادة توجيه HTTP 307 إلى المتصل.

إذا لم يكن المورد موجودًا، يمكنك استخدام وظيفة notFound بدلاً من ذلك.

المرجع

المعاملات

تقبل وظيفة redirect وسيطين:

redirect(path, type)
المعاملالنوعالوصف
pathstringعنوان URL لإعادة التوجيه إليه. يمكن أن يكون مسارًا نسبيًا أو مطلقًا.
type'replace' (افتراضي) أو 'push' (افتراضي في أفعال الخادم)نوع إعادة التوجيه المطلوب تنفيذه.

بشكل افتراضي، ستستخدم redirect push (إضافة إدخال جديد إلى سجل تاريخ المتصفح) في أفعال الخادم (Server Actions) و replace (استبدال عنوان URL الحالي في سجل تاريخ المتصفح) في كل مكان آخر. يمكنك تجاوز هذا السلوك عن طريق تحديد معامل type.

لا يؤثر معامل type عند استخدامه في مكونات الخادم.

القيمة المعادة

لا تعيد redirect أي قيمة.

السلوك

  • في أفعال الخادم ومعالجات المسارات، يجب استدعاء redirect بعد كتلة try/catch.
  • إذا كنت تفضل إرجاع إعادة توجيه HTTP 308 (دائم) بدلاً من 307 (مؤقت)، يمكنك استخدام وظيفة permanentRedirect بدلاً من ذلك.
  • تقوم redirect داخليًا بإلقاء خطأ لذا يجب استدعاؤها خارج كتل try/catch.
  • يمكن استدعاء redirect في مكونات العميل أثناء عملية التصيير ولكن ليس في معالجي الأحداث. يمكنك استخدام خطاف useRouter بدلاً من ذلك.
  • تقبل redirect أيضًا عناوين URL المطلقة ويمكن استخدامها لإعادة التوجيه إلى روابط خارجية.
  • إذا كنت ترغب في إعادة التوجيه قبل عملية التصيير، استخدم next.config.js أو البرمجية الوسيطة (Middleware).

مثال

مكون الخادم

استدعاء وظيفة 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')
  }

  // ...
}
import { redirect } from 'next/navigation'

async function fetchTeam(id) {
  const res = await fetch('https://...')
  if (!res.ok) return undefined
  return res.json()
}

export default async function Profile({ params }) {
  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>
}
'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>
}

معلومة جيدة: عند استخدام redirect في مكون العميل أثناء تحميل الصفحة الأولي خلال تصيير جانب الخادم (SSR)، سيتم تنفيذ إعادة توجيه من جانب الخادم.

يمكن استخدام redirect في مكون العميل من خلال فعل خادم. إذا كنت بحاجة إلى استخدام معالج حدث لإعادة توجيه المستخدم، يمكنك استخدام خطاف useRouter.

'use client'

import { navigate } from './actions'

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

import { navigate } from './actions'

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

import { redirect } from 'next/navigation'

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

import { redirect } from 'next/navigation'

export async function navigate(data) {
  redirect(`/posts/${data.get('id')}`)
}

الأسئلة الشائعة

لماذا تستخدم redirect الرموز 307 و 308؟

عند استخدام redirect() قد تلاحظ أن رموز الحالة المستخدمة هي 307 لإعادة التوجيه المؤقتة، و 308 لإعادة التوجيه الدائمة. بينما تقليديًا كان يتم استخدام 302 لإعادة التوجيه المؤقتة، و 301 لإعادة التوجيه الدائمة، قامت العديد من المتصفحات بتغيير طريقة طلب إعادة التوجيه، من POST إلى GET عند استخدام 302، بغض النظر عن طريقة الطلب الأصلية.

في المثال التالي لإعادة التوجيه من /users إلى /people، إذا قمت بطلب POST إلى /users لإنشاء مستخدم جديد، وكنت تتبع إعادة توجيه مؤقتة 302، ستتغير طريقة الطلب من POST إلى GET. هذا لا معنى له، لأنه لإنشاء مستخدم جديد، يجب أن تقوم بطلب POST إلى /people، وليس GET.

أدخل رمز الحالة 307 يعني الحفاظ على طريقة الطلب كـ POST.

  • 302 - إعادة توجيه مؤقتة، ستغير طريقة الطلب من POST إلى GET
  • 307 - إعادة توجيه مؤقتة، ستحافظ على طريقة الطلب كـ POST

تستخدم طريقة redirect() رمز 307 افتراضيًا، بدلاً من إعادة توجيه مؤقتة 302، مما يعني أن طلباتك سيتم الحفاظ عليها دائمًا كطلبات POST.

تعلم المزيد حول إعادة التوجيه HTTP.

سجل الإصدارات

الإصدارالتغييرات
v13.0.0تم تقديم redirect.