middleware

Nuxt는 특정 경로로 이동하기 전에 코드를 실행하기 위한 미들웨어를 제공한다.

 

Nuxt 는 애플리케이션 전체에서 사용할 수 있는 사용자 정의 가능한 경로 미들웨어 프레임워크를 제공하며, 특정 경로로 네비게이션 되기 전에 실행된다.

 

경로 미들웨어에는 세 가지 종류가 있다.

 

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

처음 두 종류의 경로 미들웨어는 definePageMeta 에서 정의할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

미들웨어 이름은 kebab-case로 정규화된다. myMiddleware 는 my-middleware 가 된다.

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

 

사용법

경로 미들웨어는 현재 경로와 다음 경로를 인수로 받는 탐색 가드이다.

// middleware/my-middleware.ts

export default defineNuxtRouteMiddleware((to, from) => {
  if (to.params.id === '1') {
    return abortNavigation()
  }
  // In a real app you would probably not redirect every route to `/`
  // however it is important to check `to.path` before redirecting or you
  // might get an infinite redirect loop
  if (to.path !== '/') {
    return navigateTo('/')
  }
})

 

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

  1. navigateTo - 지정된 경로로 리디렉션
  2. abortNavigation - 선택적 오류 메시지와 함께 네비게이션을 중단한다.

vue-router 의 탐색 가드와 달리 세 번째 next() 인수는 전달되지 않으며 리디렉션 또는 경로 취소는 미들웨어에서 값을 반환하여 처리된다.

 

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

  • 아무 것도 없음(단순 return 또는 전혀 반환 없음) - 탐색을 차단하지 않고 다음 미들웨어 기능(있는 경우)으로 이동하거나 경로 탐색을 완료한다.
  • return navigateTo('/') - 지정된 경로로 리디렉션하고 서버 측에서 리디렉션이 발생하는 경우 리디렉션 302 Found 로 설정다.
  • return navigateTo('/', { redirectCode: 301 }) - 리디렉션이 서버 측에서 발생하는 경우 지정된 경로로 리디렉션하고 리디렉션 코드가 '301 Move Permanantly' 로 설정한다.
  • return abortNavigation() - 현재 탐색을 중지한다.
  • return abortNavigation(error) - 오류로 인해 현재 탐색을 거부한다.

참고) Nuxt-Utils > navigateTo, Nuxt-Utils > abortNavigation

 

리디렉션을 수행하거나 탐색을 중지하려면 위의 도우미 기능을 사용하는 것이 좋다. vue-router 문서
에 설명된 다른 가능한 반환 값이 작동할 수도 있지만 앞으로 상당한 변경이 있을 수 있다.

 

미들웨어 순서

미들웨어는 다음 순서로 실행다.

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

예를 들어 다음과 같은 미들웨어와 구성 요소가 있다고 가정하자.

# middleware 디렉토리

middleware/
--| analytics.global.ts
--| setup.global.ts
--| auth.ts
<!--
pages/profile.vue
-->

<script setup lang="ts">
definePageMeta({
  middleware: [
    function (to, from) {
      // Custom inline middleware
    },
    'auth',
  ],
});
</script>

 

미들웨어는 다음 순서로 실행될 것으로 예상할 수 있다.

  1. analytics.global.ts
  2. setup.global.ts
  3. 맞춤형 인라인 미들웨어
  4. auth.ts

 

글로벌 미들웨어 순서

기본적으로 전역 미들웨어는 파일 이름을 기준으로 알파벳순으로 실행된다.

 

그러나 특정 순서를 정의하고 싶을 수도 있다. 예를 들어, 마지막 시나리오에서는 setup.global.ts을 analytics.global.ts보다 먼저 실행해야 할 수도 있다. 이 경우 글로벌 미들웨어 앞에 번호 매기기 등의 '알파벳순'을 붙이는 것이 좋다.

# 디렉토리 구조

middleware/
--| 01.setup.global.ts
--| 02.analytics.global.ts
--| auth.ts
'알파벳순'을 처음 사용하는 경우 번호를 매길 때 파일 이름은 숫자 값이 아닌 문자열로 정렬된다는 점을 기억하자. 예를 들어, 10.new.global.ts 은 2.new.global.ts 앞에 온다. 이것이 바로 예제에서 한 자리 숫자 앞에 0 을 붙이는 이유다.

 

미들웨어가 실행될 때

사이트가 서버에서 렌더링되거나 생성된 경우 초기 페이지에 대한 미들웨어는 페이지가 서버에서 렌더링될 된 후 클라이언트에서 다시 렌더링된다. 이는 생성된 사이트가 있거나 적극적으로 응답을 캐시하거나 로컬 저장소에서 값을 읽으려는 경우와 같이 미들웨어에 브라우저 환경이 필요한 경우 필요할 수 있다.

 

그러나 이 동작을 피하려면 다음과 같이 할 수 있다.

// middleware/example.ts

export default defineNuxtRouteMiddleware(to => {
  // skip middleware on server
  if (process.server) return
  // skip middleware on client side entirely
  if (process.client) return
  // or only skip middleware on initial client load
  const nuxtApp = useNuxtApp()
  if (process.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
})

 

미들웨어를 동적으로 추가하기

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

export default defineNuxtPlugin(() => {
  addRouteMiddleware('global-test', () => {
    console.log('this global middleware was added in a plugin and will be run on every route change')
  }, { global: true })

  addRouteMiddleware('named-test', () => {
    console.log('this named middleware was added in a plugin and would override any existing middleware of the same name')
  })
})

 

사용 예

# 디렉토리 구조

-| middleware/
---| auth.ts

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

<script setup lang="ts">
definePageMeta({
  middleware: ["auth"]
  // or middleware: 'auth'
})
</script>

이제 해당 페이지 탐색이 완료되기 전에 auth 경로 미들웨어가 실행된다.

 

아래 예제에서는 middleware/ 디렉터리 또는 플러그인을 사용하여 경로 미들웨어를 추가하는 방법과 이를 전역적으로 또는 페이지별로 사용하는 방법을 보여준다.

<!--
app.vue
-->

<script setup lang="ts">
const nav = [
  { label: 'Home', to: '/' },
  { label: 'Forbidden', to: '/forbidden' },
  { label: 'Redirect', to: '/redirect' },
]

const route = useRoute()
</script>

<template>
  <NuxtExampleLayout dir="routing/middleware" :nav="nav">
    <NuxtPage />
    <template #footer>
      <div class="text-center p-4 op-50">
        Current route: <UKbd>{{ route.path }}</UKbd>
      </div>
    </template>
  </NuxtExampleLayout>
</template>

 

빌드 시 미들웨어 설정

각 페이지에서 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 ||= {}
            // Note that this will override any middleware set in `definePageMeta` in the page
            page.meta.middleware = ['named']
          }
          if (page.children) {
            setMiddleware(page.children)
          }
        }
      }
      setMiddleware(pages)
    }
  }
})

'Nuxt 공식문서 번역 > Directories' 카테고리의 다른 글

node_modules  (0) 2023.12.17
modules  (0) 2023.12.17
layouts  (0) 2023.12.17
content  (0) 2023.12.17
composables  (1) 2023.12.17
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유