Pendahuluan
Ingin membangun aplikasi mobile dengan Nuxt dari dasar? Panduan ini akan membawa Anda melalui membuat proyek Nuxt 4 baru yang sudah terkonfigurasi untuk mobile dari hari pertama, kemudian mengemasnya sebagai aplikasi mobile native iOS dan Android menggunakan Capacitor 8.
Setelah menyelesaikan tutorial ini, Anda akan memiliki aplikasi mobile yang berjalan dengan baik di 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 penghasilan statis untuk mobile
- Capacitor 8 dengan plugin yang penting
- Aplikasi iOS dan Android native
- Pengaturan pengembangan live reload
Sudah memiliki aplikasi Nuxt? Cek Konversi Aplikasi Nuxt Anda ke Mobile sebaliknya.
Prasyarat
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 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 aplikasi code di app/ direktori:
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-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
Perbarui 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 direktori dengan file-file statis 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 umum digunakan oleh 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 — Mengontrol layar splash native
- @capacitor/status-bar — Mengatur warna bar status perangkat
- @capacitor/preferences — Penyimpanan nilai kunci (seperti localStorage tetapi asli)
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 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 asli:
bunx cap add ios
bunx cap add android
Ini menciptakan ios dan direktori yang berisi proyek native. android Step 7: Bangun dan Jalankan
Bangun proyek Anda dan sinkron dengan platform native:
Buka di Simulator iOS:
bun run mobile
Atau Emulator Android:
bun run mobile:ios
Di Xcode (iOS):
bun run mobile:android
Pilih simulator dari dropdown perangkat
- Klik tombol Play atau tekan
- Di Android Studio:
Cmd + R
Tunggu Gradle selesai sinkron
- Pilih emulator dari dropdown perangkat
- Tunggu beberapa saat sebelum melanjutkan
- Klik tombol Run atau tekan
Shift + F10
Langkah 8: Atur Ulang Reload Langsung
Untuk pengembangan yang lebih cepat, aktifkan reload langsung sehingga perubahan akan 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 edit pada Nuxt code Anda akan reload panas di perangkat.
Langkah 9: Buat Layar Mobile Pertama Anda
Mari kita buat layar home yang ramah mobile. 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 untuk 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 untuk menggunakan plugin 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>
Sinkron 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 Selanjutnya
Anda telah memiliki aplikasi mobile Nuxt yang berfungsi. Berikut adalah langkah-langkah selanjutnya:
Konfigurasi Dasar
- Ikon Aplikasi: Ganti ikon default di
ios/App/App/Assets.xcassetsdanandroid/app/src/main/res - Layar Splash: Tentukan sendiri di proyek native atau gunakan
@capacitor/splash-screenkonfigurasi - Tautan dalam Negeri: Konfigurasi skema URL untuk aplikasi Anda
Tambahkan Fitur Lainnya
- Kamera:
bun add @capacitor/camera - Lokasi:
bun add @capacitor/geolocation - Notifikasi Push:
bun add @capacitor/push-notificationsatau @capgo/capacitor-firebase-messaging untuk Firebase Cloud Messaging pada iOS dan Android - Sistem File:
bun add @capacitor/filesystem
Antarmuka Native dan transisi
Gunakan plugin Capgo alih-alih Konsta UI untuk merasakan perangkat mobile yang asli:
- @capgo/capacitor-native-navigation — tab bar Liquid Glass dan navbar native
- @capgo/capacitor-transitions — transisi halaman yang merasa 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-transitions, dan repo tailwind-capacitor untuk pengaturan Nuxt khusus.
Mengatasi Masalah Tampilan iOS (Viewport, Area Aman, dan Horizontal Overflow)
Jika konten terlihat dipotong, bergeser, atau dapat di-scroll secara horizontal di iOS, menambahkan lebih banyak overflow-x: hidden atau mengatur tag viewport saja biasanya tidak dapat memperbaikinya. Kerjakan periksaan-periksaan ini secara berurutan.
Pastikan tag meta viewport telah diterapkan dengan benar
Di 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',
},
],
},
},
});
Tangani zona aman iOS dari satu wrapper root saja
Buat sebuah shell aplikasi tunggal dan aplikasikan padding zona aman di sana — bukan di komponen nested yang banyak:
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);
}
Bungkus semua konten halaman di dalam .app-shellPengaturan padding zona aman yang berulang di header, modal, dan wrapper tata letak sering membuat UI terlihat dipotong atau terlalu besar.
Dengan @capgo/tailwind-capacitor, Anda dapat menyampaikan padding yang sama dengan utilitas seperti pt-safe pb-safe px-safe di shell tunggal tersebut.
Set Capacitor iOS contentInset ke never pertama
Ini, prefer native inset disabled dan biarkan CSS (atau Native Navigation's) menguasai area yang aman: capacitor.config.tsMenggabungkan __CAPGO_KEEP_0__’s automatic content inset dengan CSS padding adalah penyebab umum dari jarak ganda. contentInsetMode: 'css'Temukan elemen yang benar-benar mengalami overflows
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
, lebar piksel tetap, atau besar
Dalam Safari Web Inspector, jalankan: 100vwDengan Tailwind, ganti w-screendengan min-width.
Ini, prefer native inset disabled dan biarkan CSS (atau Native Navigation's) menguasai area yang aman:
[...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,
}));
Menggabungkan __CAPGO_KEEP_0__’s automatic content inset dengan CSS padding adalah penyebab umum dari jarak ganda. w-screen Temukan elemen yang benar-benar mengalami overflows: Penyebab biasanya adalah elemen yang menggunakan Tailwind, lebar piksel tetap, atau besar. Dalam Safari Web Inspector, jalankan: With Tailwind, ganti "with" w-full When memungkinkan. Banyak masalah overflow horizontal berasal dari 100vw / w-screen, padding area aman yang diulang, atau kontainer lebar tetap — bukan dari tag meta viewport itu sendiri.
Pembaruan Langsung Melalui Jaringan
Konfigurasi Capgo untuk memasukkan pembaruan tanpa harus mengirimkan aplikasi ke toko aplikasi lagi:
bunx @capgo/cli init
Pengaturan
Pembaruan Langsung Melalui Jaringan
Set up bun install untuk memasukkan pembaruan tanpa harus mengirimkan aplikasi ke toko aplikasi lagi.
Pengaturan Pengaturan Masalah
Android: “Lokasi SDK tidak ditemukan”
Buat android/local.properties dengan sdk.dir=/path/to/android/sdk
Pembaharuan tidak muncul di perangkat
Pastikan Anda menjalankan bun run mobile setelah membuat perubahan. Untuk pengisian ulang hidup, verifikasi alamat IP yang benar dan server pengembang sedang berjalan.
.output/public kosong atau hilang
Pastikan Anda mengonfigurasi nitro: { preset: 'static' } dalam nuxt.config.ts dan jalankan bun run generate.
Sumber Daya
- Capacitor Dokumentasi 8
- Dokumentasi Nuxt 4
- Capgo - Update Langganan 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 Nuxt Mobile dari Awal dengan Capacitor 8
Jika Anda menggunakan Membangun Aplikasi Nuxt Mobile dari Awal dengan Capacitor 8 untuk merencanakan otomatisasi CI/CD, hubungkannya dengan Capgo Pengaturan CI/CD untuk alur kerja produk di Capgo Pengaturan CI/CD, Capgo Pembangunan Nativ untuk alur kerja produk di Capgo Pembangunan Nativ, Capgo Integrasi untuk alur kerja produk di Capgo Integrasi, Integrasi CI/CD untuk detail implementasi di Integrasi CI/CD, dan GitHub Integrasi Aksi untuk detail implementasi di GitHub Integrasi Aksi.