Nuxt.js란? Nuxt.js는 Vue.js 기반의 프레임워크로, 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG), 그리고 단일 페이지 애플리케이션(SPA)을 쉽게 구축할 수 있게 해줍니다. Nuxt 3부터는 Vue 3와 Vite를 기반으로 더욱 빠르고 강력해졌습니다.
주요 특징
하이브리드 렌더링 : SSR, SSG, SPA 중 선택 가능
자동 라우팅 : 파일 기반 라우팅 시스템
TypeScript 지원 : 완벽한 TypeScript 지원
자동 Import : 컴포넌트와 컴포저블 자동 임포트
SEO 최적화 : 메타 태그 관리와 서버 사이드 렌더링
모듈 시스템 : 풍부한 모듈 생태계
빠른 성능 : Vite와 Nitro 엔진 기반
Nuxt 2 vs Nuxt 3
특징
Nuxt 2
Nuxt 3
Vue 버전
Vue 2
Vue 3
빌드 도구
Webpack
Vite
서버 엔진
Node.js
Nitro
TypeScript
추가 설정 필요
기본 지원
Composition API
플러그인 필요
기본 지원
현재는 Nuxt 3 사용을 권장합니다.
사전 요구사항 Nuxt.js를 사용하기 위해서는 다음이 설치되어 있어야 합니다:
Node.js (v18 이상, v20 권장)
npm, yarn, 또는 pnpm
Nuxt 3 프로젝트 생성 1. 기본 프로젝트 생성 (권장) 가장 간단하고 권장되는 방법입니다.
npx nuxi@latest init project-name pnpm dlx nuxi@latest init project-name yarn dlx nuxi@latest init project-name bunx nuxi@latest init project-name
2. 프로젝트 시작 cd project-namenpm install npm run dev
기본적으로 http://localhost:3000에서 실행됩니다.
3. 템플릿으로 시작하기 공식 스타터 템플릿을 사용할 수도 있습니다:
npx nuxi@latest init -t v3 npx nuxi@latest init -t ui npx nuxi@latest init -t content npx nuxi@latest init -t module
프로젝트 구조 Nuxt 3의 기본 프로젝트 구조:
project-name/ ├── .nuxt/ # 빌드 파일 (자동 생성) ├── .output/ # 프로덕션 빌드 결과 ├── node_modules/ ├── public/ # 정적 파일 │ └── favicon.ico ├── server/ # 서버 API 및 미들웨어 │ ├── api/ # API 라우트 │ ├── routes/ # 서버 라우트 │ └── middleware/ # 서버 미들웨어 ├── assets/ # 빌드될 리소스 (CSS, 이미지 등) ├── components/ # Vue 컴포넌트 ├── composables/ # 컴포저블 함수 ├── layouts/ # 레이아웃 컴포넌트 ├── middleware/ # 라우트 미들웨어 ├── pages/ # 페이지 컴포넌트 (자동 라우팅) ├── plugins/ # 플러그인 ├── utils/ # 유틸리티 함수 ├── app.vue # 메인 앱 컴포넌트 ├── nuxt.config.ts # Nuxt 설정 파일 ├── package.json ├── tsconfig.json # TypeScript 설정 └── .gitignore
핵심 디렉토리 설명 pages/ - 자동 라우팅 pages/ 디렉토리의 파일 구조가 자동으로 라우트가 됩니다.
pages/ ├── index.vue → / ├── about.vue → /about ├── users/ │ ├── index.vue → /users │ └── [id].vue → /users/:id └── posts/ └── [slug].vue → /posts/:slug
components/ - 자동 Import 컴포넌트는 자동으로 임포트되므로 import 문이 필요 없습니다.
<!-- components/MyButton.vue --> <template> <button>Click me</button> </template> <!-- pages/index.vue --> <template> <div> <MyButton /> <!-- 자동으로 사용 가능 --> </div> </template>
composables/ - 재사용 가능한 로직 export const useCounter = ( ) => { const count = ref (0 ) const increment = ( ) => count.value ++ return { count, increment } }
server/api/ - API 엔드포인트 export default defineEventHandler ((event ) => { return { message : 'Hello from API!' } })
기본 파일 설명 app.vue - 메인 애플리케이션 <template> <div> <NuxtPage /> </div> </template> <script setup lang="ts"> // 전역 설정 및 로직 </script>
nuxt.config.ts - Nuxt 설정 export default defineNuxtConfig ({ devtools : { enabled : true }, app : { head : { title : 'My Nuxt App' , meta : [ { charset : 'utf-8' }, { name : 'viewport' , content : 'width=device-width, initial-scale=1' }, { name : 'description' , content : 'My awesome Nuxt 3 app' } ] } }, runtimeConfig : { apiSecret : '' , public : { apiBase : '/api' } }, css : ['~/assets/css/main.css' ], modules : [], vite : { } })
페이지 생성 예제 기본 페이지 <!-- pages/index.vue --> <template> <div> <h1>Welcome to Nuxt 3</h1> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> </div> </template> <script setup lang="ts"> const count = ref(0) const increment = () => count.value++ // SEO 메타 태그 useSeoMeta({ title: 'Home Page', description: 'Welcome to my Nuxt 3 app' }) </script>
동적 라우트 <!-- pages/users/[id].vue --> <template> <div> <h1>User Profile</h1> <p>User ID: {{ route.params.id }}</p> <div v-if="data"> <h2>{{ data.name }}</h2> <p>{{ data.email }}</p> </div> </div> </template> <script setup lang="ts"> const route = useRoute() // 데이터 페칭 const { data } = await useFetch(`/api/users/${route.params.id}`) </script>
데이터 페칭 Nuxt 3는 다양한 데이터 페칭 방법을 제공합니다:
useFetch <script setup lang="ts"> // GET 요청 const { data, pending, error, refresh } = await useFetch('/api/posts') // POST 요청 const { data } = await useFetch('/api/posts', { method: 'POST', body: { title: 'New Post' } }) // 옵션과 함께 const { data } = await useFetch('/api/posts', { query: { page: 1 }, headers: { 'Authorization': 'Bearer token' } }) </script>
useAsyncData <script setup lang="ts"> const { data } = await useAsyncData('posts', () => $fetch('/api/posts')) // 의존성이 있는 경우 const route = useRoute() const { data } = await useAsyncData( `post-${route.params.id}`, () => $fetch(`/api/posts/${route.params.id}`) ) </script>
$fetch (클라이언트 사이드) const data = await $fetch('/api/posts' )
레이아웃 사용 기본 레이아웃 <!-- layouts/default.vue --> <template> <div> <header> <nav> <NuxtLink to="/">Home</NuxtLink> <NuxtLink to="/about">About</NuxtLink> </nav> </header> <main> <slot /> </main> <footer> <p>© 2025 My App</p> </footer> </div> </template>
커스텀 레이아웃 <!-- layouts/custom.vue --> <template> <div class="custom-layout"> <slot /> </div> </template> <!-- pages/special.vue --> <template> <div> <h1>Special Page</h1> </div> </template> <script setup lang="ts"> definePageMeta({ layout: 'custom' }) </script>
미들웨어 라우트 미들웨어 export default defineNuxtRouteMiddleware ((to, from ) => { const user = useState ('user' ) if (!user.value ) { return navigateTo ('/login' ) } }) <script setup lang="ts" > definePageMeta ({ middleware : 'auth' }) </script>
전역 미들웨어 export default defineNuxtRouteMiddleware ((to, from ) => { console .log ('Navigating to:' , to.path ) })
주요 Composables Nuxt 3가 제공하는 유용한 컴포저블:
const route = useRoute ()const router = useRouter ()const state = useState ('key' , () => 'default value' )useHead ({ title : 'Page Title' }) useSeoMeta ({ title : 'SEO Title' , description : 'SEO Description' }) const config = useRuntimeConfig ()const cookie = useCookie ('name' )const error = useError ()showError ({ statusCode : 404 , message : 'Not Found' })clearError ()
빌드 및 배포 개발 서버 npm run dev npm run dev -- --port 3001
프로덕션 빌드 npm run build npm run preview
SSR 배포 npm run build node .output/server/index.mjs
정적 사이트 생성 (SSG) export default defineNuxtConfig ({ ssr : true , nitro : { preset : 'static' } })
SPA 모드 export default defineNuxtConfig ({ ssr : false })
인기 있는 Nuxt 모듈 Nuxt 생태계의 유용한 모듈들:
UI 프레임워크 npm install @nuxt/ui npm install -D @nuxtjs/tailwindcss npm install vuetify @nuxtjs/vuetify
Content 관리 npm install @nuxt/content
이미지 최적화
국제화
HTTP 클라이언트 npm install @nuxtjs/axios
인증 npm install @sidebase/nuxt-auth
PWA npm install @vite-pwa/nuxt
환경 변수 .env 파일 # .env NUXT_PUBLIC_API_BASE=https://api.example.com NUXT_API_SECRET=secret-key
nuxt.config.ts에서 사용 export default defineNuxtConfig ({ runtimeConfig : { apiSecret : process.env .NUXT_API_SECRET , public : { apiBase : process.env .NUXT_PUBLIC_API_BASE } } })
컴포넌트에서 사용 <script setup lang="ts"> const config = useRuntimeConfig() // 클라이언트에서 사용 가능 console.log(config.public.apiBase) // 서버에서만 사용 가능 console.log(config.apiSecret) // 클라이언트에서는 undefined </script>
TypeScript 설정 Nuxt 3는 TypeScript를 기본으로 지원합니다.
자동 타입 생성 개발 서버를 실행하면 .nuxt/nuxt.d.ts 에 자동으로 타입이 생성됩니다.
tsconfig.json { "extends" : "./.nuxt/tsconfig.json" , "compilerOptions" : { "strict" : true , "types" : [ "@nuxt/types" , "@types/node" ] } }
타입 체크
유용한 CLI 명령어 npx nuxi dev npx nuxi build npx nuxi preview npx nuxi generate npx nuxi info npx nuxi typecheck npx nuxi upgrade npx nuxi cleanup
성능 최적화 팁 1. 지연 로딩 <template> <div> <LazyMyHeavyComponent v-if="show" /> </div> </template>
2. 클라이언트 전용 렌더링 <template> <div> <ClientOnly> <HeavyComponent /> <template #fallback> <LoadingSpinner /> </template> </ClientOnly> </div> </template>
3. 이미지 최적화 <template> <NuxtImg src="/image.jpg" width="300" height="200" loading="lazy" /> </template>
4. 프리페칭 제어 <template> <NuxtLink to="/about" :prefetch="false"> About </NuxtLink> </template>
디버깅 Nuxt 3는 Vue DevTools를 내장하고 있습니다:
export default defineNuxtConfig ({ devtools : { enabled : true } })
서버 로그 export default defineEventHandler ((event ) => { console .log ('Server log:' , event.path ) return { success : true } })
문제 해결 포트 변경 npm run dev -- --port 3001
캐시 문제 rm -rf .nuxtrm -rf node_modulesnpm install
타입 오류
다음 단계 프로젝트를 성공적으로 생성했다면:
컴포넌트 작성 : Vue 3 Composition API 활용
라우팅 이해 : 파일 기반 라우팅 시스템 학습
데이터 페칭 : useFetch, useAsyncData 활용
상태 관리 : useState 또는 Pinia 사용
API 개발 : server/api 디렉토리 활용
SEO 최적화 : useSeoMeta 설정
모듈 탐색 : Nuxt 모듈 생태계 활용
참고 자료
마무리 Nuxt.js는 Vue.js 애플리케이션 개발을 더욱 쉽고 강력하게 만들어주는 프레임워크입니다. 자동 라우팅, 서버 사이드 렌더링, 정적 사이트 생성 등 다양한 기능을 제공하며, Nuxt 3부터는 Vite 기반으로 더욱 빠른 개발 경험을 제공합니다. 파일 기반의 직관적인 구조와 풍부한 모듈 생태계로 빠르게 프로덕션 레벨의 애플리케이션을 개발할 수 있습니다.