소개
모바일 앱을 처음부터 시작하여 Nuxt로 만들고 싶으신가요? 이 가이드는 모바일 앱을 처음부터 시작하여 Nuxt 4 프로젝트를 구성하고, 모바일 앱을 native 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 개발용)
1단계: 새로운 Nuxt 4 프로젝트 만들기
새로운 Nuxt 4 프로젝트를 시작하려면:
bunx nuxi@latest init my-mobile-app
cd my-mobile-app
bun install
Nuxt 4 디렉토리 구조
Nuxt 4는 새로운 디렉토리 구조를 사용하며 app code app/ 디렉토리:
my-mobile-app/
app/
assets/
components/
composables/
layouts/
middleware/
pages/
plugins/
utils/
app.vue
public/
server/
nuxt.config.ts
package.json
This structure provides better separation between app and server 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단계: 모바일 스크립트 추가하기
업데이트 하세요 package.json 정적 생성을 테스트하세요:
{
"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
4단계: Capacitor 8 설치하기 .output/public Capacitor의 핵심 패키지를 설치하세요:
Capacitor
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/앱 앱 라이프 사이클 이벤트 (전경/후경, 깊이 링크)
- @capacitor/키보드 키보드 동작을 제어합니다.
- @capacitor/스플래시 화면 자연스러운 스플래시 스크린 제어
- @capacitor/상태바 디바이스 상태 바 스타일링
- @capacitor/설정 키-값 저장소 (localStorage와 유사한 네이티브 저장소)
Step 5: Capacitor 초기화
Capacitor을 프로젝트 세부 정보와 함께 초기화하세요:
bunx cap init "My Mobile App" com.example.mymobileapp --web-dir .output/public
대체:
"My Mobile App"앱의 표시 이름으로 대체com.example.mymobileapp역 도메인 표기법으로 앱 ID를 대체
이것을 생성합니다. 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: 네이티브 플랫폼 추가
플랫폼 패키지를 설치하세요:
bun add @capacitor/ios @capacitor/android
네이티브 프로젝트를 생성하세요:
bunx cap add ios
bunx cap add android
이것을 생성합니다. ios 그리고 android 디렉터리
7단계: 빌드 및 실행
프로젝트를 빌드하고 네이티브 플랫폼과 동기화하세요:
bun run mobile
iOS 시뮬레이터에서 열기:
bun run mobile:ios
또는 Android 에뮬레이터에서 열기:
bun run mobile:android
Xcode (iOS)에서:
- 디바이스 드롭다운에서 시뮬레이터를 선택하세요
- Play 버튼을 클릭하거나
Cmd + R
Android Studio에서:
- Gradle 동기화가 완료될 때까지 기다리세요
- 디바이스 드롭다운에서 에뮬레이터를 선택하세요
- Run 버튼을 클릭하거나
Shift + F10
8단계: Live Reload 설정
빠른 개발을 위해 Live Reload를 활성화하여 변경 사항이 즉시 장치에 나타나도록 하세요.
- 장치의 IP 주소를 찾으세요.
# macOS
ipconfig getifaddr en0
# Windows
ipconfig
- 개발용 Capacitor 설정을 생성하세요. 업데이트
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;
- 개발 서버를 시작하고 네이티브로 설정을 복사하세요.
bun run dev &
NODE_ENV=development bunx cap copy
- Xcode/Android Studio에서 다시 빌드하세요.
이제 Nuxt code의 편집 사항이 장치에서 즉시 반영됩니다.
9단계: 첫 번째 모바일 화면 만들기
모바일 친화적인 홈 스크린을 만들겠습니다. 업데이트 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>
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;
}
11단계: 공유 플러그인 추가
Let's implement the share button functionality:
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>
공유 플러그인을 사용하기 위해:
bun run mobile
Sync 및 Rebuild:
프로젝트 구조
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` (Native Build Builder Credit Next).
- 애플리케이션 아이콘: 기본 아이콘을
ios/App/App/Assets.xcassetsandandroid/app/src/main/res - 스플래시 화면: 자연스러운 프로젝트에서 personalize 하거나
@capacitor/splash-screenconfig - 깊이 있는 링크: 앱 URL 스키마를 구성하십시오
더 많은 기능 추가:
- 카메라:
bun add @capacitor/camera - 위치 정보:
bun add @capacitor/geolocation - 푸시 알림:
bun add @capacitor/push-notifications또는 @capgo/capacitor-firebase-messaging iOS와 Android용 Firebase Cloud Messaging - 파일 시스템:
bun add @capacitor/filesystem
자연스러운 UI 및 전환
Capgo 플러그인을 사용하여 Konsta UI 대신 네이티브 모바일 느낌을 얻으려면:
- @capgo/capacitor-자연스러운 네비게이션 — Liquid Glass 탭바와 네이티브 네비게이션바
- @capgo/capacitor-transition — 네이티브 느낌의 페이지 전환
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
Tailwind safe areas를 위해 추가: @capgo/tailwind-capacitor:
bun add -D tailwind-capacitor
See @capgo/capacitor-자연스러운 네비게이션, @capgo/capacitor-transition, 그리고 Tailwind-capacitor 레포 Capacitor Fixing iOS Layout Issues (Viewport, Safe Area, and Horizontal Overflow)
Capacitor If content looks cropped, shifted, or horizontally scrollable on iOS, adding more
Capacitor or tweaking the viewport tag alone usually does not fix it. Work through these checks in order. overflow-x: hidden Capacitor Make sure the viewport meta tag is applied correctly
Capacitor In
In nuxt.config.tsIn app.head:
export default defineNuxtConfig({
app: {
head: {
meta: [
{
name: 'viewport',
content: 'width=device-width, initial-scale=1, viewport-fit=cover',
},
],
},
},
});
iOS 안전 영역을 한 번에 처리하기
단일 앱 셸을 만들고 안전 영역 패딩을 적용하세요 — 여러 중첩된 컴포넌트에서 적용하지 마세요:
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가 잘려나거나 너무 크게 보이는 문제를 일으킵니다.
Live Update @capgo/tailwind-capacitor단일 셸에서 동일한 패딩을 표현할 수 있는 유틸리티를 사용하세요. pt-safe pb-safe px-safe __CAPGO_KEEP_0__ iOS
Set Capacitor iOS contentInset In never first
In capacitor.config.ts, native inset을 사용하고 CSS (또는 Native Navigation의) contentInsetMode: 'css') safe area를 관리하도록 해주세요:
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: '.output/public',
ios: {
contentInset: 'never',
},
};
Capacitor의 자동 콘텐츠 inset을 CSS padding과 혼합하는 것은 일반적인 double spacing의 원인입니다. env(safe-area-inset-*) 실제로 오버플로우가 발생하는 요소를 찾으세요.
일반적인 원인은 요소가
, Tailwind 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-screenviewport meta tag 자체에서 duplicated safe-area padding, 또는 fixed-width container — viewport meta tag 자체에서 아닌 것.
Over-the-Air 업데이트
설정 Capgo 앱 스토어 재제출 없이 업데이트를 푸시하는 방법:
bunx @capgo/cli init
문제 해결
빌드가 “Cannot find module” 에러로 실패합니다.
실행 bun install 업데이트를 푸시하는 방법은 앱 스토어 재제출 없이 다음과 같습니다.
빌드가 실패합니다. iOS: “No signing identity found”
안드로이드: “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 문서
- __CAPGO_KEEP_0__ 8 Documentation
- Capgo - 라이브 업데이트
- @capgo/capacitor-native-네비게이션
- @capgo/capacitor-transition
- @capgo/tailwind-capacitor
Capgo으로 앱을 배달하는 속도를 더 빠르게 하려면? 무료 계정으로 가입하세요. 오늘.
Build a Nuxt Mobile App from Scratch with Capacitor 8
Build a Nuxt Mobile App from Scratch with __CAPGO_KEEP_0__ 8 Capacitor을 사용하여 CI/CD 자동화 계획을 만드는 경우 __CAPGO_KEEP_0__ CI/CD와 연결하세요. Capgo CI/CD Capgo CI/CD workflow를 위한 Capgo 네이티브 빌드 Capgo 네이티브 빌드 workflow를 위한 Capgo 통합 Capgo 통합 CI/CD 통합 __CAPGO_KEEP_0__ 액션 통합 GitHub 액션 통합 Capacitor 구현 세부 사항에 대한 GitHub 액션 통합.