- CLAUDE.md 운영 규칙 - wiki/ 정리된 지식 페이지 (Nuxt + Claude Code) - raw/ 원본 자료 - reference/ Nuxt 4.x 공식 문서 Co-authored-by: Cursor <cursoragent@cursor.com>
4.3 KiB
Nuxt 라이프사이클
카테고리: 핵심 개념 최종 수정: 2026-05-13 관련: nuxt-rendering-modes, nuxt-auto-imports, nuxt-data-fetching
요약
Nuxt 앱은 서버에서 시작해 클라이언트로 이어지는 두 단계 라이프사이클을 갖는다. 어느 코드가 어디서 실행되는지 이해하는 것이 SSR 버그 예방의 핵심이다.
서버 라이프사이클
초기 요청마다 아래 순서로 실행됨.
1. Nitro 서버 플러그인 (서버 시작 시 1회)
2. 서버 미들웨어 (모든 요청마다)
3. 앱 플러그인 (Vue·Nuxt 인스턴스 생성 후)
4. 라우트 검증 (validate)
5. 앱 미들웨어 (global → named → inline)
6. 페이지·컴포넌트 렌더링 + 데이터 패칭
7. HTML 출력
1. Nitro 서버 플러그인 (server/plugins/)
서버 시작 시 1회 실행. 요청마다 실행되지 않음.
- 앱 전역 에러 캡처
- Nitro 종료 시 훅 등록
- 요청 라이프사이클 훅 등록 (응답 수정 등)
⚠️ 주의: 서버리스 환경에서는 매 요청마다 서버가 재부팅되므로 플러그인도 매번 실행됨 (단, awaited되지 않음).
2. 서버 미들웨어 (server/middleware/)
모든 요청에 대해 실행. 인증, 로깅, 요청 변환 등.
⚠️ 주의: 미들웨어에서 값을 반환하면 요청이 종료되고 그 값이 응답으로 전송됨. 의도적인 경우에만 사용할 것.
3. 앱 플러그인 (app/plugins/)
Vue·Nuxt 인스턴스 생성 후 실행. 순서:
- 내장 플러그인 (Vue Router, unhead)
- 커스텀 플러그인 (suffix 없는 것,
.serversuffix)
훅: app:created
4. 라우트 검증 (Route Validation)
definePageMeta의 validate 메서드 실행.
definePageMeta({
validate(route) {
return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id)
// false 반환 → 404, { status: 403, statusText: 'Forbidden' } 반환 → 커스텀 에러
},
})
5. 앱 미들웨어
실행 순서: global → named → inline(anonymous)
서버에서 리다이렉트 발생 시 Location: 헤더 전송 → 브라우저가 새 URL로 재요청 → 모든 앱 상태 초기화 (쿠키로 저장한 것 제외).
6. 페이지·컴포넌트 렌더링
useFetch, useAsyncData로 데이터 패칭. DOM 조작 없으므로 onBeforeMount, onMounted 등 Vue 라이프사이클 훅은 SSR에서 실행되지 않음.
⚠️ 주의:
<script setup>루트 스코프에 사이드 이펙트(setInterval등) 넣지 말 것. 언마운트 훅이 서버에서 호출되지 않아 영구적으로 남음.onMounted안에 넣어야 함.
훅: app:rendered (Vue 렌더링 완료 후), render:html (Nitro가 HTML 최종 처리 전)
클라이언트 라이프사이클
브라우저에서 완전히 실행됨.
1. 앱 플러그인 (suffix 없는 것, .client suffix)
2. 라우트 검증
3. 앱 미들웨어
4. Vue 앱 마운트 + Hydration
5. Vue 라이프사이클 (onMounted 등) 실행
6. 이후 클라이언트 사이드 내비게이션
Hydration
app.mount('#__nuxt') 호출 시 Vue가 서버에서 받은 HTML과 클라이언트의 컴포넌트를 매칭해 이벤트 리스너를 연결.
hydration 오류 방지:
- 데이터 패칭에
useAsyncData,useFetch사용 (서버 데이터 재사용) localStorage,window등 브라우저 전용 API는onMounted안에서만 사용import.meta.server,import.meta.client로 환경 분기
// 환경 분기 패턴
if (import.meta.server) {
// 서버에서만 실행
}
if (import.meta.client) {
// 클라이언트에서만 실행
}
훅: app:beforeMount (마운트 전), app:mounted (마운트 후)
주요 런타임 훅 요약
| 훅 | 실행 시점 | 환경 |
|---|---|---|
app:created |
Vue·Nuxt 인스턴스 생성 후 | 서버·클라이언트 |
app:beforeMount |
Vue 앱 마운트 전 | 클라이언트 |
app:mounted |
Vue 앱 마운트 후 | 클라이언트 |
app:rendered |
Vue 렌더링 완료 | 서버 |
render:html |
HTML 최종 생성 전 | 서버 (Nitro) |
page:start |
페이지 전환 시작 | 클라이언트 |
page:finish |
페이지 전환 완료 | 클라이언트 |
참고 / 출처
reference/3.guide/1.concepts/2.nuxt-lifecycle.md