Lompat ke konten utama
Tutorial

Membangun Aplikasi Mobile Nuxt dari Awal dengan Capacitor 8

Petunjuk 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 pertama.

Martin Donadieu

Martin Donadieu

Spesialis Konten

Membangun Aplikasi Mobile Nuxt dari Awal dengan Capacitor 8

Selamat Datang

Apakah Anda ingin membangun aplikasi seluler dengan Nuxt dari awal? Panduan ini akan mengajak Anda membuat proyek Nuxt 4 baru yang sudah terkonfigurasi untuk seluler sejak hari pertama, kemudian mengemasnya sebagai aplikasi iOS dan Android asli menggunakan Capacitor 8.

Dengan menyelesaikan tutorial ini, Anda akan memiliki aplikasi seluler yang berjalan dengan baik di simulator yang dapat Anda lanjutkan mengembangkan dan akhirnya menerbitkan di App Store dan Google Play.

Waktu yang dibutuhkan: ~30 menit

Apa yang akan dibangun:

  • Proyek Nuxt 4 baru dengan struktur direktori terbaru
  • Konfigurasi penghasilan statis untuk seluler
  • Capacitor 8 dengan plugin yang penting
  • Aplikasi iOS dan Android asli
  • Pengaturan pengembangan dengan reload hidup

Sudah memiliki aplikasi Nuxt? Cek Konversi Aplikasi Nuxt ke Mobile sebaliknya.

Prasyarat

Pastikan Anda telah menginstal hal-hal berikut:

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

Langkah 1: Buat Proyek Nuxt 4 Baru

Mulai dengan membuat proyek Nuxt 4 segar:

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

Struktur Direktori Nuxt 4

Nuxt 4 menggunakan struktur direktori baru dengan app code di direktori: app/ Struktur ini menyediakan pemisahan yang lebih baik antara aplikasi dan server __CAPGO_KEEP_0__.

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.

__CAPGO_KEEP_0__ memerlukan file HTML/JS/CSS statis. Konfigurasi Nuxt untuk pengembangan statik di

Capacitor requires static HTML/JS/CSS files. Configure Nuxt for static generation in nuxt.config.ts:

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

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

Perbarui

dengan skrip pengembangan mobile: package.json __CAPGO_KEEP_0__

{
  "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 generasi statik:

bun run generate

Anda harus melihat sebuah .output/public direktori dengan file-file statik Anda.

Langkah 4: Pasang Capacitor 8

Pasang paket-paket inti Capacitor:

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

Pasang plugin-plugin yang paling penting bagi aplikasi mobile:

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

Apa yang dilakukan plugin-plugin ini:

  • @capacitor/app — Acara kehidupan aplikasi (dalam latar depan/belakang, tautan dalam)
  • @capacitor/keyboard — Mengontrol perilaku kibor
  • @capacitor/splash-screen — Kontrol layar splash native
  • @capacitor/status-bar — Gaya layar 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 layar aplikasi Anda
  • com.example.mymobileapp dengan ID aplikasi Anda (notasi domain terbalik)

Hal ini menciptakan capacitor.config.ts. Perbarui 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 Asli

Pasang paket platform:

bun add @capacitor/ios @capacitor/android

Buat proyek native:

bunx cap add ios
bunx cap add android

Hal ini menciptakan ios dan android 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

Di Xcode (iOS):

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

Dalam Android Studio:

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

Langkah 8: Atur Ulang Reload Hidup

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

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

# Windows
ipconfig
  1. Buat konfigurasi pengembangan Capacitor. Perbarui 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 edit pada Nuxt code akan reload panas di perangkat.

Langkah 9: Buat Layar Seluler Pertama Anda

Buatlah layar utama yang ramah seluler. Perbarui 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: Tambahkan 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 Bagikan

Implementasikan fungsi tombol bagikan:

bun add @capacitor/share

Perbarui app/pages/index.vue Untuk menggunakan plugin Bagikan:

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

Sinkronkan dan bangun ulang:

bun run mobile

Struktur Proyek

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

Langkah-Langkah Selanjutnya

Anda telah memiliki aplikasi mobile Nuxt yang berfungsi. Berikut adalah langkah-langkah yang perlu Anda lakukan:

Pengaturan Dasar

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

Tambahkan Fitur Lebih Banyak

  • Kamera: bun add @capacitor/camera
  • Lokasi: bun add @capacitor/geolocation
  • Pemberitahuan 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

UI dan Transisi Asli

Gunakan plugin Capgo yang lebih baik daripada Konsta UI untuk merasakan sentuhan mobile asli:

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

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

bun add -D tailwind-capacitor

Lihat Menggunakan @capgo/capacitor-native-navigation, Menggunakan @capgo/capacitor-transisi, dan repo tailwind-capacitor untuk pengaturan spesifik Nuxt.

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

If konten terlihat dipotong, bergeser, atau dapat di-scroll secara horizontal pada iOS, menambahkan lebih banyak atau mengatur tag viewport saja biasanya tidak dapat memperbaikinya. Kerjakan periksaan-periksaan ini secara berurutan. overflow-x: hidden Pastikan tag meta viewport diterapkan dengan benar

Pada

tetapkan viewport melalui nuxt.config.tsHandle area aman iOS dari satu wrapper root saja app.head:

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

Buatlah shell aplikasi tunggal dan terapkan padding area aman di sana — bukan di komponen-komponen nested yang berbeda-beda:

Wrap semua konten halaman di dalam

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

Penggunaan padding area aman yang berulang di header, modal, dan wrapper layout sering membuat UI terlihat dipotong atau terlalu besar. .app-shellDengan

@__CAPGO_KEEP_0__/tailwind-__CAPGO_KEEP_1__ @capgo/tailwind-capacitor, you can express the same padding with utilities like pt-safe pb-safe px-safe di shell tunggal itu.

Atur Capacitor iOS contentInset ke never pertama

Di capacitor.config.ts, lebih prefer inset native disabled dan biarkan CSS (atau Navigasi Native’s contentInsetMode: 'css') menguasai area 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 double spacing.

Temukan elemen yang benar-benar mengalami overflows

Biasanya, penjahat adalah elemen yang menggunakan 100vw, Tailwind w-screenatau lebar piksel tetap, atau besar 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-screenduplikasi padding area aman, atau kontainer lebar tetap — bukan dari tag meta viewport itu sendiri.

Pembaruan Langsung Melalui Jaringan

Konfigurasi Capgo untuk memasang pembaruan tanpa perlu resubmit aplikasi di toko:

bunx @capgo/cli init

Pengaturan Masalah

Build gagal dengan “Cannot find module” Jalankan dan coba lagi. bun install iOS: “Tidak ada identitas tanda tangan ditemukan”

Buka Xcode, pergi ke Signing &amp; Capabilities, dan pilih tim pengembangan Anda. Android: “__CAPGO_KEEP_0__ lokasi tidak ditemukan”

Android: “SDK location not found” dengan android/local.properties Perubahan tidak muncul di perangkat sdk.dir=/path/to/android/sdk

Pastikan Anda menjalankan setelah membuat perubahan. Untuk live reload, verifikasi alamat IP yang benar dan server dev berjalan. bun run mobile .output/public kosong atau hilang

Pastikan Anda telah mengonfigurasi __CAPGO_KEEP_0__ nitro: { preset: 'static' } Bahasa Indonesia nuxt.config.ts dan jalankan bun run generate.

Sumber Daya

Siap untuk mengirimkan aplikasi Anda? Pelajari bagaimana Capgo dapat membantu Anda mengirimkan update 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 Otomatisasi CI/CD untuk alur kerja produk di Capgo Otomatisasi CI/CD, Capgo Pembangunan Native untuk alur kerja produk di Capgo Pembangunan Native, Capgo Integrasi untuk alur kerja produk di Capgo Integrasi, Integrasi CI/CD untuk detail implementasi di Integrasi CI/CD, dan Aksi Integrasi GitHub untuk detail implementasi di Aksi Integrasi GitHub

Pembaruan Langsung untuk Aplikasi Capacitor

Ketika bug layer web masih aktif, kirimkan perbaikan melalui Capgo daripada menunggu hari-hari untuk persetujuan toko aplikasi.

Mulai Sekarang

Terbaru dari Blog Kami

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