미들웨어를 사용하면 요청이 완료되기 전에 코드를 실행할 수 있으며, 들어오는 요청을 기반으로 응답을 수정하여 다시 작성, 리디렉션, 요청 또는 응답 헤더 수정 또는 직접 응답하는 것이 가능합니다.
미들웨어는 캐시된 콘텐츠보다 먼저 실행되므로 정적 파일 및 페이지를 개인화할 수 있습니다. 미들웨어의 일반적인 예는 인증, A/B 테스트, 로컬화된 페이지, 봇 보호 등이 있습니다. 로컬화된 페이지의 경우 i18n
라우팅으로 시작하여 더 고급 사용 사례에 미들웨어를 구현할 수 있습니다.
참고:
12.2
이전에 미들웨어를 사용하고 있었다면 업그레이드 가이드를 참조하세요.
미들웨어를 사용하려면 다음 단계를 따르세요:
npm install next@latest
src
디렉터리에)에서 middleware.ts
(또는 .js
) 파일을 만듭니다.middleware.ts
파일에서 미들웨어 함수를 내보냅니다:// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// 이 함수는 `await`을 사용하는 경우 `async`로 표시될 수 있습니다.
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL('/about-2', request.url))
}
// 자세한 내용은 아래의 "경로 일치"를 참조하세요.
export const config = {
matcher: '/about/:path*',
}
미들웨어는 프로젝트의 모든 라우트에서 호출됩니다. 다음은 실행 순서입니다.
next.config.js
에서 headers
next.config.js
에서 redirects
next.config.js
에서 beforeFiles
(rewrite)public/
, _next/static/
, Pages
등)next.config.js
에서 afterFiles
(rewrite)/blog/[slug]
)next.config.js
에서 fallback
(rewrite)미들웨어가 실행되는 경로를 정의하는 방법은 두 가지가 있습니다.
matcher config
Matcher
를 사용하면 특정 경로에서 Middleware
가 실행되도록 필터링할 수 있습니다.
export const config = {
matcher: '/about/:path*',
}
하나의 경로 또는 배열 구문으로 여러 경로를 일치시킬 수 있습니다.
export const config = {
matcher: ['/about/:path*', '/dashboard/:path*'],
}
matcher
구성에는 부정적인 룩어헤드 또는 문자 일치와 같은 일치를 위한 완전한 정규식을 사용할 수 있습니다. 특정 경로를 제외한 모든 경로를 일치시키기 위한 부정적인 룩어헤드의 예는 다음과 같습니다.
export const config = {
matcher: [
/*
* api (API 라우트)
* _next/static (정적 파일)
* _next/image (이미지 최적화 파일)
* favicon.ico (파비콘 파일)
* 로 시작하지 않는 모든 요청 경로와 일치합니다.
*/
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
}
참고:
Matcher
값은 빌드 시간에 정적으로 분석할 수 있도록 상수여야 합니다. 변수와 같은 동적 값은 무시됩니다.
/
로 시작해야 합니다./about/:path
는 /about/a
와 /about/b
와 일치하지만 /about/a/c
와는 일치하지 않습니다./about/:path*
는 *
이 0
개 이상이므로 /about/a/b/c
와 일치합니다. ?
는 0
개 또는 1
개를 의미하며 +
는 1
개 이상을 의미합니다./about/(.)
은 /about/:path
와 동일합니다.참고: 하위 호환성을 위해
Next.js
는 항상/public
을/public/index
로 간주합니다. 따라서/public/:path
와 같은matcher
는 일치합니다.
// middleware.ts
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 API
를 사용하면 다음을 수행할 수 있습니다:
getServerSideProps
및 리다이렉트 대상을 위해 요청 헤더를 설정합니다.Middleware
에서 응답을 생성하려면 다음을 수행할 수 있습니다:
Page
또는 Edge API Route
)로 다시 작성합니다.NextResponse
를 직접 반환합니다. 응답 생성 참조쿠키는 일반적인 헤더입니다. 요청에서는 쿠키가 Cookie
헤더에 저장됩니다. 응답에서는 Set-Cookie
헤더에 저장됩니다. Next.js
는 NextRequest
및 NextResponse
의 쿠키 확장을 통해 이러한 쿠키에 액세스하고 조작하는 편리한 방법을 제공합니다.
cookies
는 다음과 같은 메서드를 가지고 있습니다: get
, getAll
, set
, delete
cookies. has
를 사용하여 쿠키의 존재 여부를 확인하거나 clear
를 사용하여 모든 쿠키를 제거할 수 있습니다.cookies
는 다음과 같은 메서드를 가지고 있습니다: get
, getAll
, set
, delete
.// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// "Cookie:nextjs=fast" 헤더가 들어오는 요청에 있을 것으로 가정합니다
// RequestCookies API를 사용하여 요청에서 쿠키 가져오기
let cookie = request.cookies.get('nextjs')?.value
console.log(cookie) // => 'fast'
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
// ResponseCookies API를 사용하여 응답에 쿠키 설정하기
const response = NextResponse.next()
response.cookies.set('vercel', 'fast')
response.cookies.set({
name: 'vercel',
value: 'fast',
path: '/test',
})
cookie = response.cookies.get('vercel')
console.log(cookie) // => { name: 'vercel', value: 'fast', Path: '/test' }
// 나가는 응답은 `Set-Cookie:vercel=fast;path=/test` 헤더를 가질 것입니다.
return response
}
NextResponse API
를 사용하여 요청 및 응답 헤더를 설정할 수 있습니다. (요청 헤더 설정은 Next.js v13.0.0
이후 사용 가능합니다).
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// 요청 헤더를 복제하고 새로운 헤더 'x-hello-from-middleware1'를 설정합니다.
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-hello-from-middleware1', 'hello')
// NextResponse.rewrite에서도 요청 헤더를 설정할 수 있습니다.
const response = NextResponse.next({
request: {
// 새로운 요청 헤더
headers: requestHeaders,
},
})
// 새로운 응답 헤더 'x-hello-from-middleware2'를 설정합니다.
response.headers.set('x-hello-from-middleware2', 'hello')
return response
}
참고: 백엔드 웹 서버 구성에 따라
431 Request Header Fields Too Large
오류가 발생할 수 있으므로 큰 헤더 설정은 피하십시오.
Middleware
에서 NextResponse
를 반환하여 직접 응답할 수 있습니다. (Middleware
에서 응답하는 것은 Next.js v13.1.0
이후 사용 가능합니다).
활성화된 경우 Response
또는 NextResponse API
를 사용하여 미들웨어에서 응답을 제공할 수 있습니다:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
import { isAuthenticated } from '@lib/auth'
// /api/로 시작하는 경로에서만 미들웨어 제한
export const config = {
matcher: '/api/:function*',
}
export function middleware(request: NextRequest) {
// 요청을 확인하기 위해 인증 함수를 호출합니다.
if (!isAuthenticated(request)) {
// 오류 메시지를 나타내는 JSON으로 응답합니다.
return new NextResponse(
JSON.stringify({ success: false, message: 'authentication failed' }),
{ status: 401, headers: { 'content-type': 'application/json' } }
)
}
}
Next.js
의 버전 13.1
에서는 미들웨어에 대한 두 가지 추가 플래그인 skipMiddlewareUrlNormalize
와 skipTrailingSlashRedirect
가 소개되었습니다. 이 플래그는 고급 사용 사례를 처리할 수 있도록 도와줍니다.
skipTrailingSlashRedirect
는 URL의 마지막 슬래시 추가 또는 제거에 대한 Next.js의 기본 리다이렉트 기능을 끄고, 미들웨어 내에서 사용자 정의 처리를 할 수 있게 합니다. 이를 통해 일부 경로에서는 마지막 슬래시를 유지하면서 다른 경로에서는 제거할 수 있어서 점진적인 마이그레이션을 보다 쉽게 할 수 있습니다.
// next.config.js
module.exports = {
skipTrailingSlashRedirect: true,
}
// middleware.js
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
가 수행하는 URL 정규화를 비활성화하는 기능입니다. 원래 URL을 사용하여 전체 제어가 필요한 고급 경우에 유용합니다.
// next.config.js
module.exports = {
skipMiddlewareUrlNormalize: true,
}
// middleware.js
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
}
두 플래그는 일부 경우에는 매우 유용하지만, 고급 사용 사례이므로 필요에 따라 사용하도록 권장합니다.