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 Andacom.example.mymobileappdengan 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):
- Pilih simulator dari dropdown perangkat
- Klik tombol Putar atau tekan
Cmd + R
Dalam Android Studio:
- Tunggu Gradle selesai sinkronisasi
- Pilih emulator dari dropdown perangkat
- 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.
- Temukan alamat IP lokal Anda:
# macOS
ipconfig getifaddr en0
# Windows
ipconfig
- 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;
- Mulai server pengembangan dan salin konfigurasi ke native:
bun run dev &
NODE_ENV=development bunx cap copy
- 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.xcassetsdanandroid/app/src/main/res - Layar Splash: Customize di proyek native atau gunakan
@capacitor/splash-screenkonfigurasi - 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-notificationsatau @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:
- @capgo/capacitor-native-navigation — Baja Kaca tab bar dan navbar asli
- @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-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 & 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
- 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 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