Lompat ke konten utama
Tutorial

Buat Aplikasi Mobile Next.js dari Awal dengan Capacitor 8

Petunjuk langkah demi langkah untuk membuat proyek Next.js 15 baru dan mengubahnya menjadi aplikasi mobile native iOS dan Android menggunakan Capacitor 8. Ideal untuk memulai dari awal dengan pengembangan mobile pertama.

Martin Donadieu

Martin Donadieu

Pengembang Konten

Buat Aplikasi Mobile Next.js dari Awal dengan Capacitor 8

Pendahuluan

Ingin membuat aplikasi mobile dengan Next.js dari awal? Panduan ini akan membawa Anda melalui proses membuat proyek Next.js 15 baru yang sudah terkonfigurasi untuk mobile sejak hari pertama, lalu 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 publikasikan ke App Store dan Google Play.

Waktu yang dibutuhkan: ~30 menit

Apa yang akan dibangun:

  • Proyek Next.js 15 baru dengan App Router
  • Konfigurasi ekspor statis untuk mobile
  • Capacitor 8 dengan plugin yang penting
  • Aplikasi iOS dan Android native
  • Pengaturan pengembangan live reload

Sudah memiliki aplikasi Next.js? Cek Ubah Aplikasi Next.js Anda 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 (untuk pengembangan Android)

Langkah 1: Buat Projek Next.js Baru

Mulai dengan membuat projek Next.js 15 segar:

bunx create-next-app@latest my-mobile-app

Mengapa Anda harus memilih opsi-opsi berikut:

  • Bahasa TypeScript: Ya (direkomendasikan)
  • Bahasa ESLint: Ya
  • Bahasa Tailwind CSS: Ya (direkomendasikan untuk gaya mobile)
  • src/ directory: Ya
  • App Router: Ya (direkomendasikan)
  • Import alias: Default (@/*)

Navigasikan ke proyek Anda:

cd my-mobile-app

Langkah 2: Konfigurasi Next.js untuk Export Statik

Capacitor memerlukan file HTML/JS/CSS statis. Konfigurasi Next.js untuk export statik dengan mengupdate next.config.ts:

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  output: 'export',
  images: {
    unoptimized: true,
  },
  // Ensure trailing slashes for proper routing in Capacitor
  trailingSlash: true,
};

export default nextConfig;

Mengapa pengaturan ini?

  • output: 'export' — Membuat HTML statis bukan memerlukan server Node.js
  • images: { unoptimized: true } — Menonaktifkan Optimasi Gambar Next.js (memerlukan server)
  • trailingSlash: true — Menjamin routing yang tepat di WebView native

Langkah 3: Tambahkan Skrip Mobile

Perbarui package.json dengan skrip pengembangan mobile:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "mobile": "bun run build && bunx cap sync",
    "mobile:ios": "bun run mobile && bunx cap open ios",
    "mobile:android": "bun run mobile && bunx cap open android"
  }
}

Tes bangunan:

bun run build

Anda seharusnya melihat out directory 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 penting bagi aplikasi mobile:

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

Apa yang dilakukan plugin ini:

  • @capacitor/app — Acara siklus aplikasi (dalam latar depan/belakang, tautan dalam)
  • @capacitor/keyboard — Mengontrol perilaku kibor
  • @capacitor/splash-screen — Mengontrol layar splash native
  • @capacitor/status-bar — Atur status bar perangkat
  • @capacitor/preference — 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 out

Ganti:

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

Hal 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: 'out',
  plugins: {
    SplashScreen: {
      launchShowDuration: 2000,
      launchAutoHide: true,
      androidScaleType: 'CENTER_CROP',
      splashFullScreen: true,
      splashImmersive: true,
    },
    Keyboard: {
      resize: 'body',
      resizeOnFullScreen: true,
    },
    StatusBar: {
      style: 'light',
    },
  },
};

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

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 Play atau tekan Cmd + R

Di Android Studio:

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

Langkah 8: Atur Ulang Reload Hidup

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

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

# Windows
ipconfig
  1. Buat konfigurasi pengembangan Capacitor. Tambahkan ke capacitor.config.ts:
import type { CapacitorConfig } from '@capacitor/cli';

const devConfig: CapacitorConfig = {
  appId: 'com.example.mymobileapp',
  appName: 'My Mobile App',
  webDir: 'out',
  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: 'out',
  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 Next.js code akan reload panas di perangkat.

Langkah 9: Buat Layar Mobile Pertama Anda

Mari kita buat layar home sederhana yang ramah mobile. Perbarui src/app/page.tsx:

'use client';

import { useEffect, useState } from 'react';
import { App } from '@capacitor/app';
import { Keyboard } from '@capacitor/keyboard';

export default function Home() {
  const [appInfo, setAppInfo] = useState<{ name: string; version: string } | null>(null);

  useEffect(() => {
    // Get app info on mount
    App.getInfo().then(setAppInfo).catch(console.error);

    // Handle back button on Android
    const backHandler = App.addListener('backButton', ({ canGoBack }) => {
      if (!canGoBack) {
        App.exitApp();
      } else {
        window.history.back();
      }
    });

    // Hide keyboard when tapping outside inputs
    const keyboardHandler = Keyboard.addListener('keyboardWillShow', () => {
      document.body.classList.add('keyboard-open');
    });

    return () => {
      backHandler.then(h => h.remove());
      keyboardHandler.then(h => h.remove());
    };
  }, []);

  return (
    <main className="min-h-screen bg-linear-to-b from-blue-500 to-blue-700 flex flex-col items-center justify-center p-6 text-white">
      <h1 className="text-4xl font-bold mb-4">My Mobile App</h1>
      <p className="text-xl mb-8 text-center opacity-90">
        Built with Next.js 15 + Capacitor 8
      </p>

      {appInfo && (
        <div className="bg-white/20 rounded-lg p-4 backdrop-blur-sm">
          <p className="text-sm">
            {appInfo.name} v{appInfo.version}
          </p>
        </div>
      )}

      <div className="mt-12 space-y-4 w-full max-w-sm">
        <button className="w-full py-4 px-6 bg-white text-blue-600 rounded-xl font-semibold text-lg shadow-lg active:scale-95 transition-transform">
          Get Started
        </button>
        <button className="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">
          Learn More
        </button>
      </div>
    </main>
  );
}

Langkah 10: Tambahkan Pengaturan Area Aman

Perangkat mobile memiliki notches, indikator rumah, dan bar status. Tambahkan pengaturan area aman dengan Tailwind.

Perbarui src/app/globals.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

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

/* Keyboard handling */
.keyboard-open {
  --sab: 0px;
}

Struktur Proyek

Proyek Anda sekarang harus terlihat seperti ini:

my-mobile-app/
├── android/              # Android native project
├── ios/                  # iOS native project
├── out/                  # Static build output
├── src/
│   ├── app/
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   └── page.tsx
│   └── ...
├── capacitor.config.ts   # Capacitor configuration
├── next.config.ts        # Next.js configuration
├── package.json
└── ...

Langkah-Langkah Selanjutnya

Anda telah memiliki aplikasi mobile Next.js yang berjalan. Berikut adalah langkah-langkah selanjutnya:

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 config
  • Deep Links: Konfigurasi skema URL untuk aplikasi Anda

Tambah Fitur Lebih

  • Kamera: bun add @capacitor/camera
  • Lokasi: bun add @capacitor/geolocation
  • Pemberitahuan Push: bun add @capacitor/push-notifications
  • Sistem File: bun add @capacitor/filesystem

UI dan transisi native

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

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

Untuk area yang aman di 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 khusus Next.js.

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

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

App Router

): export (app/from viewport Pages Router app/layout.tsx:

import type { Viewport } from 'next';

export const viewport: Viewport = {
  width: 'device-width',
  initialScale: 1,
  viewportFit: 'cover',
};

): letakkan tag meta viewport di (pages/, bukan pages/_app.tsxTangani area aman iOS dari wrapper root saja _document.tsx.

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

Selimuti semua konten halaman di dalamnya

html,
body,
#__next {
  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);
}

Jika konten terlihat dipotong, bergeser, atau dapat di-scroll secara horizontal pada iOS, menambahkan lebih banyak atau mengatur tag viewport saja biasanya tidak dapat memperbaikinya. Jalankan periksaan-periksaan ini secara berurutan. .app-shell. Padding area yang aman di header, modal, dan wrapper layout sering membuat UI terlihat dipotong atau terlalu besar.

Dengan @capgo/tailwind-capacitor, Anda dapat mengungkapkan padding yang sama dengan utilitas seperti pt-safe pb-safe px-safe di lapisan tunggal.

Atur Capacitor iOS contentInset ke never pertama

Dalam capacitor.config.ts, lebih baik mengaktifkan inset native dan biarkan CSS (atau Native Navigation’s contentInsetMode: 'css') mengontrol area aman:

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

Menggabungkan Capacitor’s automatic content inset dengan CSS env(safe-area-inset-*) penyisipan adalah penyebab umum dari penempatan ganda.

Temukan elemen yang sebenarnya mengalami kelebihan

Biasanya, penyebabnya adalah elemen yang menggunakan 100vw, Tailwind w-screen, lebar piksel tetap, atau besar min-width.

Di 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, gantikan w-screen dengan w-full ketika memungkinkan. Banyak masalah kelebihan horizontal berasal dari 100vw / w-screen, penambahan padding area aman yang duplikat, atau kontainer lebar tetap — bukan dari tag meta viewport itu sendiri.

Pembaruan Langsung Melalui Udara

Atur Capgo untuk memperbarui aplikasi tanpa harus mengirimkan aplikasi ke toko aplikasi lagi:

bunx @capgo/cli init

Pengaturan

Build gagal dengan “Tidak dapat menemukan modul” Jalankan bun install dan coba lagi.

iOS: “Tidak dapat menemukan identitas tanda tangan” 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 telah menjalankan bun run mobile setelah membuat perubahan. Untuk pengisian ulang hidup, verifikasi alamat IP yang benar dan server pengembang sedang berjalan.

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 Next.js dari Awal dengan Capacitor 8

Jika Anda menggunakan Membangun Aplikasi Mobile Next.js 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 Capacitor

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

Mulai Sekarang

Terbaru dari Blog kami

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