소개
Nuxt로 모바일 앱을 처음부터 만들고 싶으신가요? 이 가이드에서는 Nuxt 4 프로젝트를 모바일용으로 처음부터 설정하고, iOS 및 Android 앱으로 패키징하는 방법을 알려드립니다. Capacitor 8.
이 튜토리얼을 마치면 시뮬레이터에서 작동하는 모바일 앱을 만들 수 있으며, 개발을 계속하고 나중에는 앱 스토어와 구글 플레이에 게시할 수 있습니다.
필요 시간: ~30분
만드는 것:
- 새로운 Nuxt 4 프로젝트와 최신 디렉토리 구조
- 모바일용 정적 생성 구성
- Capacitor 8에 필수 플러그인
- 자연 iOS 및 Android 앱
- 라이브 리로드 개발 설정
Nuxt 앱이 이미 있으신가요? Nuxt 앱을 모바일로 변환하세요. 대신.
필수 조건
다음 항목이 설치되어 있는지 확인하세요:
- Node.js 18+ (
node --version) - Bun 패키지 매니저 (
curl -fsSL https://bun.sh/install | bash) - Xcode (macOS만, iOS 개발용)
- Android Studio (for Android development)
1단계: Nuxt 4 프로젝트 만들기
Nuxt 4 프로젝트를 시작하기 위해 새로운 Nuxt 4 프로젝트를 생성하세요:
bunx nuxi@latest init my-mobile-app
cd my-mobile-app
bun install
Nuxt 4 디렉토리 구조
Nuxt 4는 앱 code이 포함된 새로운 디렉토리 구조를 사용합니다. app/ 디렉토리:
my-mobile-app/
app/
assets/
components/
composables/
layouts/
middleware/
pages/
plugins/
utils/
app.vue
public/
server/
nuxt.config.ts
package.json
이 구조는 앱과 서버 code 사이의 분리를 향상시킵니다.
2단계: Nuxt를 정적 생성에 구성하기
Capacitor는 정적 HTML/JS/CSS 파일이 필요합니다. Nuxt를 정적 생성에 구성하세요. nuxt.config.ts:
export default defineNuxtConfig({
compatibilityDate: '2025-01-15',
devtools: { enabled: true },
// Enable static generation
ssr: true,
nitro: {
preset: 'static',
},
});
3단계: 모바일 스크립트 추가하기
__CAPGO_KEEP_0__를 모바일 개발 스크립트로 업데이트하세요: package.json with mobile development scripts:
{
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"generate": "nuxt generate",
"preview": "nuxt preview",
"mobile": "bun run generate && bunx cap sync",
"mobile:ios": "bun run mobile && bunx cap open ios",
"mobile:android": "bun run mobile && bunx cap open android"
}
}
정적 생성 테스트:
bun run generate
정적 파일이 포함된 .output/public 디렉토리를 볼 수 있습니다.
4단계: Capacitor 8 설치
Capacitor 핵심 패키지 설치:
bun add @capacitor/core
bun add -D @capacitor/cli
모바일 앱이 일반적으로 필요로 하는 필수 플러그인 설치:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/status-bar @capacitor/preferences
이러한 플러그인이 무엇을 하는지:
- @capacitor/app 앱 생명주기 이벤트 (전경/후경, 깊이 링크)
- @capacitor/keyboard 키보드 동작 제어
- @capacitor/splash-screen — 네이티브 스플래시 화면 제어
- @capacitor/status-bar — 장치 상태 바 스타일링
- @capacitor/preferences — 키-값 저장소 (localStorage와 같은 네이티브)
Step 5: Capacitor 초기화
Capacitor을 프로젝트 세부 정보와 초기화하세요:
bunx cap init "My Mobile App" com.example.mymobileapp --web-dir .output/public
Replace:
"My Mobile App"with your app의 표시 이름com.example.mymobileappwith your app ID (역방향 도메인 표기법)
This creates capacitor.config.ts. 플러그인 구성으로 업데이트하세요:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.mymobileapp',
appName: 'My Mobile App',
webDir: '.output/public',
plugins: {
SplashScreen: {
launchShowDuration: 2000,
launchAutoHide: true,
androidScaleType: 'CENTER_CROP',
splashFullScreen: true,
splashImmersive: true,
},
Keyboard: {
resize: 'body',
resizeOnFullScreen: true,
},
StatusBar: {
style: 'dark',
},
},
};
export default config;
Step 6: Native 플랫폼 추가
설치할 플랫폼 패키지를 설치하세요:
bun add @capacitor/ios @capacitor/android
네이티브 프로젝트를 생성하세요:
bunx cap add ios
bunx cap add android
이것은 ios 그리고 android 디렉토리 내에 네이티브 프로젝트가 생성됩니다.
Step 7: 빌드 및 실행
프로젝트를 빌드하고 네이티브 플랫폼과 동기화하세요:
bun run mobile
iOS 시뮬레이터에서 열기:
bun run mobile:ios
또는 Android 에뮬레이터에서 열기:
bun run mobile:android
Xcode (iOS)에서:
- 디바이스 드롭다운에서 시뮬레이터를 선택하세요
- 플레이 버튼을 클릭하거나
Cmd + R
Android Studio에서:
- Gradle 동기화가 완료될 때까지 기다려 주세요.
- 디바이스 드롭다운에서 에뮬레이터를 선택하세요.
- 실행 버튼을 클릭하거나
Shift + F10
8단계: Live Reload 설정
개발을 더 빠르게 하려면, 변경 사항이 즉시 디바이스에 나타나도록 Live Reload를 활성화하세요.
- 디바이스의 IP 주소를 찾으세요:
# macOS
ipconfig getifaddr en0
# Windows
ipconfig
- 개발 Capacitor 설정을 생성하세요. Update
capacitor.config.ts:
import type { CapacitorConfig } from '@capacitor/cli';
const devConfig: CapacitorConfig = {
appId: 'com.example.mymobileapp',
appName: 'My Mobile App',
webDir: '.output/public',
server: {
url: 'http://YOUR_IP_ADDRESS:3000',
cleartext: true,
},
plugins: {
// ... same plugin config
},
};
const prodConfig: CapacitorConfig = {
appId: 'com.example.mymobileapp',
appName: 'My Mobile App',
webDir: '.output/public',
plugins: {
// ... same plugin config
},
};
const config = process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
export default config;
- 개발 서버를 시작하고 config를 네이티브로 복사하세요:
bun run dev &
NODE_ENV=development bunx cap copy
- Xcode/Android Studio에서 다시 빌드하세요.
이제 Nuxt code의 편집 사항이 디바이스에서 즉시 반영됩니다.
Step 9: 모바일 첫 번째 화면 만들기
Let’s 모바일 홈 화면을 만들어요. 업데이트 app/app.vue:
<template>
<NuxtPage />
</template>
만들기 app/pages/index.vue:
<template>
<main
class="min-h-screen bg-linear-to-b from-green-500 to-green-700 flex flex-col items-center justify-center p-6 text-white"
>
<h1 class="text-4xl font-bold mb-4">My Mobile App</h1>
<p class="text-xl mb-8 text-center opacity-90">
Built with Nuxt 4 + Capacitor 8
</p>
<div v-if="appInfo" class="bg-white/20 rounded-lg p-4 backdrop-blur-sm mb-8">
<p class="text-sm">
{{ appInfo.name }} v{{ appInfo.version }}
</p>
</div>
<div class="space-y-4 w-full max-w-sm">
<button
class="w-full py-4 px-6 bg-white text-green-600 rounded-xl font-semibold text-lg shadow-lg active:scale-95 transition-transform"
@click="handleGetStarted"
>
Get Started
</button>
<button
class="w-full py-4 px-6 bg-white/20 text-white rounded-xl font-semibold text-lg backdrop-blur-sm active:scale-95 transition-transform"
@click="handleShare"
>
Share App
</button>
</div>
</main>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { App } from '@capacitor/app';
const appInfo = ref<{ name: string; version: string } | null>(null);
let backButtonListener: { remove: () => void } | null = null;
onMounted(async () => {
// Get app info
try {
appInfo.value = await App.getInfo();
} catch (e) {
// Web fallback
appInfo.value = { name: 'My Mobile App', version: '1.0.0' };
}
// Handle Android back button
backButtonListener = await App.addListener('backButton', ({ canGoBack }) => {
if (!canGoBack) {
App.exitApp();
} else {
window.history.back();
}
});
});
onUnmounted(() => {
backButtonListener?.remove();
});
function handleGetStarted() {
// Navigate to onboarding or main app
console.log('Get started clicked');
}
async function handleShare() {
// We'll implement this with the Share plugin later
console.log('Share clicked');
}
</script>
Step 10: Tailwind CSS 추가하기
스타일링이 작동하려면 프로젝트에 Tailwind CSS를 추가하세요:
bun add tailwindcss @tailwindcss/vite
업데이트 nuxt.config.ts:
import tailwindcss from '@tailwindcss/vite';
export default defineNuxtConfig({
compatibilityDate: '2025-01-15',
devtools: { enabled: true },
ssr: true,
nitro: {
preset: 'static',
},
css: ['~/assets/css/main.css'],
vite: {
plugins: [tailwindcss()],
},
});
만들기 app/assets/css/main.css:
@import 'tailwindcss';
:root {
--sat: env(safe-area-inset-top);
--sar: env(safe-area-inset-right);
--sab: env(safe-area-inset-bottom);
--sal: env(safe-area-inset-left);
}
body {
padding-top: var(--sat);
padding-right: var(--sar);
padding-bottom: var(--sab);
padding-left: var(--sal);
}
/* Prevent text selection on mobile */
* {
-webkit-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
/* Allow text selection in inputs */
input,
textarea {
-webkit-user-select: auto;
user-select: auto;
}
Step 11: 공유 플러그인 추가하기
공유 버튼 기능을 구현해 보아요:
bun add @capacitor/share
업데이트 app/pages/index.vue 공유 플러그인을 사용하려면:
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { App } from '@capacitor/app';
import { Share } from '@capacitor/share';
// ... existing code ...
async function handleShare() {
try {
await Share.share({
title: 'Check out this app!',
text: 'Built with Nuxt 4 and Capacitor 8',
url: 'https://capacitorjs.com',
dialogTitle: 'Share with friends',
});
} catch (e) {
console.log('Share cancelled or failed:', e);
}
}
</script>
Sync 및 재구축:
bun run mobile
프로젝트 구조
현재 프로젝트는 다음과 같이 보아야 합니다.
my-mobile-app/
├── android/ # Android native project
├── ios/ # iOS native project
├── .output/
│ └── public/ # Static build output
├── app/
│ ├── assets/
│ │ └── css/
│ │ └── main.css
│ ├── pages/
│ │ └── index.vue
│ └── app.vue
├── capacitor.config.ts # Capacitor configuration
├── nuxt.config.ts # Nuxt configuration
├── package.json
└── ...
다음 단계
페이지/영역: Capgo Builder / 네이티브 클라우드 빌드 제품 페이지. 역할: 짧은 UI 레이블 또는 네비게이션 아이템. 메시지 키 `native_build_builder_credit_next` (네이티브 빌드 빌더 크레딧 다음).
이제 Nuxt 모바일 앱이 작동합니다. 다음 단계는 무엇입니까?
- 필수 설정 앱 아이콘:
ios/App/App/Assets.xcassets기본 아이콘을android/app/src/main/res - 페이지/영역: Capgo 마케팅 웹사이트. 역할: 짧은 UI 레이블 또는 네비게이션 아이템. 페이지 trust.astro에서 볼 수 있음. 메시지 키 `and` (그리고). 스플래시 화면:
@capacitor/splash-screen네이티브 프로젝트에서 커스터마이즈하거나 - 설정파일을 사용하세요. config URL Scheme 설정
더 많은 기능 추가
- 카메라:
bun add @capacitor/camera - 위치 정보:
bun add @capacitor/geolocation - 푸시 알림:
bun add @capacitor/push-notifications또는 @capgo/capacitor-firebase-messaging Capacitor와 Capgo의 다른 라이브러리들 - Capacitor와 Capgo의 다른 라이브러리들
bun add @capacitor/filesystem
Capacitor와 Capgo의 다른 라이브러리들
Use Capgo plugins instead of Konsta UI for a native mobile feel:
- @capgo/capacitor-native-navigation — Liquid Glass tab bar and native navbar
- @capgo/capacitor-transitions — native-feeling page transitions
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
Tailwind safe areas를 위해 추가하세요 @capgo/tailwind-capacitor:
bun add -D tailwind-capacitor
Using @__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-native-navigation Using @capgo/capacitor-transitions, Using @capgo/capacitor-transitionstailwind-__CAPGO_KEEP_0__ repo tailwind-capacitor repo For Tailwind safe areas, add
See
iOS에서 콘텐츠가 잘려나거나-shifted하거나 가로 스크롤이 가능하다면, 더 많은 overflow-x: hidden 또는 뷰포트 태그를 조정하는 것만으로는 문제를 해결할 수 없다. 이러한 체크를 순서대로 진행하라.
뷰포트 메타 태그가 올바르게 적용되었는지 확인하라.
In nuxt.config.ts, 뷰포트를 통해 app.head:
export default defineNuxtConfig({
app: {
head: {
meta: [
{
name: 'viewport',
content: 'width=device-width, initial-scale=1, viewport-fit=cover',
},
],
},
},
});
iOS 안전 영역을 하나의 루트 wrapper에서만 처리하라.
싱글 앱 셸을 생성하고 안전 영역 패딩을 거기에 적용하라 — 여러 개의 중첩된 컴포넌트에서만 적용하지 마라:
html,
body,
#__nuxt {
width: 100%;
min-height: 100%;
margin: 0;
padding: 0;
overflow-x: hidden;
}
* {
box-sizing: border-box;
}
.app-shell {
min-height: 100dvh;
width: 100%;
padding-top: env(safe-area-inset-top);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
}
모든 페이지 콘텐츠를 내부에 .app-shell. 중복된 안전 영역 패딩이 헤더, 모달, 레이아웃 wrapper에 적용되어 UI가 잘려나거나 너무 크게 보인다.
With @capgo/tailwind-capacitor와 같은 유틸리티를 사용하여 동일한 패딩을 표현할 수 있다. pt-safe pb-safe px-safe 그 단일 셸에서.
Capacitor iOS 설정 contentInset Live Update Dynamic Label To never 처음
In capacitor.config.ts, Native Navigation의 안전한 영역을 CSS (또는 Native Navigation)가 관리하도록 해서 contentInsetMode: 'css'__CAPGO_KEEP_0__의 자동 콘텐츠 인셋과 CSS 패딩을 혼합하는 것은 더블 스페이싱의 일반적인 원인입니다.
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: '.output/public',
ios: {
contentInset: 'never',
},
};
Mixing Capacitor’s automatic content inset with CSS env(safe-area-inset-*) 일반적으로 원인은 요소가
, Tailwind를 사용하는 것입니다.
__CAPGO_KEEP_0__의 자동 콘텐츠 인셋과 CSS 패딩을 혼합하는 것은 더블 스페이싱의 일반적인 원인입니다. 100vw실제로 넘치는 요소를 찾으세요. w-screen픽셀 너비 또는 대형 min-width.
Safari Web Inspector에서 실행하세요:
[...document.querySelectorAll('*')]
.filter(el => el.scrollWidth > document.documentElement.clientWidth)
.map(el => ({
el,
tag: el.tagName,
class: el.className,
scrollWidth: el.scrollWidth,
clientWidth: document.documentElement.clientWidth,
}));
Tailwind로 대체 w-screen 가능한 경우 w-full 수평 스크롤 문제는 보통 100vw / w-screen중복된 안전 영역 패딩 또는 픽셀 너비 컨테이너에서 오는 것이 아니라
viewport meta 태그 자체에서 오는 것입니다.
오버 더 에어 업데이트 Capgo 문제 해결
bunx @capgo/cli init
__CAPGO_KEEP_0__
트러블 슈팅
실행 bun install 다시 시도해 보세요.
iOS: “인증서를 찾을 수 없습니다.” Xcode를 열고, Signing & Capabilities로 이동하여 개발 팀을 선택하세요.
Android: “SDK 위치를 찾을 수 없습니다.”
생성 android/local.properties 와 sdk.dir=/path/to/android/sdk
장치에 변경 사항이 보이지 않습니다.
변경 사항이 적용된 후에 bun run mobile 변경 사항이 적용된 후에 다시 실행해 보세요. 라이브 리로드를 위해 IP 주소가 정확하고 개발 서버가 실행 중인지 확인하세요.
.output/public이 비어 있거나 누락된 경우
변경 사항이 적용된 후에 개발 환경을 다시 설정하세요. nitro: { preset: 'static' } 내 nuxt.config.ts 및 실행 bun run generate.
자원
- Capacitor 8 문서
- Nuxt 4 문서
- Capgo - 실시간 업데이트
- @capgo/capacitor-자연스러운 네비게이션
- @capgo/capacitor-전환
- @capgo/tailwind-capacitor
앱을 배달하기 위해 준비되셨나요? Capgo이 업데이트를 더 빠르게 전달하는 방법에 대해 배워보세요 — 무료 계정으로 가입하세요 오늘
Build a Nuxt Mobile App from Scratch with Capacitor 8
만약에 Build a Nuxt Mobile App from Scratch with Capacitor 8 CI/CD 자동화 계획을 만들기 위해 Capgo CI/CD Capgo CI/CD에서 제품 워크플로우 Capgo Native Builds Capgo Native Builds에서 제품 워크플로우 Capgo Integrations 제품 워크플로우에서 Capgo Integrations CI/CD 통합 제품 워크플로우에서 CI/CD 통합 구현 세부 사항 GitHub 액션 통합 액션 통합 구현 세부 사항에 대한 GitHub.