nuxt logo

문서 번역(비공식)

미들웨어

Nuxt는 특정 경로로 이동하기 전에 코드를 실행할 수 있는 미들웨어를 제공합니다.

Nuxt는 애플리케이션 전반에서 사용할 수 있는 커스터마이즈 가능한 경로 미들웨어 프레임워크를 제공하며, 특정 경로로 이동하기 전에 실행하고자 하는 코드를 추출하는 데 이상적입니다.

경로 미들웨어에는 세 가지 종류가 있습니다:

  1. 익명(또는 인라인) 경로 미들웨어는 페이지 내에서 직접 정의됩니다.
  2. 명명된 경로 미들웨어는 middleware/에 배치되며, 페이지에서 사용될 때 비동기 임포트를 통해 자동으로 로드됩니다.
  3. 글로벌 경로 미들웨어는 middleware/.global 접미사를 붙여 배치되며, 모든 경로 변경 시 실행됩니다.

첫 번째와 두 번째 종류의 경로 미들웨어는 definePageMeta에서 정의할 수 있습니다.

미들웨어의 이름은 케밥 케이스로 정규화됩니다: myMiddlewaremy-middleware가 됩니다.

경로 미들웨어는 Nuxt 앱의 Vue 부분 내에서 실행됩니다. 비슷한 이름에도 불구하고, 이는 앱의 Nitro 서버 부분에서 실행되는 서버 미들웨어와는 완전히 다릅니다.

사용법

경로 미들웨어는 현재 경로와 다음 경로를 인수로 받는 네비게이션 가드입니다.

middleware/my-middleware.ts
export default defineNuxtRouteMiddleware((to, from) => {
  if (to.params.id === '1') {
    return abortNavigation()
  }
  // 실제 앱에서는 모든 경로를 `/`로 리디렉션하지 않겠지만,
  // 리디렉션하기 전에 `to.path`를 확인하는 것이 중요합니다.
  // 그렇지 않으면 무한 리디렉션 루프에 빠질 수 있습니다.
  if (to.path !== '/') {
    return navigateTo('/')
  }
})

Nuxt는 미들웨어에서 직접 반환할 수 있는 두 가지 전역적으로 사용 가능한 헬퍼를 제공합니다.

  1. navigateTo - 주어진 경로로 리디렉션합니다.
  2. abortNavigation - 선택적 오류 메시지와 함께 네비게이션을 중단합니다.

vue-router네비게이션 가드와 달리, 세 번째 next() 인수가 전달되지 않으며, 리디렉션 또는 경로 취소는 미들웨어에서 값을 반환함으로써 처리됩니다.

가능한 반환 값은 다음과 같습니다:

  • 아무것도 없음 (단순히 return 또는 반환 없음) - 네비게이션을 차단하지 않으며, 다음 미들웨어 함수로 이동하거나 경로 네비게이션을 완료합니다.
  • return navigateTo('/') - 주어진 경로로 리디렉션하며, 서버 측에서 리디렉션이 발생하면 리디렉션 코드를 302 Found로 설정합니다.
  • return navigateTo('/', { redirectCode: 301 }) - 주어진 경로로 리디렉션하며, 서버 측에서 리디렉션이 발생하면 리디렉션 코드를 301 Moved Permanently로 설정합니다.
  • return abortNavigation() - 현재 네비게이션을 중단합니다.
  • return abortNavigation(error) - 오류와 함께 현재 네비게이션을 거부합니다.
이것도 참고 api > utils > navigate-to 이것도 참고 api > utils > abort-navigation

리디렉션을 수행하거나 네비게이션을 중단하기 위해 위의 헬퍼 함수를 사용하는 것을 권장합니다. vue-router 문서에 설명된 다른 가능한 반환 값도 작동할 수 있지만, 향후에 파괴적인 변경이 있을 수 있습니다.

미들웨어 순서

미들웨어는 다음 순서로 실행됩니다:

  1. 글로벌 미들웨어
  2. 페이지에 정의된 미들웨어 순서 (배열 구문으로 여러 미들웨어가 선언된 경우)

예를 들어, 다음과 같은 미들웨어와 컴포넌트가 있다고 가정합니다:

middleware/ directory
-| middleware/
---| analytics.global.ts
---| setup.global.ts
---| auth.ts
pages/profile.vue
definePageMeta({
  middleware: [
    function (to, from) {
      // 사용자 정의 인라인 미들웨어
    },
    'auth',
  ],
});

다음 순서로 미들웨어가 실행될 것으로 예상할 수 있습니다:

  1. analytics.global.ts
  2. setup.global.ts
  3. 사용자 정의 인라인 미들웨어
  4. auth.ts

글로벌 미들웨어 순서 지정

기본적으로 글로벌 미들웨어는 파일 이름을 기준으로 알파벳 순서로 실행됩니다.

그러나 특정 순서를 정의하고 싶을 때가 있을 수 있습니다. 예를 들어, 마지막 시나리오에서 setup.global.tsanalytics.global.ts보다 먼저 실행되어야 할 수 있습니다. 이 경우, 글로벌 미들웨어에 '알파벳' 번호를 접두사로 붙이는 것을 권장합니다.

Directory structure
-| middleware/
---| 01.setup.global.ts
---| 02.analytics.global.ts
---| auth.ts

'알파벳' 번호가 처음이라면, 파일 이름은 숫자 값이 아닌 문자열로 정렬된다는 것을 기억하세요. 예를 들어, 10.new.global.ts2.new.global.ts보다 먼저 올 것입니다. 이것이 예제에서 한 자리 숫자에 0을 접두사로 붙이는 이유입니다.

미들웨어 실행 시점

사이트가 서버 렌더링되거나 생성된 경우, 초기 페이지에 대한 미들웨어는 페이지가 렌더링될 때와 클라이언트에서 다시 실행됩니다. 이는 미들웨어가 브라우저 환경을 필요로 할 때 필요할 수 있습니다. 예를 들어, 사이트가 생성되었거나, 응답을 적극적으로 캐시하거나, 로컬 스토리지에서 값을 읽고자 할 때입니다.

그러나 이 동작을 피하고 싶다면 다음과 같이 할 수 있습니다:

middleware/example.ts
export default defineNuxtRouteMiddleware(to => {
  // 서버에서 미들웨어 건너뛰기
  if (import.meta.server) return
  // 클라이언트 측에서 미들웨어 완전히 건너뛰기
  if (import.meta.client) return
  // 또는 초기 클라이언트 로드에서만 미들웨어 건너뛰기
  const nuxtApp = useNuxtApp()
  if (import.meta.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
})

이는 서버에서 미들웨어에서 오류를 발생시키고 오류 페이지가 렌더링되더라도 마찬가지입니다. 미들웨어는 브라우저에서 다시 실행됩니다.

오류 페이지를 렌더링하는 것은 완전히 별도의 페이지 로드로, 등록된 모든 미들웨어가 다시 실행됩니다. 미들웨어에서 useError를 사용하여 오류가 처리되고 있는지 확인할 수 있습니다.

동적으로 미들웨어 추가

addRouteMiddleware() 헬퍼 함수를 사용하여 플러그인 내에서 글로벌 또는 명명된 경로 미들웨어를 수동으로 추가할 수 있습니다.

export default defineNuxtPlugin(() => {
  addRouteMiddleware('global-test', () => {
    console.log('이 글로벌 미들웨어는 플러그인에서 추가되었으며 모든 경로 변경 시 실행됩니다.')
  }, { global: true })

  addRouteMiddleware('named-test', () => {
    console.log('이 명명된 미들웨어는 플러그인에서 추가되었으며 동일한 이름의 기존 미들웨어를 덮어씁니다.')
  })
})

예제

Directory Structure
-| middleware/
---| auth.ts

페이지 파일에서 이 경로 미들웨어를 참조할 수 있습니다:

definePageMeta({
  middleware: ["auth"]
  // 또는 middleware: 'auth'
})

이제 해당 페이지로의 네비게이션이 완료되기 전에 auth 경로 미들웨어가 실행됩니다.

샘플 코드 편집 및 미리보기examples > routing > middleware

빌드 시점에 미들웨어 설정

각 페이지에서 definePageMeta를 사용하는 대신, pages:extend 훅 내에서 명명된 경로 미들웨어를 추가할 수 있습니다.

nuxt.config.ts
import type { NuxtPage } from 'nuxt/schema'

export default defineNuxtConfig({
  hooks: {
    'pages:extend' (pages) {
      function setMiddleware (pages: NuxtPage[]) {
        for (const page of pages) {
          if (/* some condition */ true) {
            page.meta ||= {}
            // 이 작업은 페이지의 `definePageMeta`에서 설정된 모든 미들웨어를 덮어씁니다.
            page.meta.middleware = ['named']
          }
          if (page.children) {
            setMiddleware(page.children)
          }
        }
      }
      setMiddleware(pages)
    }
  }
})