메인 콘텐츠로 건너뛰기
강좌

Capacitor 8을 사용하여 Nuxt 모바일 앱부터 시작하는 방법

Capacitor 8을 사용하여 새로운 Nuxt 4 프로젝트를 만들고 iOS 및 Android 모바일 앱으로 변환하는 단계별 가이드입니다. 모바일 개발을 시작하는 데 적합합니다.

마틴 도나디우

마틴 도나디우

콘텐츠 마케터

Capacitor 8을 사용하여 Nuxt 모바일 앱부터 시작하는 방법

소개

Nuxt를 사용하여 모바일 앱을 처음부터 만들고 싶으십니까? 이 가이드는 모바일 앱을 처음부터 만들기 위해 Nuxt 4 프로젝트를 새로 만들고, 모바일 앱을 처음부터 만들기 위해 Nuxt 4 프로젝트를 새로 만들고, __CAPGO_KEEP_0__ 8을 사용하여 iOS 및 Android 앱으로 패키징하는 방법을 안내합니다. Capacitor 8.

이 튜토리얼을 마치면 시뮬레이터에서 작동하는 모바일 앱을 만들 수 있으며, 개발을 계속하고 나중에는 앱 스토어와 구글 플레이에 게시할 수 있습니다.

시간 소요량: ~30분

생성할 프로젝트:

  • 새로운 Nuxt 4 프로젝트와 최신 디렉토리 구조
  • 모바일용 정적 생성 설정
  • Capacitor 8에 필수 플러그인
  • 네이티브 iOS 및 Android 앱
  • 라이브 리로드 개발 설정

이미 Nuxt 앱이 있으신가요? Nuxt 앱을 모바일로 변환 대신

사전 요구 사항

이러한 것을 설치했는지 확인하세요:

  • Node.js 18+ (__CAPGO_KEEP_0__에서 확인하세요) node --version)
  • Bun (package manager에서)curl -fsSL https://bun.sh/install | bash)
  • Xcode (macOS만, iOS 개발을 위해)
  • Android Studio (Android 개발을 위해)

Step 1: 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 사이의 분리를 더 잘 제공합니다.

Step 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',
  },
});

Step 3: 모바일 스크립트 추가하기

__CAPGO_KEEP_0__을 업데이트하여 모바일 개발 스크립트를 추가하세요: 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

Step 4: __CAPGO_KEEP_0__ 8 설치하기 .output/public __CAPGO_KEEP_0__

Capacitor

Capgo Capacitor core 패키지를 설치하세요:

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 — 네이티브 스플래시 스크린을 제어하는 @__CAPGO_KEEP_0__/splash-screen
  • — 디바이스 상태 바 스타일을 제어하는 @capacitor/status-bar — 사용자 환경 설정을 제어하는 @__CAPGO_KEEP_0__/preferences
  • @capacitor/status-bar — 키보드 동작을 제어하는 @__CAPGO_KEEP_0__/keyboard
  • — 네이티브 스플래시 스크린을 제어하는 @capacitor/splash-screen — Native localStorage (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

이것은 iosandroid 자연 프로젝트가 포함된 디렉토리

7단계: 빌드 및 실행

프로젝트를 빌드하고 네이티브 플랫폼과 동기화하세요:

bun run mobile

iOS 시뮬레이터에서 열기:

bun run mobile:ios

또는 Android 에뮬레이터에서 열기:

bun run mobile:android

Xcode (iOS)에서:

  1. 디바이스 드롭다운에서 시뮬레이터를 선택하세요
  2. Play 버튼을 클릭하거나 Cmd + R

Android Studio에서:

  1. Gradle이 동기화 완료되기를 기다리세요
  2. 디바이스 드롭다운에서 에뮬레이터를 선택하세요
  3. 버튼을 클릭하거나 Shift + F10

8단계: 라이브 리로드 설정

빠른 개발을 위해 라이브 리로드를 활성화하여 장치에서 즉시 변경 사항이 나타나도록 하세요.

  1. 장치 IP 주소를 찾으세요:
# macOS
ipconfig getifaddr en0

# Windows
ipconfig
  1. 개발 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;
  1. 개발 서버를 시작하고 네이티브로 설정을 복사하세요:
bun run dev &
NODE_ENV=development bunx cap copy
  1. 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 추가

For styling to work, add Tailwind CSS to your project:

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단계: 공유 플러그인 추가하기

공유 버튼 기능을 구현하기 위해:

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 and rebuild:

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 / native cloud build product page. Role: Short UI label or navigation item. Message key `native_build_builder_credit_next` (Native Build Builder Credit Next). 다음 단계를 진행하세요.

기본 설정

  • 앱 아이콘: 기본 아이콘을 ios/App/App/Assets.xcassetsandroid/app/src/main/res
  • 스플래시 화면: 자연스럽게 프로젝트에서 커스터마이즈하거나 @capacitor/splash-screen config
  • 깊이 있는 링크: 앱 URL 스키마를 구성하십시오

추가 기능 추가

  • 카메라: bun add @capacitor/camera
  • 위치 정보: bun add @capacitor/geolocation
  • 푸시 알림: bun add @capacitor/push-notifications 또는 @capgo/capacitor-firebase-messaging Capacitor live-update alternatives 비교 페이지에서
  • Capawesome 비교 페이지에서 bun add @capacitor/filesystem

컨설팅 서비스 페이지에서

Use Capgo plugins instead of Konsta UI for a native mobile feel:

bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync

자연스러운 UI 및 전환 효과를 위해 __CAPGO_KEEP_0__ 플러그인을 사용하세요: Konsta UI 대신에 native mobile feel을 위해 __CAPGO_KEEP_0__ 플러그인을 사용하세요: @__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-native-navigation — Liquid Glass 탭바와 native navbar을 사용하세요: @__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-transitions — native-feeling 페이지 전환 효과를 사용하세요: For Tailwind safe areas, add @capgo/tailwind-capacitor:

bun add -D tailwind-capacitor

보기 Using @capgo/capacitor-native-navigation, Using @capgo/capacitor-transitions, 그리고 tailwind-capacitor repo Nuxt-specific 설정을 위한

iOS 레이아웃 문제를 해결하는 방법 (뷰포트, Safe Area, 및 수평 스크롤)

iOS에서 콘텐츠가 잘린 것처럼 보이거나 shift된 것처럼 보이거나 수평 스크롤이 가능하다면, 더 많은 overflow-x: hidden 또는 뷰포트 태그를 조정하는 것만으로는 문제를 해결할 수 없다. 이러한 체크를 순서대로 진행하십시오.

뷰포트 메타 태그가 올바르게 적용되어 있는지 확인하십시오

In nuxt.config.tsviewport를 설정하세요. app.head:

export default defineNuxtConfig({
  app: {
    head: {
      meta: [
        {
          name: 'viewport',
          content: 'width=device-width, initial-scale=1, viewport-fit=cover',
        },
      ],
    },
  },
});

iOS safe area를 한 번에 root 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가 잘려나거나 너무 크게 보이는 문제를 해결하세요.

@__CAPGO_KEEP_0__/tailwind-__CAPGO_KEEP_1__와 함께 사용하면, 같은 패딩을 표현할 수 있습니다. @capgo/tailwind-capacitor__CAPGO_KEEP_0__ iOS를 pt-safe pb-safe px-safe context

Set Capacitor iOS contentInset live_update_dynamic_label_to never first

In capacitor.config.ts, native inset을 사용하고 CSS (또는 Native Navigation의 )가 safe area를 관리하도록 해보세요: contentInsetMode: 'css'Mixing __CAPGO_KEEP_0__의 자동 콘텐츠 inset과 CSS padding은 일반적인 double spacing의 원인이 됩니다.

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를 사용하는 요소, fixed pixel width를 사용하는 요소, 또는 큰

Safari Web Inspector에서 실행하세요:

Tailwind를 사용하면 100vwwith w-screenwith min-width.

with

[...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,
  }));

with w-screen with w-full 가능한 경우에. 많은 수평 방향으로 넘치는 문제는 duplicated safe-area padding, 또는 고정 너비 컨테이너에서 오는 것이 아니라 viewport meta tag 자체에서 오는 것이 아니다. 100vw / w-screen오버 더 에어 업데이트

설정

__CAPGO_KEEP_0__ Capgo 문제 해결

bunx @capgo/cli init

설정

Build가 "Cannot find module"로 실패합니다. 설정 bun install 다시 시도해 보세요.

iOS: "No signing identity found" Xcode를 열고 Signing &amp; Capabilities로 이동하여 개발 팀을 선택하세요.

안드로이드: “SDK 위치를 찾을 수 없음” 생성 android/local.propertiessdk.dir=/path/to/android/sdk

장치에 나타나지 않는 변경 사항 변경 사항이 나타나도록 하려면 bun run mobile live reload를 위해 IP 주소가 정확하고 개발 서버가 실행 중인지 확인하세요.

.output/public이 빈 폴더거나 없을 경우 변경 사항이 반영되지 않습니다. nitro: { preset: 'static' } 변경 사항을 반영하려면 nuxt.config.ts 를 확인하고 실행하세요. bun run generate.

리소스

앱을 배달하기 위해 준비되셨나요? Capgo을 사용하여 업데이트를 더 빠르게 배달하는 방법을 배워보세요 — 무료 계정으로 가입하세요 오늘.

Build a Nuxt Mobile App from Scratch with Capacitor 8

만약에 __CAPGO_KEEP_0__을 사용하고 있다면 Build a Nuxt Mobile App from Scratch with Capacitor 8 CI/CD 자동화 계획을 만들기 위해 __CAPGO_KEEP_0__을 사용하고 있다면 Capgo CI/CD Capgo CI/CD를 위한 제품 워크플로우 Capgo 네이티브 빌드 Capgo 네이티브 빌드를 위한 제품 워크플로우 Capgo 통합 Capgo 통합을 위한 제품 워크플로우 CI/CD 통합 __CAPGO_KEEP_0__ 액션 통합 GitHub 액션 통합을 위한 구현 세부 정보 GitHub 액션 통합을 위한 구현 세부 정보

Capacitor 앱에 대한 실시간 업데이트

웹-layer 버그가 활성화된 경우, 앱 스토어 승인 대기 없이 Capgo를 통해 픽스를 배포하세요. 사용자는 배경에서 업데이트를 받으며 네이티브 변경 사항은 일반적인 검토 경로에 남아 있습니다.

마틴의 인간 지원

시작하기

최신 블로그 뉴스

Capgo은 전문적인 모바일 앱을 만들기 위해 필요한 최고의 통찰력을 제공합니다.