Redirecting

Next.js'de yönlendirmeleri ele alabileceğiniz birkaç yol vardır. Bu sayfa, mevcut her seçeneği, kullanım durumlarını ve çok sayıda yönlendirmenin nasıl yönetileceğini inceleyecektir.

API Purpose Where Status Code
redirect Redirect user after a mutation or event Server Components, Server Actions, Route Handlers 307 (Temporary) or 303 (Server Action)
permanentRedirect Redirect user after a mutation or event Server Components, Server Actions, Route Handlers 308 (Permanent)
useRouter Perform a client-side navigation Event Handlers in Client Components N/A
redirects in next.config.js Redirect an incoming request based on a path next.config.js file 307 (Temporary) or 308 (Permanent)
NextResponse.redirect Redirect an incoming request based on a condition Middleware

redirect function

redirect işlevi, kullanıcıyı başka bir URL'ye yönlendirmenize olanak tanır. redirect işlevini Sunucu Bileşenleri, Rota İşleyicileri ve Sunucu Eylemleri içinde çağırabilirsiniz.

redirect genellikle bir mutasyon veya olaydan sonra kullanılır. Örneğin, bir gönderi oluşturmak:

app/actions.tsx
'use server'
 
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'
 
export async function createPost(id: string) {
  try {
    // Call database
  } catch (error) {
    // Handle errors
  }
 
  revalidatePath('/posts') // Update cached posts
  redirect(`/post/${id}`) // Navigate to the new post page
}

Bildiğim iyi oldu:

  • redirect varsayılan olarak bir 307 (Geçici Yönlendirme) durum kodu döndürür. Bir Sunucu Eyleminde kullanıldığında, genellikle bir POST isteğinin sonucu olarak bir başarı sayfasına yönlendirmek için kullanılan bir 303 (Diğerine Bakın) döndürür.
  • redirect dahili olarak bir hata atar, bu nedenle try/catch bloklarının dışında çağrılmalıdır.
  • redirect oluşturma işlemi sırasında İstemci Bileşenlerinde çağrılabilir ancak olay işleyicilerinde çağrılamaz. Bunun yerine useRouter kancasını kullanabilirsiniz.
  • Render işleminden önce yeniden yönlendirme yapmak istiyorsanız next.config.js veya Orta Yazılım.

Daha fazla bilgi için redirect API referansına bakın.

permanentRedirect function

permanentRedirect işlevi, kullanıcıyı kalıcı olarak başka bir URL'ye yönlendirmenize olanak tanır. permanentRedirect işlevini Sunucu Bileşenlerinde, Rota İşleyicilerinde ve Sunucu Eylemlerinde çağırabilirsiniz.

permanentRedirect genellikle bir varlığın kanonik URL'sini değiştiren bir mutasyon veya olaydan sonra kullanılır, örneğin bir kullanıcının kullanıcı adını değiştirdikten sonra profil URL'sini güncellemek gibi:

app/actions.ts
'use server'
 
import { permanentRedirect } from 'next/navigation'
import { revalidateTag } from 'next/cache'
 
export async function updateUsername(username: string, formData: FormData) {
  try {
    // Call database
  } catch (error) {
    // Handle errors
  }
 
  revalidateTag('username') // Update all references to the username
  permanentRedirect(`/profile/${username}`) // Navigate to the new user profile
}

Bildiğim iyi oldu:

  • permanentRedirect varsayılan olarak bir 308 (kalıcı yönlendirme) durum kodu döndürür.
  • Render işleminden önce yeniden yönlendirme yapmak istiyorsanız next.config.js veya Orta Yazılım.

Daha fazla bilgi için permanentRedirect API referansına bakın.

useRouter hook

Bir İstemci Bileşenindeki bir olay işleyicisinin içinde yeniden yönlendirme yapmanız gerekiyorsa, useRouter kancasından push yöntemini kullanabilirsiniz. Örneğin:

app/page.tsx
'use client'
 
import { useRouter } from 'next/navigation'
 
export default function Page() {
  const router = useRouter()
 
  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}

Bildiğim iyi oldu:

  • Bir kullanıcıyı programlı olarak yönlendirmeniz gerekmiyorsa, bir <Link> bileşen

Daha fazla bilgi için useRouter API referansına bakın.

redirects in next.config.js

next.config.js dosyasındaki redirects seçeneği, gelen bir istek yolunu farklı bir hedef yola yönlendirmenize olanak tanır. Bu, sayfaların URL yapısını değiştirdiğinizde veya önceden bilinen bir yönlendirme listesine sahip olduğunuzda kullanışlıdır.

redirects yol, başlık, çerez ve sorgu eşleştirmeyi destekleyerek kullanıcıları gelen bir talebe göre yeniden yönlendirme esnekliği sağlar.

redirects adresini kullanmak için next.config.js dosyanıza bu seçeneği ekleyin:

next.config.js
module.exports = {
  async redirects() {
    return [
      // Basic redirect
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
      // Wildcard path matching
      {
        source: '/blog/:slug',
        destination: '/news/:slug',
        permanent: true,
      },
    ]
  },
}

Daha fazla bilgi için redirects API referansına bakın.

Bildiğim iyi oldu:

  • redirects permanent seçeneği ile 307 (Geçici Yönlendirme) veya 308 (Kalıcı Yönlendirme) durum kodu döndürebilir.
  • redirects platformlarda bir sınıra sahip olabilir. Örneğin, Vercel'de 1.024 yönlendirme sınırı vardır. Çok sayıda yönlendirmeyi (1000+) yönetmek için Middleware kullanarak özel bir çözüm oluşturmayı düşünün. Daha fazla bilgi için Yönlendirmeleri uygun ölçekte yönetme bölümüne bakın.
  • redirects Middleware'den önce çalışır.

NextResponse.redirect in Middleware

Ara yazılım, bir istek tamamlanmadan önce kod çalıştırmanıza olanak tanır. Ardından, gelen isteğe bağlı olarak, NextResponse.redirect adresini kullanarak farklı bir URL'ye yönlendirin. Bu, kullanıcıları bir koşula göre (örn. kimlik doğrulama, oturum yönetimi vb.) yeniden yönlendirmek istiyorsanız veya çok sayıda yönlendirmeniz varsa kullanışlıdır.

Örneğin, kimlik doğrulaması yapılmamışsa kullanıcıyı bir /login sayfasına yönlendirmek için:

middleware.ts
import { NextResponse, NextRequest } from 'next/server'
import { authenticate } from 'auth-provider'
 
export function middleware(request: NextRequest) {
  const isAuthenticated = authenticate(request)
 
  // If the user is authenticated, continue as normal
  if (isAuthenticated) {
    return NextResponse.next()
  }
 
  // Redirect to login page if not authenticated
  return NextResponse.redirect(new URL('/login', request.url))
}
 
export const config = {
  matcher: '/dashboard/:path*',
}

Bildiğim iyi oldu:

  • Ara yazılım redirects adresinden sonra next.config.js adresinde ve render işleminden önce çalışır.

Daha fazla bilgi için Orta Yazılım belgelerine bakın.

Managing redirects at scale (Advanced)

Çok sayıda yönlendirmeyi (1000+) yönetmek için Middleware kullanarak özel bir çözüm oluşturmayı düşünebilirsiniz. Bu, uygulamanızı yeniden dağıtmak zorunda kalmadan yönlendirmeleri programlı olarak ele almanızı sağlar.

Çok sayıda yönlendirmeyi ele alırken şunları göz önünde bulundurmalısınız:

  1. Yönlendirme haritası oluşturma ve saklama.
  2. Veri arama performansını optimize etme.

1. Creating and storing a redirect map

Yönlendirme haritası, bir veritabanında (genellikle bir anahtar-değer deposu) veya JSON dosyasında saklayabileceğiniz bir yönlendirme listesidir.

Aşağıdaki veri yapısını göz önünde bulundurun:

{
  "/old": {
    "destination": "/new",
    "permanent": true
  },
  "/blog/post-old": {
    "destination": "/blog/post-new",
    "permanent": true
  }
}

Middleware'de, Vercel's Edge Config veya Redis gibi bir veritabanından okuyabilir ve gelen isteğe göre kullanıcıyı yeniden yönlendirebilirsiniz:

middleware.ts
import { NextResponse, NextRequest } from 'next/server'
import { get } from '@vercel/edge-config'
 
type RedirectEntry = {
  destination: string
  permanent: boolean
}
 
export async function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname
  const redirectData = await get(pathname)
 
  if (redirectData && typeof redirectData === 'string') {
    const redirectEntry: RedirectEntry = JSON.parse(redirectData)
    const statusCode = redirectEntry.permanent ? 308 : 307
    return NextResponse.redirect(redirectEntry.destination, statusCode)
  }
 
  // No redirect found, continue without redirecting
  return NextResponse.next()
}

2. Optimizing data lookup performance

Gelen her istek için büyük bir veri kümesini okumak yavaş ve pahalı olabilir. Veri arama performansını optimize etmenin iki yolu vardır:

Önceki örneği göz önünde bulundurarak, oluşturulan bir bloom filtresi dosyasını Middleware'e aktarabilir, ardından gelen istek yol adının bloom filtresinde bulunup bulunmadığını kontrol edebilirsiniz.

Eğer varsa, isteği gerçek dosyayı kontrol edecek ve kullanıcıyı uygun URL'ye yönlendirecek bir Rota İşleyicisine iletin. Bu, gelen her isteği yavaşlatabilecek büyük bir yönlendirme dosyasının Middleware'e aktarılmasını önler.

middleware.ts
import { NextResponse, NextRequest } from 'next/server'
import { ScalableBloomFilter } from 'bloom-filters'
import GeneratedBloomFilter from './redirects/bloom-filter.json'
 
type RedirectEntry = {
  destination: string
  permanent: boolean
}
 
// Initialize bloom filter from a generated JSON file
const bloomFilter = ScalableBloomFilter.fromJSON(GeneratedBloomFilter as any)
 
export async function middleware(request: NextRequest) {
  // Get the path for the incoming request
  const pathname = request.nextUrl.pathname
 
  // Check if the path is in the bloom filter
  if (bloomFilter.has(pathname)) {
    // Forward the pathname to the Route Handler
    const api = new URL(
      `/api/redirects?pathname=${encodeURIComponent(request.nextUrl.pathname)}`,
      request.nextUrl.origin
    )
 
    try {
      // Fetch redirect data from the Route Handler
      const redirectData = await fetch(api)
 
      if (redirectData.ok) {
        const redirectEntry: RedirectEntry | undefined =
          await redirectData.json()
 
        if (redirectEntry) {
          // Determine the status code
          const statusCode = redirectEntry.permanent ? 308 : 307
 
          // Redirect to the destination
          return NextResponse.redirect(redirectEntry.destination, statusCode)
        }
      }
    } catch (error) {
      console.error(error)
    }
  }
 
  // No redirect found, continue the request without redirecting
  return NextResponse.next()
}

Ardından, Rota İşleyicide:

app/redirects/route.ts
import { NextRequest, NextResponse } from 'next/server'
import redirects from '@/app/redirects/redirects.json'
 
type RedirectEntry = {
  destination: string
  permanent: boolean
}
 
export function GET(request: NextRequest) {
  const pathname = request.nextUrl.searchParams.get('pathname')
  if (!pathname) {
    return new Response('Bad Request', { status: 400 })
  }
 
  // Get the redirect entry from the redirects.json file
  const redirect = (redirects as Record<string, RedirectEntry>)[pathname]
 
  // Account for bloom filter false positives
  if (!redirect) {
    return new Response('No redirect', { status: 400 })
  }
 
  // Return the redirect entry
  return NextResponse.json(redirect)
}

Bilmekte fayda var:

  • Bir bloom filtresi oluşturmak için aşağıdaki gibi bir kütüphane kullanabilirsiniz bloom-filters .
  • Kötü niyetli istekleri önlemek için Rota İşleyicinize yapılan istekleri doğrulamalısınız.