I turn coffee into code ☕ → 💻 자세히보기

개발/Next.js

[Next.js] 미들웨어

xuwon 2025. 8. 7. 22:23
Next.js의 미들웨어

요청(request)이 처리되기 전에 실행되는 코드
사용자 요청을 조작하거나 조건에 따라 리다이렉트, 응답 수정 가능!

Next.js에서는 이 미들웨어가 엣지(Edge) 환경에서 실행되는 코드로 설계되어 있어
빠르고 서버리스(serverless)한 방식으로 동작한다고 한다.


실행 시점

- 모든 요청 전에 실행됨
- 정적 파일을 제외한 모든 페이지 요청에서 동작 가능
- API 라우트 요청에는 기본적으로 적용되지 않음

위치

- Next.js 프로젝트 루트 또는 app/ 디렉토리 내에 middleware.ts 파일을 만들면 자동 적용


기본 예시

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const token = request.cookies.get('token')?.value;

  // 로그인 되어 있지 않으면 로그인 페이지로 리디렉트
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // 정상적으로 통과
  return NextResponse.next();
}

 

주요 기능

리다이렉트 특정 조건에 따라 다른 페이지로 보냄 (NextResponse.redirect)
요청 차단 요청 자체를 막고 응답을 반환 (new Response(...))
리라이트(Rewrite) URL을 내부적으로 다른 경로로 바꿈
지역 기반 라우팅 헤더에서 위치를 파악해 맞는 페이지로 이동
쿠키 검사  쿠키를 읽어 인증 처리 등 가능 


리다이렉트 vs 리라이트

- 리다이렉트는 새로운 URL로 이동 / 리라이트는 원래 URL은 유지하나 내부적으로 다른 페이지 처리
- 리라이트는 클린 URL, 다국어 처리 등에 많이 쓰임


경로 제어 (matcher 옵션)

특정 경로에만 미들웨어를 적용하고 싶다면 matcher 설정이 가능하다.

export const config = {
  matcher: ['/dashboard/:path*', '/profile'],
}; // /dashboard 하위와 /profile 경로에만 미들웨어 적용


특정 경로를 제외하려면 정규식을 사용해서 걸러내야 함.

export const config = {
  matcher: [
    /*
     * - `/api`, `/static`, `/_next` 경로는 제외
     * - 그 외 모든 경로는 포함
     */
    '/((?!api|static|_next).*)',
  ],
};

쿠키 및 헤더 접근 예시

export function middleware(request: NextRequest) {
  const lang = request.headers.get('accept-language');
  const cookie = request.cookies.get('session');

  console.log(lang, cookie);

  return NextResponse.next();
}

리다이렉트 예시

export function middleware(request: NextRequest) {
  const isLoggedIn = Boolean(request.cookies.get('auth'));

  if (!isLoggedIn && request.nextUrl.pathname.startsWith('/admin')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

auth 쿠키가 없고 /admin으로 시작하는 경로가 아니면 로그인 페이지로 리다이렉트


리라이트 예시

export function middleware(request: NextRequest) {
  const url = request.nextUrl.clone();

  if (url.pathname === '/about') {
    url.pathname = '/about-us'; // 내부 경로 변경
    return NextResponse.rewrite(url);
  }

  return NextResponse.next();
}

주의할 점!

- 서버 측에서 실행됨
- 상태 관리 접근 불가 (React 상태, 훅 사용 불가능)
- 외부 라이브러리 제한 존재