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, yeniden yazarak, yeniden yönlendirerek, istek veya yanıt başlıklarını değiştirerek veya doğrudan yanıt vererek yanıtı değiştirebilirsiniz.
Ara yazılım, önbelleğe alınan içerik ve yollar eşleştirilmeden önce çalışır. Daha fazla ayrıntı için Yolları Eşleştirme bölümüne bakın.
Convention
Orta Yazılımı tanımlamak için projenizin kök dizinindeki middleware.ts (veya .js) dosyasını kullanın. Örneğin, pages veya app ile aynı seviyede veya varsa src içinde.
Example
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url))
}
// See "Matching Paths" below to learn more
export const config = {
matcher: '/about/:path*',
}Matching Paths
Ara yazılım, projenizdeki her rota için çağrılacaktır. Yürütme sırası aşağıdaki gibidir:
headersitibarennext.config.jsredirectsitibarennext.config.js- Ara yazılım (
rewrites,redirects, vb.) beforeFiles(rewrites) adresindennext.config.js- Dosya sistemi rotaları (
public/,_next/static/,pages/,app/, vb.) afterFiles(rewrites) adresindennext.config.js- Dinamik Rotalar (
/blog/[slug]) fallback(rewrites) adresindennext.config.js
Middleware'in hangi yollarda çalışacağını tanımlamanın iki yolu vardır:
Matcher
matcher Orta Yazılımı belirli yollarda çalışacak şekilde filtrelemenizi sağlar.
export const config = {
matcher: '/about/:path*',
}Bir dizi sözdizimiyle tek bir yolu veya birden fazla yolu eşleştirebilirsiniz:
export const config = {
matcher: ['/about/:path*', '/dashboard/:path*'],
}matcher yapılandırması tam regex'e izin verir, böylece negatif lookahead'ler veya karakter eşleştirme gibi eşleştirme desteklenir. Belirli yollar hariç tümünü eşleştirmek için negatif lookahead örneği burada görülebilir:
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
}Ayrıca missing dizisini kullanarak Orta Katmandan geçmesi gerekmeyen prefetch'leri ( next/link adresinden) yok sayabilirsiniz:
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
{
source: '/((?!api|_next/static|_next/image|favicon.ico).*)',
missing: [
{ type: 'header', key: 'next-router-prefetch' },
{ type: 'header', key: 'purpose', value: 'prefetch' },
],
},
],
}Bilmekte fayda var:
matcherdeğerlerinin sabit olması gerekir, böylece derleme zamanında statik olarak analiz edilebilirler. Değişkenler gibi dinamik değerler göz ardı edilecektir.
Yapılandırılmış eşleştiriciler:
- ile başlamalıdır
/ - Adlandırılmış parametreler içerebilir:
/about/:path,/about/ave/about/bile eşleşir ancak/about/a/c - Adlandırılmış parametreler üzerinde değiştiriciler olabilir (
:ile başlayarak):/about/:path*,/about/a/b/cile eşleşir çünkü*sıfır veya daha fazladır.?sıfır veya bir ve+bir veya daha fazladır - Parantez içine alınmış düzenli ifade kullanabilir:
/about/(.*)ile aynıdır/about/:path*
Path-to-regexp belgeleri hakkında daha fazla bilgi edinin.
Bilmekte fayda var: Geriye dönük uyumluluk için Next.js,
/publicadresini her zaman/public/indexolarak kabul eder. Bu nedenle,/public/:patheşleştiricisi eşleşecektir.
Conditional Statements
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/about')) {
return NextResponse.rewrite(new URL('/about-2', request.url))
}
if (request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.rewrite(new URL('/dashboard/user', request.url))
}
}NextResponse
NextResponse API şunları yapmanızı sağlar:
redirectgelen isteği farklı bir URL'ye yönlendirirrewritebelirli bir URL'yi görüntüleyerek yanıt- API Rotaları,
getServerSidePropsverewritehedefleri için istek üstbilgilerini ayarlama - Yanıt çerezlerini ayarlama
- Yanıt başlıklarını ayarlama
Middleware'den bir yanıt üretmek için şunları yapabilirsiniz:
rewriteyanıt üreten bir rotaya(Sayfa veya Edge API Rotası)- doğrudan bir
NextResponsedöndürür. Yanıt Üretme bölümüne bakın
Using Cookies
Çerezler normal başlıklardır. Bir Request adresinde Cookie başlığında saklanırlar. Bir Response adresinde Set-Cookie başlığında bulunurlar. Next.js, NextRequest ve NextResponse üzerindeki cookies uzantısı aracılığıyla bu çerezlere erişmek ve bunları değiştirmek için uygun bir yol sağlar.
- Gelen istekler için
cookiesaşağıdaki yöntemlerle birlikte gelir:get,getAll,setvedeleteçerezleri.hasile bir çerezin varlığını kontrol edebilir veyaclearile tüm çerezleri kaldırabilirsiniz. - Giden yanıtlar için
cookiesaşağıdaki yöntemlere sahiptir:get,getAll,set, vedelete.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Assume a "Cookie:nextjs=fast" header to be present on the incoming request
// Getting cookies from the request using the `RequestCookies` API
let cookie = request.cookies.get('nextjs')
console.log(cookie) // => { name: 'nextjs', value: 'fast', Path: '/' }
const allCookies = request.cookies.getAll()
console.log(allCookies) // => [{ name: 'nextjs', value: 'fast' }]
request.cookies.has('nextjs') // => true
request.cookies.delete('nextjs')
request.cookies.has('nextjs') // => false
// Setting cookies on the response using the `ResponseCookies` API
const response = NextResponse.next()
response.cookies.set('vercel', 'fast')
response.cookies.set({
name: 'vercel',
value: 'fast',
path: '/',
})
cookie = response.cookies.get('vercel')
console.log(cookie) // => { name: 'vercel', value: 'fast', Path: '/' }
// The outgoing response will have a `Set-Cookie:vercel=fast;path=/` header.
return response
}Setting Headers
NextResponse API'sini kullanarak istek ve yanıt başlıklarını ayarlayabilirsiniz ( istek başlıklarının ayarlanması Next.js v13.0.0'dan beri mevcuttur).
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Clone the request headers and set a new header `x-hello-from-middleware1`
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-hello-from-middleware1', 'hello')
// You can also set request headers in NextResponse.rewrite
const response = NextResponse.next({
request: {
// New request headers
headers: requestHeaders,
},
})
// Set a new response header `x-hello-from-middleware2`
response.headers.set('x-hello-from-middleware2', 'hello')
return response
}Bilmekte fayda var: Arka uç web sunucusu yapılandırmanıza bağlı olarak 431 Request Header Fields Too Large hatasına neden olabileceğinden büyük başlıklar ayarlamaktan kaçının.
Producing a Response
Middleware'den doğrudan bir Response veya NextResponse örneği döndürerek yanıt verebilirsiniz. (Bu Next.js v13.1.0'dan beri mevcuttur )
import { NextRequest } from 'next/server'
import { isAuthenticated } from '@lib/auth'
// Limit the middleware to paths starting with `/api/`
export const config = {
matcher: '/api/:function*',
}
export function middleware(request: NextRequest) {
// Call our authentication function to check the request
if (!isAuthenticated(request)) {
// Respond with JSON indicating an error message
return Response.json(
{ success: false, message: 'authentication failed' },
{ status: 401 }
)
}
}waitUntil and NextFetchEvent
NextFetchEvent nesnesi, yerel FetchEvent nesnesini içerir ve waitUntil() yöntem.
waitUntil() yöntemi argüman olarak bir söz alır ve söz yerine gelene kadar Orta Yazılımın ömrünü uzatır. Bu, arka planda iş yapmak için kullanışlıdır.
import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextRequest } from 'next/server'
export function middleware(req: NextRequest, event: NextFetchEvent) {
event.waitUntil(
fetch('https://my-analytics-platform.com', {
method: 'POST',
body: JSON.stringify({ pathname: req.nextUrl.pathname }),
})
)
return NextResponse.next()
}Advanced Middleware Flags
Next.js'nin v13.1 adresinde, gelişmiş kullanım durumlarını ele almak için ara yazılım, skipMiddlewareUrlNormalize ve skipTrailingSlashRedirect için iki ek bayrak tanıtıldı.
skipTrailingSlashRedirect sondaki eğik çizgileri eklemek veya kaldırmak için Next.js yönlendirmelerini devre dışı bırakır. Bu, bazı yollar için sondaki eğik çizgiyi korumak için ara yazılım içinde özel işleme izin verir, ancak diğerleri için değil, bu da artımlı geçişleri kolaylaştırabilir.
module.exports = {
skipTrailingSlashRedirect: true,
}const legacyPrefixes = ['/docs', '/blog']
export default async function middleware(req) {
const { pathname } = req.nextUrl
if (legacyPrefixes.some((prefix) => pathname.startsWith(prefix))) {
return NextResponse.next()
}
// apply trailing slash handling
if (
!pathname.endsWith('/') &&
!pathname.match(/((?!\.well-known(?:\/.*)?)(?:[^/]+\/)*[^/]+\.\w+)/)
) {
req.nextUrl.pathname += '/'
return NextResponse.redirect(req.nextUrl)
}
}skipMiddlewareUrlNormalize Next.js'nin doğrudan ziyaretleri ve istemci geçişlerini aynı şekilde ele almak için yaptığı URL normalleştirmesini devre dışı bırakmaya izin verir. Bunun kilidini açtığı orijinal URL'yi kullanarak tam kontrole ihtiyaç duyduğunuz bazı gelişmiş durumlar vardır.
module.exports = {
skipMiddlewareUrlNormalize: true,
}export default async function middleware(req) {
const { pathname } = req.nextUrl
// GET /_next/data/build-id/hello.json
console.log(pathname)
// with the flag this now /_next/data/build-id/hello.json
// without the flag this would be normalized to /hello
}Runtime
Middleware şu anda yalnızca Edge çalışma zamanını desteklemektedir. Node.js çalışma zamanı kullanılamaz.
Version History
| Version | Changes |
|---|---|
v13.1.0 | Advanced Middleware flags added |
v13.0.0 | Middleware can modify request headers, response headers, and send responses |
v12.2.0 | Middleware is stable, please see the upgrade guide |
v12.0.9 | Enforce absolute URLs in Edge Runtime (PR) |
v12.0.0 | Middleware (Beta) added |