[Next.js] 미들웨어(middleware)

hyeon·2025년 4월 18일

layout.tsx에 다음과 같은 로직을 구현되어 있었다.

  • 로그인 안한 경우, 로그인 페이지로 리다이렉트
  • 로그인한 경우, API를 호출해서 결과값으로 소속된 그룹에 따라 url 별도 처리

처음에는 이 로직을 layout.tsx가 아닌, middleware.ts로 옮기면 더 깔끔하지 않을까? 라는 생각이 들었다.


middleware는 페이지 진입 전에 실행되고, 라우팅도 서버 측에서 바로 처리할 수 있기 때문이다.

하지만 막상 옮기려다 보니,

  • 비동기 API 호출 지양
  • CSR에서 middleware가 스킵되는 문제
  • UX 리디렉션 방식의 한계 등

생각보다 고려해야 할 점이 많다는 걸 깨달았다.

이 글은 그런 시행착오를 겪으며 직접 정리한

Next.js middleware.ts를 사용할 때 꼭 알아둬야 할 실전 주의사항들에 대한 내용이다.




Next.js middleware.ts 사용할 때 주의해야 할 점


1. 비동기 fetch/DB 호출 지양

  • middleware는 Edge Runtime에서 실행됨 (서버가 아님)
  • 외부 API 호출 (fetch, DB 쿼리 등)는 지양
  • 느리거나 실패할 수 있음. cold start, 속도 저하 문제 발생
  • 대신 req.cookies, req.nextUrl.pathname, 헤더 등 요청 메타데이터 기반 로직만 쓰는 걸 권장

📌 예외: Supabase.getUser()처럼 내부 쿠키 파싱 기반이면 OK


2. 정확한 matcher 설정으로 성능 최적화

  • middleware는 매 요청마다 실행되기 때문에, 반드시 export const config = { matcher: [...] }로 적용 범위 제한
export const config = {
  matcher: ['/dashboard/:path*', '/admin/:path*'], // 필요한 경로만!
}
  • 정규식으로 너무 넓게 적용하면 static 리소스까지 intercept할 수 있음 → 성능 저하

3. NextResponse.redirect()는 클라이언트 이동처럼 부드럽지 않음

  • router.push처럼 전환 애니메이션이 있는 게 아님
  • 그냥 브라우저 리디렉트처럼 팍 바뀌기 때문에, 사용자에게 약간 부자연스럽게 보일 수 있음

👉 UX적 전환이 중요하면 클라이언트 쪽에서 처리하는 것도 고려


4. 쿠키 읽을 때 도메인/Path 조건 주의

  • req.cookies.get('access_token')요청에 포함된 쿠키만 읽을 수 있음
  • HttpOnly, SameSite, Path 설정 잘못되면 middleware에서 접근 못 함

👉 특히 개발 중에는 localhost와 실제 배포 주소의 쿠키 동작 차이도 체크해야 함


5. 동작 흐름의 예측 가능성 중요

  • router.push()로 이동 시 CSR이면 middleware가 아예 실행 안 될 수도 있음 (이미 prefetch된 경우 → 서버 요청 없음)

해결책: router.refresh() 추가하거나, 중요한 보안 로직은 middleware 대신 서버에서 처리


6. 미들웨어에 너무 많은 로직 몰아넣지 않기

  • 가독성, 디버깅 모두 힘들어짐
  • 토큰 파싱, 경로 조건 분기 정도만 처리하고, 복잡한 로직은 layout.tsx, page.tsx, API route 등으로 분산

참고사항
Next.js 16부터는 proxy.ts가 middleware.ts를 대체합니다.

profile
당근🥕

0개의 댓글