본문으로 건너뛰기
개발 머꼬
개발 노트Nuxt.js
hohyeon.dev24

레이아웃을 만들었는데 페이지 내용이 사라진 이유

  • #Common Pitfall
  • #Engineering Note
  • #Nuxt.js

문제 발생

공통 헤더를 넣으려고 레이아웃을 만들었더니 페이지 본문이 통째로 사라졌습니다.

<!-- layouts/default.vue -->
<template>
  <AppHeader />
  <AppFooter />
</template>

<slot />을 넣자 내용은 돌아왔는데, 이번에는 다른 프로젝트에서 레이아웃이 아예 적용되지 않는 경우도 만났습니다.

원인 분석

두 가지 연결이 각각 필요합니다.

첫째, 레이아웃은 <slot />으로 페이지를 그립니다. Nuxt 문서 설명대로 레이아웃은 공통 UI 패턴을 재사용 가능한 컴포넌트로 뽑아내고 <slot /> 요소를 통해 페이지 내용을 표시합니다. 슬롯이 없으면 페이지는 렌더될 자리가 없어 사라집니다 — 오류가 아니라 우리가 자리를 안 만든 것입니다.

둘째, app.vue<NuxtLayout>이 있어야 합니다. 문서가 명시합니다 — 레이아웃은 app.vue<NuxtLayout>을 추가함으로써 활성화되며, 그것이 <NuxtPage />를 감쌉니다. app.vue를 직접 만들면서 이걸 빠뜨리면 레이아웃 디렉터리가 통째로 무시됩니다.

구조 제약도 하나 있습니다 — 레이아웃은 레이아웃 전환 애니메이션을 적용할 수 있도록 단일 루트 요소를 가져야 하며, 그 루트 요소가 <slot />일 수는 없습니다.

해결 방안

  1. 레이아웃에 슬롯과 단일 루트를 둡니다.
<!-- layouts/default.vue -->
<template>
  <div class="app-shell">
    <AppHeader />
    <main><slot /></main>
    <AppFooter />
  </div>
</template>
  1. app.vue에서 레이아웃을 켭니다.
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>
  1. 기본 레이아웃 이름을 지킵니다. ~/layouts/default.vue는 별도 지정이 없을 때 자동으로 쓰이는 폴백입니다.

  2. 페이지별로 바꿀 때는 definePageMeta를 씁니다.

<script setup>
definePageMeta({ layout: "admin" });
</script>
  1. 레이아웃을 아예 쓰지 않는 페이지도 명시할 수 있습니다. layout: false로 두면 그 페이지만 셸 없이 렌더됩니다 — 인쇄용 화면이나 임베드 페이지에 씁니다.

  2. 레이아웃과 페이지의 책임을 나눕니다. 레이아웃은 셸(헤더·푸터·네비)만 담당하고 데이터 조회는 페이지가 합니다 — 레이아웃에서 요청 데이터를 읽기 시작하면 모든 페이지가 그 비용을 함께 냅니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.