ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Next.js - middleware 사용하기 (기본편)
    React.js & Next.js 2022. 9. 25. 21:37

    Advanced Features: Middleware | Next.js

     

    Advanced Features: Middleware | Next.js

    Learn how to use Middleware to run code before a request is completed.

    nextjs.org

    nested-middleware | Next.js

     

    nested-middleware | Next.js

    Nested Middleware You are defining a Middleware file in a location different from /middleware , which is not allowed. While in beta, a Middleware file under specific pages would only be executed when pages below its declaration were matched, allowing nesti

    nextjs.org

    미들웨어 사용 이유

    미들웨어를 사용하면 요청이 완료되기 전에 코드를 실행할 수 있으며, 수신 요청에 따라 다시 작성, 리디렉션, 헤더 추가 또는 쿠키 설정을 통해 응답을 수정할 수 있습니다.

     

    미들웨어는 캐시된 콘텐츠보다 먼저 실행되므로 정적 파일 및 페이지를 개인 설정할 수 있습니다. 미들웨어의 일반적인 예로는 인증, A/B 테스트, 현지화된 페이지, 봇 보호 등이 있습니다. 지역화된 페이지의 경우 i18n 라우팅부터 시작하여 보다 고급화된 사용 사례를 위해 미들웨어를 구현할 수 있습니다.

    미들웨어 위치

    next 12.2 버전 이후부터 미들웨어를 사용하기 위해서는 pages 폴더와 동일한 위치에 있어야 한다

    기본 사용법

    // middleware.ts
    import { NextResponse } from 'next/server'
    import type { NextRequest } from 'next/server'
    
    // This function can be marked `async` if using `await` inside
    export function middleware(request: NextRequest) {
      return NextResponse.redirect(new URL('/about-2', request.url))
    }
    
    // See "Matching Paths" below to learn more
    export const config = {
      matcher: '/about/:path*',
    }

    matcher

    matcher 프로퍼티는 하위 디렉토리의 특별한 경롤를 지정하기 위해 사용된다

    • matcher allows you to filter middleware to run on specific paths
    export const config = {
      matcher: '/about/:path*',
    }
    • 배열 문법으로도 정의가 가능하다
    export const config = {
      matcher: ['/about/:path*', '/dashboard/:path*'],
    }
    • 정규 표현식을 사용하여 정의가 가능하다
    export const config = {
      matcher: [
        /*
         * Match all request paths except for the ones starting with:
         * - api (API routes)
         * - static (static files)
         * - favicon.ico (favicon file)
         */
        '/((?!api|static|favicon.ico).*)',
      ],
    }

    Note: The matcher values need to be constants so they can be statically analyzed at build-time. Dynamic values such as variables will be ignored.

     

    matcher 값은 상수를 필요로 하기 때문에 빌드 타임에 정적으로 분석될 수 있습니다. 동적인 값들의 변수들은 무시될 것입니다.

     

    matcher는 다음과 같이 사용할 수 있습니다:

     

    1. / 로 시작해야 합니다
    2. /about/:path 의 경우 /about/a , /about/b 등에 대응하지만, /about/a/c 에는 대응하지 않습니다
    3. 하위 파라미터 까지 대응하기 위해서는 다음과 같은 구조로 사용해야 합니다
      • * is zero or more.
      • ? is zero or one
      • + one or more
    4. 정규 표현식에서의 /about/(.*)/about/:path* 다음 파라미터는 내용이 같습니다

    예시 코드 (경로에 따른 middleware 설정하기)

    import { NextRequest, NextResponse } from 'next/server'
    
    export function middleware(request: NextRequest) {
      if (request.nextUrl.pathname.startsWith('/test_middleware')) {
        console.log('call middle ware!')
    
        return NextResponse.redirect(new URL(`/fruits`, request.url))
      }
    }
    
    export const config = {
      matcher: '/test_middleware/:path*',
    }

    시나리오

    • /test_middleware 라는 경로의 요청이 들어오면 요청된 url 을 /fruits 라는 경로로 리다이렉트한다

    redirect vs rewrite

    redirect의 경우 path 값을 변경시키며 해당 경로로 이동합니다

    • /test_middleware - /fruits
    import { NextRequest, NextResponse } from 'next/server'
    
    export function middleware(request: NextRequest) {
      if (request.nextUrl.pathname.startsWith('/test_middleware')) {
        console.log('call middle ware!')
    
        return NextResponse.redirect(new URL(`/fruits`, request.url))
      }
    }
    
    export const config = {
      matcher: '/test_middleware/:path*',
    }

    rewrite의 경우 path 값은 유지한채 해당 데이터를 보여줍니다

    • /test_middleware - /test_middleware (내부 컴포넌트는 fruits)
    import { NextRequest, NextResponse } from 'next/server'
    
    export function middleware(request: NextRequest) {
      if (request.nextUrl.pathname.startsWith('/test_middleware')) {
        console.log('call middle ware!')
    
        return NextResponse.rewrite(new URL(`/fruits`, request.url))
      }
    }
    
    export const config = {
      matcher: '/test_middleware/:path*',
    }

    댓글

Designed by Tistory.