지난 포스트에서 Nuxt.js의 기본 개념과 개발 환경 설정에 대해 알아보았습니다. 이번 포스트는 Nuxt.js의 핵심 기능 중 하나인 파일 기반 라우팅 시스템에 대해 자세히 알아보겠습니다. Vue.js에서는 라우팅을 위해 별도로 router 설정을 해주어야 했지만, Nuxt.js에서는 파일 구조만으로 자동으로 라우팅이 구성되는 편리한 시스템을 제공합니다.
1. Nuxt.js의 파일 기반 라우팅
Nuxt.js에서는 app/pages 디렉토리 내의 파일 구조가 곧 애플리케이션의 라우팅 구조가 됩니다. 이는 개발자가 별도의 라우터 설정 없이도 직관적으로 페이지를 구성할 수 있게 해줍니다.
기본적인 파일 구조와 해당 URL 매핑은 다음과 같습니다:
app/pages/index.vue
→/
(홈페이지)app/pages/about.vue
→/about
app/pages/blog/index.vue
→/blog
app/pages/blog/post.vue
→/blog/post
간단한 예제로 확인해보겠습니다. 먼저 홈페이지와 소개 페이지를 만들어 보겠습니다.
2. 기본 페이지 구성하기
홈페이지(app/pages/index.vue)를 다음과 같이 작성합니다:
<template>
<div>
<h1>Nuxt.js 학습 홈페이지</h1>
<p>Nuxt.js의 라우팅 시스템에 대해 알아봅시다!</p>
<NuxtLink to="/about">소개 페이지로 이동</NuxtLink>
</div>
</template>
소개 페이지(app/pages/about.vue)를 작성합니다:
<template>
<div>
<h1>소개 페이지</h1>
<p>이 페이지는 Nuxt.js의 파일 기반 라우팅으로 자동 생성되었습니다.</p>
<NuxtLink to="/">홈으로 돌아가기</NuxtLink>
</div>
</template>
이렇게 파일을 생성하면 Nuxt.js는 자동으로 라우팅을 구성하여 해당 URL로 접근할 수 있게 해줍니다.


3. NuxtLink 컴포넌트 활용하기
위 예제에서 사용한 <NuxtLink> 컴포넌트는 Nuxt.js에서 페이지 간 이동을 위해 제공하는 특별한 컴포넌트입니다. 일반 HTML의 <a>
태그와 달리, <NuxtLink>는 페이지를 새로고침하지 않고 클라이언트 사이드에서 페이지 전환을 처리합니다.
<NuxtLink>의 주요 특징:
- 자동 코드 스플리팅: 필요한 페이지 컴포넌트만 로드
- 프리페칭: 링크가 화면에 보이면 해당 페이지를 미리 로드
- 활성 클래스: 현재 활성화된 링크에 자동으로 클래스 적용
외부 링크를 위해서는 external 속성을 사용할 수 있습니다:
blog
4. 동적 라우팅 구현하기
실제 애플리케이션에서는 블로그 포스트, 제품 상세 페이지 등 동적인 ID나 슬러그를 기반으로 한 라우팅이 필요합니다. Nuxt.js에서는 파일 이름에 대괄호([])를 사용하여 동적 라우팅을 구현할 수 있습니다.
예를 들어, 블로그 포스트 상세 페이지를 만들어 보겠습니다:
// app/pages/blog/[id].vue
<template>
<div>
<h1>블로그 포스트 #{{ $route.params.id }}</h1>
<p>이 페이지는 동적 라우팅으로 생성되었습니다.</p>
<NuxtLink to="/blog">블로그 목록으로 돌아가기</NuxtLink>
</div>
</template>
<script setup>
const route = useRoute();
console.log('현재 포스트 ID:', route.params.id);
</script>
이제 블로그 목록 페이지를 만들어 각 포스트로 이동할 수 있게 해보겠습니다:
// app/pages/blog/index.vue
<template>
<div>
<h1>블로그 포스트 목록</h1>
<ul>
<li v-for="id in 5" :key="id">
<NuxtLink :to="`/blog/${id}`">포스트 #{{ id }} 보기</NuxtLink>
</li>
</ul>
<NuxtLink to="/">홈으로 돌아가기</NuxtLink>
</div>
</template>
이렇게 하면 /blog/1, /blog/2 등의 URL로 접근할 수 있고, 각 페이지에서는 해당 ID를 파라미터로 받아 처리할 수 있습니다.


5. useRoute 컴포저블 활용하기
위 예제에서 사용한 useRoute는 Nuxt.js에서 제공하는 컴포저블(composable) 함수로, 현재 라우트 정보에 접근할 수 있게 해줍니다. 이를 통해 라우트 파라미터, 쿼리 파라미터, 현재 경로 등 다양한 정보를 활용할 수 있습니다.
<script setup>
const route = useRoute();
// 라우트 파라미터 접근
console.log(route.params.id);
// 쿼리 파라미터 접근 (/blog/1?category=tech)
console.log(route.query.category);
// 현재 경로 확인
console.log(route.path);
</script>
useRoute는 Vue의 Composition API와 함께 사용되어 더 깔끔하고 타입 안전한 코드를 작성할 수 있게 해줍니다.

6. 중첩 라우팅 구현하기
Nuxt.js에서는 중첩 라우팅을 구현하기 위해 디렉토리 구조와 동일한 이름의 Vue 파일을 생성하고, 그 안에 <NuxtPage /> 컴포넌트를 사용합니다.
예를 들어, 사용자 프로필 페이지와 그 하위 페이지들을 구현해 보겠습니다:
// app/pages/users.vue (부모 라우트)
<template>
<div>
<h1>사용자 페이지</h1>
<nav>
<ul>
<li><NuxtLink to="/users/profile">프로필</NuxtLink></li>
<li><NuxtLink to="/users/settings">설정</NuxtLink></li>
</ul>
</nav>
<!-- 중첩된 페이지가 렌더링될 위치 -->
<NuxtPage />
</div>
</template>
이제 중첩된 페이지들을 만들어 보겠습니다:
// pages/users/profile.vue
<template>
<div>
<h2>사용자 프로필</h2>
<p>여기에 프로필 정보가 표시됩니다.</p>
</div>
</template>
// pages/users/settings.vue
<template>
<div>
<h2>사용자 설정</h2>
<p>여기에서 설정을 변경할 수 있습니다.</p>
</div>
</template>
이렇게 구성하면 /users
페이지에 접속했을 때 공통 레이아웃이 유지되면서 /users/profile
이나 /users/settings
로 이동할 때 해당 컨텐츠만 변경됩니다.


7. 라우트 메타데이터 활용하기
각 페이지에 메타데이터를 추가하여 SEO 최적화나 페이지별 설정을 관리할 수 있습니다. Nuxt.js에서는 definePageMeta 함수를 사용합니다:
<script setup>
definePageMeta({
title: '블로그 상세 페이지',
layout: 'blog',
middleware: ['auth']
});
</script>
이렇게 정의된 메타데이터는 useRoute().meta
를 통해 접근할 수 있으며, 레이아웃이나 미들웨어 등 Nuxt.js의 다양한 기능과 연동됩니다.
definePageMeta에 대한 참고 링크 : https://nuxt.com/docs/4.x/api/utils/define-page-meta
8. 프로그래매틱 라우팅
때로는 버튼 클릭이나 폼 제출 같은 이벤트 후에 프로그래밍 방식으로 페이지를 이동해야 할 경우가 있습니다. Nuxt.js에서는 navigateTo
함수를 제공합니다:
<template>
<div>
<button @click="handleLogin">로그인</button>
</div>
</template>
<script setup>
async function handleLogin() {
// 로그인 로직 처리
const isLoggedIn = await loginUser();
if (isLoggedIn) {
// 로그인 성공 시 대시보드로 이동
navigateTo('/dashboard');
}
}
</script>
navigateTo
함수는 다양한 옵션을 지원합니다:
// 외부 URL로 이동
navigateTo('https://nuxt.com', { external: true });
// 쿼리 파라미터 추가
navigateTo('/search', { query: { keyword: 'nuxt' } });
// 현재 페이지 새로고침
navigateTo(useRoute().path, { replace: true });
9. 404 페이지 및 에러 처리
존재하지 않는 경로에 접근했을 때 표시할 404 페이지를 만들어 보겠습니다. Nuxt.js에서는 pages/[...slug].vue
파일을 사용하여 모든 경로를 캐치할 수 있습니다:
// pages/[...slug].vue
<template>
<div>
<h1>404 - 페이지를 찾을 수 없습니다</h1>
<p>요청하신 페이지 "{{ $route.path }}"를 찾을 수 없습니다.</p>
<NuxtLink to="/">홈으로 돌아가기</NuxtLink>
</div>
</template>
<script setup>
const route = useRoute();
// 404 상태 코드 설정
if (process.server) {
setResponseStatus(404);
}
</script>

또는 더 일반적인 에러 페이지를 error.vue 파일로 프로젝트 루트에 만들 수도 있습니다:
// error.vue (프로젝트 루트에 위치)
<template>
<div>
<h1>{{ error.statusCode }} 오류 발생</h1>
<p>{{ error.message }}</p>
<button @click="handleError">홈으로 돌아가기</button>
</div>
</template>
<script setup>
const props = defineProps({
error: Object
});
function handleError() {
clearError({ redirect: '/' });
}
</script>
10. 실습: 간단한 블로그 라우팅 시스템 구현하기
지금까지 배운 내용을 바탕으로 간단한 블로그 라우팅 시스템을 구현해 보겠습니다:
// app/pages/index.vue (홈페이지)
<template>
<div>
<h1>Nuxt.js 블로그</h1>
<p>Nuxt.js로 만든 간단한 블로그입니다.</p>
<NuxtLink to="/posts">블로그 포스트 보기</NuxtLink>
</div>
</template>
// app/pages/posts/index.vue (포스트 목록)
[<template>
<div>
<h1>블로그 포스트 목록</h1>
<ul>
<li v-for="post in posts" :key="post.id">
<NuxtLink :to="`/posts/${post.id}`">
{{ post.title }}
</NuxtLink>
</li>
</ul>
</div>
</template>
<script setup>
// 실제로는 API에서 가져올 데이터
const posts = [
{ id: 1, title: 'Nuxt.js 시작하기' },
{ id: 2, title: '파일 기반 라우팅의 장점' },
{ id: 3, title: '서버 사이드 렌더링 이해하기' },
{ id: 4, title: 'Nuxt.js로 SEO 최적화하기' }
];
</script>]
// app/pages/posts/[id].vue (포스트 상세)
<template>
<div v-if="post">
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<NuxtLink to="/posts">목록으로 돌아가기</NuxtLink>
</div>
<div v-else>
<p>포스트를 찾을 수 없습니다.</p>
</div>
</template>
<script setup>
const route = useRoute();
const postId = parseInt(route.params.id);
// 실제로는 API에서 가져올 데이터
const posts = [
{
id: 1,
title: 'Nuxt.js 시작하기',
content: 'Nuxt.js는 Vue.js 기반의 프레임워크로...'
},
{
id: 2,
title: '파일 기반 라우팅의 장점',
content: '파일 기반 라우팅은 개발자 경험을 향상시키고...'
},
{
id: 3,
title: '서버 사이드 렌더링 이해하기',
content: 'SSR은 초기 로딩 성능과 SEO에 큰 이점을...'
},
{
id: 4,
title: 'Nuxt.js로 SEO 최적화하기',
content: 'Nuxt.js는 메타 태그 관리를 쉽게 할 수 있어...'
}
];
const post = posts.find(p => p.id === postId);
// 포스트가 없을 경우 404 상태 코드 설정
if (!post && process.server) {
setResponseStatus(404);
}
</script>


마무리 및 다음 포스트 소개
이번 포스트에서는 Nuxt.js의 파일 기반 라우팅 시스템에 대해 살펴보았습니다. 파일 구조만으로 자동으로 라우팅이 구성되는 Nuxt.js의 강력한 기능을 통해 복잡한 라우터 설정 없이도 직관적으로 페이지를 구성할 수 있다는 것을 배웠습니다.
주요 내용을 요약하면:
- 파일 기반 라우팅의 기본 개념과 구조
- <NuxtLink> 컴포넌트를 활용한 페이지 이동
- 동적 라우팅과 파라미터 활용
- useRoute 컴포저블을 통한 라우트 정보 접근
- 중첩 라우팅 구현 방법
- 404 페이지 및 에러 처리
다음 포스트에서는 레이아웃과 컴포넌트에 대해 알아볼 예정입니다. Nuxt.js에서 공통 레이아웃을 설계하고 적용하는 방법, 재사용 가능한 컴포넌트를 제작하고 활용하는 방법을 배우게 됩니다. 특히 layouts 디렉토리 활용법, <slot/>을 이용한 콘텐츠 영역 설정, components 디렉토리의 자동 임포트 기능 등을 자세히 다룰 예정이니 기대해 주세요!
답글 남기기