본문 바로가기
FrontEnd

next.js 에서 _middleware.ts의 역할과 최근 활용 예시

by 수비두비 2022. 5. 22.

프로젝트를 진행하면서 특정 페이지에 접근을 했을 때, 예를들어 로그인을 하지 않았을 때 리다이렉트를 해야하는 경우 next.js 에서는 _app.tsx 파일에서 useEffect를 통해서 토큰과 pathname을 기준으로 리다이렉트를 시키곤 했다. 이때 문제는 접근 안 되는 페이지에 url을 입력했을 때 해당 페이지가 잠깐 노출이 되고 리다이렉트를 시키는 문제가 있었는데, _middleware에 설정을 하면 페이지 전환 없이 바로 원하는 페이지로 리다이렉트를 할 수 있었다. (쿠키에는 접근이 가능한데 localStorage에는 접근이 안 되서 헤멘적이 있다)

middleware API 란?

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

사용 예시

  • Authentication
  • Bot protection
  • Redirects and rewrites
  • Handling unsupported browsers
  • Feature flags and A/B tests
  • Advanced i18n routing requirements

_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 테스트에 관심이 있어서 언젠가 도입하고 싶다.

참고 사이트

next.js document

'FrontEnd' 카테고리의 다른 글

[Typescript] satisfies  (0) 2024.11.20
[TypeScript] keyof/typeof 팁  (0) 2024.02.21
[css] 아래에서 위로 올라오는 애니메이션(?)  (0) 2022.08.23
브라우저 렌더링  (0) 2022.07.23
[Tip] next.js에서 i18n 을 세팅해보자  (0) 2022.05.30

댓글