Pindah ke konten utama
Tutorial

Bangun Aplikasi Nuxt Mobile dari Awal dengan Capacitor 8

Langkah demi langkah untuk membuat proyek Nuxt 4 baru dan mengubahnya menjadi aplikasi mobile native iOS dan Android menggunakan Capacitor 8. Ideal untuk memulai dari awal dengan pengembangan Vue mobile-first.

Kredit artikel

Martin Donadieu

Pengarang

Valeria

Pengulas

Jordan

Pengedit

Buat Aplikasi Mobile Nuxt dari Awal dengan Capacitor 8

Pendahuluan

Want to build a mobile app with Nuxt from the ground up? This guide walks you through creating a brand new Nuxt 4 project configured for mobile from day one, then packaging it as native iOS and Android apps using Capacitor 8.

By the end of this tutorial, you’ll have a working mobile app running on simulators that you can continue developing and eventually publish to the App Store and Google Play.

Waktu yang dibutuhkan: sekitar 30 menit

Apa yang akan dibangun:

  • Proyek Nuxt 4 baru dengan struktur direktori terbaru
  • Konfigurasi pengembangan statis untuk mobile
  • Capacitor 8 dengan plugin penting
  • Aplikasi native iOS dan Android
  • Pengaturan pengembangan reload langsung

Sudah memiliki aplikasi Nuxt? Cek Mengubah Aplikasi Nuxt Anda ke Mobile sebaliknya.

Prerequisites

Pastikan Anda telah menginstal hal-hal berikut:

  • Node.js 18+ (periksa dengan node --version)
  • Bun pengelola paket (curl -fsSL https://bun.sh/install | bash)
  • Xcode (hanya macOS, untuk pengembangan iOS)
  • Studio Android (untuk pengembangan Android)

Langkah 1: Buat Projek Nuxt 4 Baru

Mulai dengan membuat proyek Nuxt 4 yang segar:

bunx nuxi@latest init my-mobile-app
cd my-mobile-app
bun install

Mulai dengan membuat projek Nuxt 4 segar:

Nuxt 4 menggunakan struktur direktori baru dengan aplikasi code di app/ directory:

my-mobile-app/
  app/
    assets/
    components/
    composables/
    layouts/
    middleware/
    pages/
    plugins/
    utils/
    app.vue
  public/
  server/
  nuxt.config.ts
  package.json

Struktur ini menyediakan pemisahan yang lebih baik antara aplikasi dan server code.

Langkah 2: Konfigurasi Nuxt untuk Pengembangan Statik

Capacitor memerlukan file HTML/JS/CSS statis. Konfigurasi Nuxt untuk pengembangan statik di nuxt.config.ts:

export default defineNuxtConfig({
  compatibilityDate: '2025-01-15',
  devtools: { enabled: true },

  // Enable static generation
  ssr: true,
  nitro: {
    preset: 'static',
  },
});

Langkah 3: Tambahkan Skrip Mobile

Update Anda package.json dengan skrip pengembangan mobile:

{
  "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"
  }
}

Tes pengembangan statik:

bun run generate

Anda seharusnya melihat sebuah .output/public directory dengan file statis Anda.

Langkah 4: Pasang Capacitor 8

Pasang paket-paket inti Capacitor:

bun add @capacitor/core
bun add -D @capacitor/cli

Instal plugin penting yang biasanya dibutuhkan oleh aplikasi mobile:

bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/status-bar @capacitor/preferences

Apa saja yang dilakukan oleh plugin ini:

  • /@capacitor/aplikasi — Event siklus aplikasi (depan/belakang, tautan dalam)
  • @capacitor/keyboard — Mengontrol perilaku keyboard
  • @capacitor/splash-screen — Mengontrol layar splash native
  • @capacitor/status-bar — Mengatur tampilan status perangkat
  • @capacitor/preferences — Penyimpanan nilai kunci (seperti localStorage tetapi native)

Langkah 5: Inisialisasi Capacitor

Inisialisasi Capacitor dengan detail proyek Anda:

bunx cap init "My Mobile App" com.example.mymobileapp --web-dir .output/public

Ganti:

  • "My Mobile App" dengan nama tampilan aplikasi Anda
  • com.example.mymobileapp dengan ID aplikasi (notasi domain terbalik)

Ini menciptakan capacitor.config.tsPerbarui dengan konfigurasi plugin:

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;

Langkah 6: Tambahkan Platform Nativ

Instal paket platform:

bun add @capacitor/ios @capacitor/android

Membuat proyek native:

bunx cap add ios
bunx cap add android

Ini menciptakan ios dan android daftar direktori yang berisi proyek native.

Langkah 7: Bangun dan Jalankan

Bangun proyek Anda dan sinkron dengan platform native:

bun run mobile

Buka di Simulator iOS:

bun run mobile:ios

Atau Emulator Android:

bun run mobile:android

Pada Xcode (iOS):

  1. Pilih simulator dari dropdown perangkat
  2. Klik tombol Bermain atau tekan Cmd + R

Pada Android Studio:

  1. Tunggu Gradle selesai sinkron
  2. Pilih emulator dari dropdown perangkat
  3. Klik tombol Jalankan atau tekan Shift + F10

Langkah 8: Atur Ulang Hidup

Untuk pengembangan yang lebih cepat, aktifkan ulang hidup agar perubahan muncul secara instan di perangkat Anda.

  1. Mencari alamat IP lokal Anda:
# macOS
ipconfig getifaddr en0

# Windows
ipconfig
  1. Buat konfigurasi pengembangan 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. Mulai server pengembangan dan salin konfigurasi ke native:
bun run dev &
NODE_ENV=development bunx cap copy
  1. Rebuild di Xcode/Android Studio

Sekarang perubahan pada Nuxt code akan memuat ulang secara otomatis di perangkat.

Langkah 9: Buat Layar Mobile Pertama

Buatlah layar home yang ramah mobile. app/app.vue:

<template>
  <NuxtPage />
</template>

Buat 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>

Langkah 10: Tambah Tailwind CSS

Untuk gaya yang berfungsi, tambahkan Tailwind CSS ke proyek Anda:

bun add tailwindcss @tailwindcss/vite

Perbarui 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()],
  },
});

Buat 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;
}

Langkah 11: Tambahkan Plugin Berbagi

Mari kita implementasikan fungsi tombol berbagi.

bun add @capacitor/share

Perbarui app/pages/index.vue Implementasikan fungsi tombol berbagi:

<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>

Untuk menggunakan plugin Berbagi:

bun run mobile

Sinkron dan bangun ulang:

Project Anda sekarang harus terlihat seperti ini:

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
└── ...

Next Steps

Sekarang Anda memiliki aplikasi seluler Nuxt yang berfungsi. Ini langkah selanjutnya:

Pengaturan Dasar

  • Ikon Aplikasi: Ganti ikon bawaan di ios/App/App/Assets.xcassets dan android/app/src/main/res
  • Layar Splash: Customisasi di proyek native atau gunakan @capacitor/splash-screen konfigurasi
  • Tautan Dalam: Konfigurasi skema URL untuk aplikasi Anda

Tambah Fitur Lebih

  • Kamera: bun add @capacitor/camera
  • Geolokasi: bun add @capacitor/geolocation
  • Notifikasi Push: bun add @capacitor/push-notifications atau @capgo/capacitor-firebase-messaging untuk Firebase Cloud Messaging pada iOS dan Android
  • Sistem File: bun add @capacitor/filesystem

Antarmuka UI dan transisi

Gunakan plugin Capgo sebaliknya Konsta UI untuk merasakan mobile native:

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

Untuk area aman Tailwind, tambahkan @capgo/tailwind-capacitor:

bun add -D tailwind-capacitor

Minta Menggunakan @capgo/capacitor-navigasi native, Menggunakan @capgo/capacitor-transisi, dan repo tailwind-capacitor untuk pengaturan Nuxt khusus. untuk pengaturan Nuxt khusus.

Mengatasi Masalah Tata Letak iOS (Viewport, Area Aman, dan Overflows Horizontal)

atau mengatur tag viewport saja biasanya tidak dapat memperbaikinya. Lakukan periksaan-periksaan ini secara berurutan. overflow-x: hidden Atur viewport tag saja biasanya tidak cukup untuk memperbaiki masalah ini. Jalankan periksaan-periksaan ini secara berurutan.

Pastikan tag meta viewport diterapkan dengan benar

In nuxt.config.tsAtur viewport melalui app.head:

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

Menangani area aman iOS dari wrapper root saja

Membuat shell aplikasi tunggal dan menerapkan padding area aman di sana — bukan di komponen nested beberapa kali:

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);
}

Mengapit semua konten halaman di dalam .app-shellDuplikasi padding area aman di header, modal, dan wrapper layout sering membuat UI terlihat dipotong atau terlalu besar.

Dengan @capgo/tailwind-capacitorkamu bisa mengekspresikan padding yang sama dengan utilitas seperti pt-safe pb-safe px-safe di shell tunggal itu.

Mengatur Capacitor iOS contentInset ke never first

pertama capacitor.config.tsprefer pengaturan native inset disabled dan biarkan CSS (atau Native Navigation's) contentInsetMode: 'css'milik area yang aman:

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: '.output/public',
  ios: {
    contentInset: 'never',
  },
};

Menggabungkan Capacitor's automatic content inset dengan CSS env(safe-area-inset-*) padding adalah penyebab umum dari jarak ganda.

Temukan elemen yang melebihi batas

Penyebab biasanya adalah elemen yang menggunakan 100vw, Tailwind w-screen, lebar piksel yang tetap, atau lebar yang sangat min-width.

In Safari Web Inspector, jalankan:

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

Dengan Tailwind, ganti w-screen dengan w-full ketika memungkinkan. Banyak masalah keluaran horizontal berasal dari 100vw / w-screenatau padding area yang aman, atau kontainer dengan lebar tetap — bukan dari tag meta viewport itu sendiri.

Update Melalui Jaringan

Konfigurasi Capgo untuk memasukkan pembaruan tanpa pengajuan ulang ke toko aplikasi:

bunx @capgo/cli init

Troubleshooting

Gagal membangun dengan "Tidak Dapat Menemukan Modul" Run bun install Coba lagi.

iOS: "Tidak Ditemukan Identitas Signing" Buka Xcode, pergi ke Signing &amp; Capabilities, dan pilih tim pengembangan Anda.

Android: "Lokasi SDK tidak ditemukan" Buat android/local.properties dengan sdk.dir=/path/to/android/sdk

Perubahan tidak muncul di perangkat Pastikan Anda menjalankan bun run mobile setelah membuat perubahan. Untuk reload hidup, verifikasi alamat IP yang benar dan server pengembang sedang berjalan.

.output/public kosong atau hilang Pastikan Anda mengonfigurasi nitro: { preset: 'static' } di nuxt.config.ts dan jalankan bun run generate.

Sumber Daya

Siap untuk mengirimkan aplikasi Anda? Pelajari cara Capgo membantu Anda mengirimkan pembaruan lebih cepat — daftar untuk akun gratis hari ini.

Teruskan dari Membangun Aplikasi Mobile Nuxt dari Awal dengan Capacitor 8

Jika Anda menggunakan Membangun Aplikasi Mobile Nuxt dari Awal dengan Capacitor 8 untuk merencanakan otomatisasi CI/CD, hubungkannya dengan Capgo CI/CD untuk alur kerja produk di Capgo CI/CD, Capgo Pembangunan Nativ untuk alur kerja produk di Capgo Pembangunan Nativ Integrasi Capgo untuk alur kerja produk di Capgo Integrations, untuk alur kerja produk di __CAPGO_KEEP_0__ Integrasi, untuk detail implementasi di Integrasi CI/CD, dan GitHub Actions Integration untuk detail implementasi di GitHub Integrasi Aksi.

Pembaruan Langsung untuk Aplikasi Capacitor

Ketika bug-layer web masih aktif, kirimkan perbaikan melalui Capgo daripada menunggu hari-hari untuk persetujuan toko aplikasi. Pengguna mendapatkan update di latar belakang sementara perubahan native tetap dalam jalur review normal.

Terbaru dari Blog kami

Capgo memberikan Anda wawasan terbaik yang Anda butuhkan untuk membuat aplikasi mobile yang profesional.