Files
gil-wiki/wiki/nuxt-routing.md
gil 5f664546cf feat: 위키 저장소 초기 커밋
- CLAUDE.md 운영 규칙
- wiki/ 정리된 지식 페이지 (Nuxt + Claude Code)
- raw/ 원본 자료
- reference/ Nuxt 4.x 공식 문서

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 00:31:51 +09:00

4.6 KiB

Nuxt 라우팅

카테고리: 핵심 개념 최종 수정: 2026-05-13 관련: nuxt-lifecycle, nuxt-rendering-modes

요약

Nuxt는 app/pages/ 디렉토리의 파일 구조를 기반으로 vue-router 라우트를 자동 생성한다. 동적 라우트, 중첩 라우트, 미들웨어를 파일 네이밍 컨벤션만으로 설정한다.


파일 기반 라우팅

pages/
├── index.vue          → /
├── about.vue          → /about
└── posts/
    ├── index.vue      → /posts
    └── [id].vue       → /posts/:id

💡 경험: pages/ 디렉토리가 없으면 Nuxt는 vue-router를 포함하지 않음 (app.vue 단독 사용 가능).


라우트 파일 네이밍 패턴

파일명 라우트 설명
pages/index.vue / 루트
pages/about.vue /about 정적 라우트
pages/posts/[id].vue /posts/:id 동적 파라미터
pages/[...slug].vue /* Catch-all
pages/[[optional]].vue / 또는 /:optional 선택적 파라미터
pages/user-[group]/[id].vue /user-:group/:id 복합 동적

중첩 라우트

pages/
└── parent/
    ├── index.vue      → /parent
    └── child.vue      → /parent/child

부모 레이아웃이 있다면 <NuxtPage />로 자식 라우트를 렌더링.


네비게이션

뷰포트에 들어오면 자동으로 다음 페이지 컴포넌트와 payload를 프리패치. 전체 페이지 새로고침 없이 클라이언트 사이드 라우팅.

<template>
  <nav>
    <NuxtLink to="/"></NuxtLink>
    <NuxtLink to="/about">소개</NuxtLink>
    <NuxtLink :to="{ name: 'posts-id', params: { id: 1 } }">포스트 1</NuxtLink>
  </nav>
</template>

navigateTo() — 프로그래매틱 이동

// 미들웨어나 이벤트 핸들러에서
await navigateTo('/login')
await navigateTo({ path: '/search', query: { q: 'nuxt' } })
await navigateTo('https://external.com', { external: true })

라우트 파라미터

<script setup lang="ts">
const route = useRoute()
// /posts/123 접근 시
console.log(route.params.id)  // '123'
console.log(route.query.page) // 쿼리스트링
console.log(route.fullPath)   // '/posts/123?page=1'
</script>

라우트 미들웨어

⚠️ 주의: 라우트 미들웨어는 Vue 앱의 클라이언트/서버 파트에서 실행됨. Nitro 서버의 server/middleware/와 다름. API 라우트(/api/*)에는 동작하지 않음.

종류 3가지

종류 위치 적용 범위
Global middleware/auth.global.ts 모든 라우트 변경
Named middleware/auth.ts 지정한 페이지만
Anonymous 페이지 컴포넌트 안 해당 페이지만

Named 미들웨어 예시

// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const user = useUser()
  if (!user.value) {
    return navigateTo('/login')
  }
})
<!-- pages/dashboard.vue -->
<script setup lang="ts">
definePageMeta({
  middleware: 'auth',       // 단일
  // middleware: ['auth', 'verified'],  // 복수
})
</script>

Anonymous(Inline) 미들웨어

<script setup lang="ts">
definePageMeta({
  middleware: defineNuxtRouteMiddleware((to, from) => {
    // 이 페이지 전용 로직
  }),
})
</script>

미들웨어에서 실행 흐름 제어

export default defineNuxtRouteMiddleware((to, from) => {
  // 계속 진행
  return

  // 다른 페이지로 리다이렉트
  return navigateTo('/login')

  // 현재 라우트 abort (404 표시)
  return abortNavigation()

  // 커스텀 에러
  return abortNavigation({ statusCode: 403, message: 'Forbidden' })
})

라우트 검증 (validate)

<script setup lang="ts">
definePageMeta({
  validate(route) {
    // id가 숫자인지 확인
    return /^\d+$/.test(route.params.id as string)
    // false → 404
    // { status: 403 } → 커스텀 에러
  },
})
</script>

definePageMeta 주요 옵션

definePageMeta({
  layout: 'dashboard',          // 레이아웃 지정
  middleware: ['auth'],         // 미들웨어
  validate: (route) => true,    // 라우트 검증
  keepalive: true,              // 컴포넌트 캐싱
  pageTransition: { name: 'slide', mode: 'out-in' },  // 페이지 트랜지션
  key: route => route.fullPath, // 컴포넌트 key 제어
})

참고 / 출처

  • reference/1.getting-started/07.routing.md
  • reference/2.directory-structure/1.app/1.middleware.md
  • reference/2.directory-structure/1.app/1.pages.md