프로젝트를 진행하면서 특정 페이지에 접근을 했을 때, 예를들어 로그인을 하지 않았을 때 리다이렉트를 해야하는 경우 next.js 에서는 _app.tsx
파일에서 useEffect
를 통해서 토큰과 pathname을 기준으로 리다이렉트를 시키곤 했다. 이때 문제는 접근 안 되는 페이지에 url을 입력했을 때 해당 페이지가 잠깐 노출이 되고 리다이렉트를 시키는 문제가 있었는데, _middleware
에 설정을 하면 페이지 전환 없이 바로 원하는 페이지로 리다이렉트를 할 수 있었다. (쿠키에는 접근이 가능한데 localStorage에는 접근이 안 되서 헤멘적이 있다)
request를 기반으로 response를 조작하고 구성하는 방법을 더 잘 제어할 수 있게 제공 되는 API
쉽게 말해 특정 url 에 접근 했을 때 관련된 requset를 기반으로 response를 조절할 수 있다.
/page/_middleware.ts 라면 모든 페이지
/pages/about/_middleware.ts 라면 about 페이지
requset(NextRequset)는 cookies
, nextUrl
등을 가지고 있다.
import type { NextFetchEvent } from 'next/server'
import type { NextRequest } from 'next/server'
export type Middleware = (
request: NextRequest,
event: NextFetchEvent
) => Promise<Response | undefined> | Response | undefined
_app.tsx 에서 리다이렉트 시킬 때 예시
// pages/\_app.tsx
const confirmedUrl = ['/', '/signin', '/signup']
React.useEffect(() => {
if (!confirmedUrl.includes(router.pathname)) {
router.push('/download')
}
}, [router.pathname])
_middleware.ts 에서 리다이렉트 시킬 떄 예시
// pages/\_middleware.ts
import type { NextFetchEvent, NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
export function middleware(req: NextRequest, ev: NextFetchEvent) {
const { pathname } = req.nextUrl
const confirmedUrl = ['/', '/login', '/signin']
if (!confirmedUrl.includes(pathname)) {
const url = req.nextUrl.clone()
url.pathname = '/download'
return NextResponse.redirect(`${url}`)
}
}
auth 에 따른 관리도 편하고 useEffect로 관리하는 거보다 안정적인 거 같아서 마음에 든다.
A/B 테스트에 관심이 있어서 언젠가 도입하고 싶다.