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

definePageMeta에 변수를 넘겼더니 값이 사라진 이유

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

문제 발생

레이아웃과 미들웨어를 조건에 따라 다르게 주려고 했습니다.

<script setup>
const layoutName = useRuntimeConfig().public.adminLayout;

definePageMeta({
  layout: layoutName,           // 적용되지 않음
  middleware: isAdmin ? "admin" : "auth",
});
</script>

레이아웃이 기본값으로 나오거나 빌드가 실패했습니다. 같은 코드를 컴포넌트로 옮겼더니 아예 무시됐습니다.

원인 분석

런타임에 실행되는 함수가 아닙니다. Nuxt 문서는 definePageMetaapp/pages/ 디렉터리의 페이지 컴포넌트에 메타데이터를 설정하는 컴파일러 매크로로 정의합니다.

컴파일러 매크로라는 것은 빌드 시점에 그 호출을 정적으로 읽어 라우트 정의로 옮긴다는 뜻입니다. 그래서 문서가 못박습니다 — 빌드 타임에 동작하므로 지역 변수나 외부 런타임 값을 참조할 수 없습니다. 라우트 테이블은 앱이 뜨기 전에 확정되어야 하니 당연한 제약입니다.

두 번째 문제도 여기서 나옵니다. 이 매크로는 페이지 컴포넌트에서만 의미가 있습니다. 일반 컴포넌트에 넣으면 아무 일도 일어나지 않습니다.

해결 방안

  1. 정적 값만 넘깁니다.
<script setup>
definePageMeta({
  layout: "admin",
  middleware: ["auth", "admin"],
});
</script>
  1. 조건 분기는 미들웨어 안에서 합니다. "누가 볼 수 있는가"는 런타임 판단이므로 애초에 미들웨어의 일입니다.
// app/middleware/admin.ts
export default defineNuxtRouteMiddleware(() => {
  const { user } = useUserSession();
  if (user.value?.role !== "admin") return navigateTo("/");
});
  1. 레이아웃을 런타임에 바꿔야 하면 setPageLayout을 씁니다. 매크로에 변수를 넣는 대신 미들웨어에서 호출합니다.

  2. 매크로가 지원하는 속성을 먼저 확인합니다. 문서가 나열하는 것은 middleware, layout, alias, name, keepalive, pageTransition, validate, redirect 등이고, 타입 확장으로 커스텀 메타도 추가할 수 있습니다. validate는 잘못된 파라미터를 404로 보내는 데 유용한데 자주 잊힙니다.

  3. 왜 정적이어야 하는지 팀에 남깁니다. 이 제약은 불편이 아니라 라우트 테이블이 빌드 산출물이라는 사실의 결과입니다. 그 사실을 모르면 다음 사람이 같은 코드를 다시 씁니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

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