Introduction
Apakah Anda ingin membuat aplikasi mobile dengan Nuxt dari awal? Panduan ini akan membantu Anda membuat proyek Nuxt 4 baru yang sudah terkonfigurasi untuk mobile sejak awal, kemudian mengemasnya sebagai aplikasi native iOS dan Android menggunakan Capacitor 8.
Setelah menyelesaikan tutorial ini, Anda akan memiliki aplikasi mobile yang berjalan pada simulator yang dapat Anda lanjutkan mengembangkan dan akhirnya menerbitkan ke App Store dan Google Play.
Waktu yang dibutuhkan: ~30 menit
Apa yang akan dibangun:
- Proyek Nuxt 4 baru dengan struktur direktori terbaru
- Konfigurasi pengembangan statis untuk mobile
- Capacitor 8 with essential plugins
- Aplikasi native iOS dan Android
- Pengaturan pengembangan dengan live reload
Udah punya aplikasi Nuxt? Cek Migrasi Aplikasi Nuxt Anda ke Mobile sebaliknya.
Persyaratan
Pastikan Anda telah menginstal hal-hal berikut:
- Node.js 18+ (cek dengan
node --version) - Bun manajer paket (
curl -fsSL https://bun.sh/install | bash) - Xcode (hanya untuk macOS, untuk pengembangan iOS)
- Android Studio (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:
Dengan __CAPGO_KEEP_0__ package.json Dengan __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 statis:
bun run generate
Kamu harus melihat sebuah .output/public direktori dengan file-file statis kamu.
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 untuk 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 (depan/belakang, tautan dalam)
- @capacitor/keyboard — Mengontrol perilaku keyboard
- @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 Andacom.example.mymobileappdengan ID aplikasi Anda (notasi domain terbalik)
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
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 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
Dalam Xcode (iOS):
- Pilih simulator dari dropdown perangkat
- Klik tombol Play atau tekan
Cmd + R
Ini cara kerja Android Studio:
- Tunggu Gradle selesai sinkronisasi
- Pilih emulator dari dropdown perangkat
- Klik tombol Run atau tekan
Shift + F10
Langkah 8: Atur Ulang Reload Hidup
Untuk pengembangan yang lebih cepat, aktifkan reload hidup sehingga perubahan muncul secara instan di perangkat Anda.
- Cari alamat IP lokal Anda:
# macOS
ipconfig getifaddr en0
# Windows
ipconfig
- Buat konfigurasi pengembangan Capacitor Anda. 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;
- Mulai server pengembangan dan salin konfigurasi ke native:
bun run dev &
NODE_ENV=development bunx cap copy
- Rebuild di Xcode/Android Studio
Sekarang perubahan pada Nuxt code Anda akan reload secara otomatis 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
Buat 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()],
},
});
Langkah 11: Tambahkan Plugin Berbagi 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;
}
Buatlah fungsi tombol berbagi:
Buat untuk menggunakan plugin Berbagi:
bun add @capacitor/share
Sinkronkan dan bangun ulang: app/pages/index.vue Langkah 12: Tambahkan Capacitor untuk Nuxt Mobile App
<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>
Buatlah aplikasi seluler Nuxt yang menggunakan Capacitor:
bun run mobile
Struktur Proyek
Proyek Anda seharusnya 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 Selanjutnya
Kamu telah memiliki aplikasi mobile Nuxt yang berfungsi. Berikut langkah-langkah yang perlu kamu lakukan:
Pengaturan Dasar
- Ikon Aplikasi: Ganti ikon default di
ios/App/App/Assets.xcassetsdanandroid/app/src/main/res - Layar Splash: Customisasi di proyek native atau gunakan
@capacitor/splash-screenKonfigurasi - Tautan dalam Nada Dasar: Konfigurasi Schemes URL untuk aplikasi Anda
Tambahkan Fitur Lebih Banyak
- Kamera:
bun add @capacitor/camera - Geolokasi:
bun add @capacitor/geolocation - Pemberitahuan Push:
bun add @capacitor/push-notificationsatau @capgo/capacitor-firebase-messaging __CAPGO_KEEP_0__/__CAPGO_KEEP_1__-firebase-messaging - untuk Firebase Cloud Messaging pada iOS dan Android
bun add @capacitor/filesystem
Sistem File:
Use Capgo plugins instead of Konsta UI for a native mobile feel:
- Pilih plugin capgo yang lebih baik daripada Konsta UI untuk merasakan pengalaman mobile asli: capgo/capacitor-native-navigation --- Tab Bar Glas Liquid dan navbar native ---
- @capgo/capacitor-transisi --- transisi halaman yang terasa 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-navigasi native, Menggunakan @capgo/capacitor-transisi, dan repo tailwind-capacitor untuk pengaturan spesifik Nuxt.
Pengaturan Layout iOS (Viewport, Daerah Aman, dan Overflows Horizontal)
Jika konten terlihat dipotong, bergeser, atau dapat di-scroll ke kanan pada iOS, menambahkan lebih banyak overflow-x: hidden atau mengatur tag viewport saja biasanya tidak dapat memperbaikinya. Jalankan periksaan-periksaan ini secara berurutan.
Pastikan tag meta viewport diterapkan dengan benar
Di nuxt.config.ts, atur viewport melalui app.head:
export default defineNuxtConfig({
app: {
head: {
meta: [
{
name: 'viewport',
content: 'width=device-width, initial-scale=1, viewport-fit=cover',
},
],
},
},
});
Pengaturan area aman iOS hanya dapat dilakukan dari satu wrapper root saja
Buatlah shell aplikasi tunggal dan aplikasikan padding area aman di sana — bukan di komponen-komponen nested yang berbeda:
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);
}
Selimuti semua konten halaman di dalam .app-shellPenambahan padding area aman yang sama di header, modal, dan wrapper layout sering membuat UI terlihat dipotong atau terlalu besar.
Dengan @capgo/tailwind-capacitorkamu dapat mengungkapkan padding yang sama dengan utilitas seperti pt-safe pb-safe px-safe di atas satu shell.
Atur Capacitor iOS contentInset ke never pertama
Di capacitor.config.ts, lebih baik menggunakan inset asli yang dinonaktifkan dan biarkan CSS (atau Native Navigation's) contentInsetMode: 'css') mengendalikan 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 sebenarnya mengalami kelebihan.
Biasanya, penyebabnya 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 yang aman, atau kontainer lebar piksel — bukan dari tag meta viewport itu sendiri.
Pembaruan Langsung Melalui Jaringan
Konfigurasi Capgo Pembaruan Langsung Melalui Jaringan tanpa Harus Mengirimkan Aplikasi ke Toko Aplikasi:
bunx @capgo/cli init
Penyelesaian Masalah
Build gagal dengan "Cannot find module"
Jalankan bun install dan coba lagi.
iOS: “Tidak ditemukan identitas tanda tangan” Buka Xcode, pergi ke Signing & Capabilities, dan pilih tim pengembangan Anda.
Android: “SDK lokasi 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 live reload, verifikasi alamat IP yang benar dan server pengembangan berjalan.
.output/public kosong atau hilang
Pastikan Anda mengonfigurasi nitro: { preset: 'static' } di nuxt.config.ts dan jalankan bun run generate.
Sumber Daya
- Capacitor 8 Dokumentasi
- Dokumentasi Nuxt 4
- Capgo - Update Hidup
- @capgo/capacitor-navigasi native
- @capgo/capacitor-transisi
- @capgo/tailwind-capacitor
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 Bangun Nativ untuk alur kerja produk di Capgo Bangun Nativ, 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.