Langsung ke konten utama
Tutorial

Membangun Mobile Apps dengan React dan Capacitor

Pelajari cara membangun mobile app menggunakan React, Capacitor, serta tambahkan Capgo Native Navigation, Transitions, dan praktik terbaik layout iOS.

Membangun Mobile Apps dengan React dan Capacitor

Dalam tutorial ini, kita akan mulai dengan React app baru dan beralih ke native mobile development menggunakan Capacitor. Anda juga bisa menambahkan Capgo Native Navigation and Transitions untuk feel mobile yang native, serta menggunakan tailwind-capacitor untuk safe areas.

Capacitor memungkinkan Anda mengubah React web application menjadi native mobile app dengan mudah tanpa modifikasi besar atau harus belajar skill baru seperti React Native.

Hanya dengan beberapa langkah mudah, sebagian besar aplikasi React bisa diubah menjadi aplikasi mobile.

Tutorial ini akan memandu Anda melalui prosesnya, mulai dari aplikasi React baru lalu menambahkan Capacitor untuk masuk ke ranah aplikasi mobile native. Anda juga bisa menggunakan Capgo Native Navigation, Transitions, dan tailwind-capacitor untuk safe areas.

Tentang Capacitor

CapacitorJS adalah game-changer! Anda bisa dengan mudah memasukkannya ke proyek web apa pun, dan ia akan membungkus aplikasi Anda ke dalam native webview, sekaligus membuatkan proyek native Xcode dan Android Studio untuk Anda. Selain itu, plugin-nya menyediakan akses ke fitur native perangkat seperti kamera melalui JS bridge.

Dengan Capacitor, Anda mendapatkan aplikasi mobile native yang luar biasa tanpa setup rumit atau learning curve yang tinggi. API yang ramping dan fungsionalitasnya yang efisien membuatnya sangat mudah diintegrasikan ke proyek Anda. Percayalah, Anda akan takjub betapa mudahnya membuat aplikasi native yang berfungsi penuh dengan Capacitor!

Menyiapkan Aplikasi React Anda

Meskipun ada berbagai metode untuk memulai aplikasi React, mari kita gunakan cara termudah dalam tutorial ini yang menyediakan aplikasi React kosong:

npx create-react-app my-app

Untuk membuat aplikasi mobile native, kita memerlukan sebuah export dari proyek kita. Jadi, mari kita tambahkan script sederhana di package.json yang dapat digunakan untuk build dan export proyek React:

{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}

Sekarang Anda bisa menjalankan npm run build tanpa perlu khawatir, dan Anda akan melihat folder out yang baru di root proyek Anda.

Folder ini akan digunakan oleh Capacitor nanti, tapi untuk saat ini, kita harus mengaturnya dengan benar.

Menambahkan Capacitor ke React App Anda

Untuk membungkus web app ke dalam container mobile native, kita perlu mengikuti beberapa langkah awal, tapi setelah itu cukup dengan menjalankan satu sync command.

Pertama, kita bisa menginstal Capacitor CLI sebagai dev dependency, lalu mengaturnya di dalam proyek. Saat setup, Anda bisa tekan “enter” untuk menerima nilai default name dan bundle ID.

Berikutnya, kita perlu menginstal paket inti serta paket yang relevan untuk platform iOS dan Android.

Terakhir, kita bisa menambahkan platformnya, dan Capacitor akan membuat folder untuk setiap platform di root proyek kita:

# Install the Capacitor CLI locally
npm install -D @capacitor/cli

# Initialize Capacitor in your React project
npx cap init

# Install the required packages
npm install @capacitor/core @capacitor/ios @capacitor/android

# Add the native platforms
npx cap add ios
npx cap add android

Pada tahap ini, Anda seharusnya sudah bisa melihat iOS dan Android folder di proyek React Anda.

Itu adalah proyek native asli!

Untuk mengakses proyek Android nantinya, Anda harus menginstal Android Studio. Untuk iOS, Anda butuh Mac dan harus menginstal Xcode.

Selain itu, Anda harus menemukan file capacitor.config.ts di proyek Anda, yang berisi beberapa pengaturan fundamental Capacitor yang digunakan saat sinkronisasi. Satu hal yang perlu Anda perhatikan adalah webDir, yang harus mengarah ke hasil perintah build Anda. Saat ini, nilainya tidak tepat.

Untuk memperbaikinya, buka file capacitor.config.json file dan perbarui webDir:

{
  "appId": "com.example.app",
  "appName": "my-app",
  "webDir": "out",
  "bundledWebRuntime": false
}

Anda bisa mencobanya dengan menjalankan perintah berikut:

npm run build
npx cap sync

Perintah pertama npm run build hanya akan melakukan build pada proyek React Anda dan mengekspor static build.

Sedangkan perintah kedua npx cap sync akan menyinkronkan semua web code ke tempat yang tepat di platform native agar bisa ditampilkan di aplikasi.

Selain itu, perintah sync mungkin akan memperbarui platform native dan menginstal plugin, jadi saat Anda menginstal plugin Capacitor saatnya untuk menjalankan npx cap sync lagi.

Tanpa disadari, Anda sebenarnya sudah selesai, jadi mari kita lihat aplikasinya di perangkat!

Build dan Deploy aplikasi native

Untuk mengembangkan aplikasi iOS, Anda perlu menginstal Xcode dan untuk aplikasi Android, Anda perlu menginstal Android Studio Selain itu, jika Anda berencana mendistribusikan aplikasi di app store, Anda perlu mendaftar di Apple Developer Program untuk iOS dan Google Play Console untuk Android.

Jika Anda baru dalam pengembangan mobile native, Anda bisa menggunakan Capacitor CLI untuk membuka kedua proyek native dengan mudah:

npx cap open ios
npx cap open android

Setelah proyek native siap, deploy aplikasi ke perangkat yang terhubung sangatlah mudah. Di Android Studio, Anda cukup menunggu semuanya siap, lalu bisa langsung deploy aplikasi ke perangkat tanpa mengubah pengaturan apa pun. Berikut contohnya:

android-studio-run

Di Xcode, Anda perlu mengatur signing account untuk deploy aplikasi ke perangkat asli, bukan sekadar simulator. Jika belum pernah melakukannya, Xcode akan memandu Anda melalui prosesnya (namun, Anda harus terdaftar di Developer Program). Setelah itu, Anda cukup menekan tombol play untuk menjalankan aplikasi di perangkat yang terhubung, yang bisa Anda pilih di bagian atas. Berikut contohnya:

xcode-run

Selamat! Anda telah berhasil men-deploy React web app ke perangkat mobile. Berikut contohnya:

react-mobile-app

Tapi tunggu dulu, ada cara yang lebih cepat untuk melakukan ini selama masa development…

Capacitor Live Reload

Saat ini, Anda mungkin sudah terbiasa dengan fitur hot reload di semua framework modern, dan kabar baiknya adalah Anda bisa mendapatkan fungsionalitas yang sama di perangkat mobile dengan usaha minimal!

Aktifkan akses ke aplikasi lokal Anda dengan live reload di jaringan Anda dengan membuat aplikasi Capacitor memuat konten dari URL tertentu.

Langkah pertama adalah mencari tahu alamat IP lokal Anda. Jika menggunakan Mac, Anda bisa mengetahuinya dengan menjalankan perintah berikut di terminal:

ipconfig getifaddr en0

Di Windows, jalankan:

ipconfig

Lalu cari alamat IPv4.

Kita bisa menginstruksikan Capacitor untuk memuat aplikasi langsung dari server dengan menambahkan entri lain ke capacitor.config.ts file:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'my-app',
  webDir: 'out',
  bundledWebRuntime: false,
  server: {
    url: 'http://192.168.x.xx:3000',
    cleartext: true
  }
};

export default config;

Pastikan untuk menggunakan IP dan port yang benar, saya menggunakan port default React dalam contoh ini.

Sekarang, kita bisa menerapkan perubahan ini dengan menyalinnya ke proyek native kita:

npx cap copy

Panduan copy perintahnya mirip dengan sync, tapi ini hanya akan menyalin perubahan yang ada di folder web dan konfigurasi, tanpa memperbarui proyek native.

Sekarang Anda bisa deploy aplikasi sekali lagi melalui Android Studio atau Xcode. Setelah itu, jika Anda mengubah sesuatu di React app Anda, aplikasi akan otomatis reload dan menampilkan perubahannya!

Perlu diingat bahwa jika Anda menginstal plugin baru seperti kamera, Anda tetap perlu melakukan rebuild pada proyek native. Ini karena file native berubah, dan tidak bisa dilakukan secara on the fly.

Pastikan Anda menggunakan IP dan port yang benar di konfigurasi Anda. Blok code di atas menunjukkan port default React untuk keperluan demonstrasi.

Menggunakan Capacitor Plugins

Mari kita lihat cara menggunakan Capacitor plugin secara langsung, seperti yang sudah kita bahas sebelumnya. Untuk melakukannya, kita bisa menginstal plugin yang cukup simpel dengan menjalankan:

npm i @capacitor/share

Tidak ada yang rumit dari Plugin share, tapi tetap memunculkan dialog share native! Untuk ini, kita hanya perlu mengimpor package dan memanggil share() function dari aplikasi kita. Mari ubah src/App.js menjadi:

import React from 'react';
import { Share } from '@capacitor/share';

function App() {
  const share = async () => {
    await Share.share({
      title: 'Open Youtube',
      text: 'Check new video on youtube',
      url: 'https://www.youtube.com',
      dialogTitle: 'Share with friends'
    });
  };

  return (
    <div>
      <h1>Welcome to React and Capacitor!</h1>
      <p>
        <h2>Cool channel</h2>
        <button onClick={() => share()}>Share now!</button>
      </p>
    </div>
  );
}

export default App;

Seperti yang disebutkan sebelumnya, saat menginstal plugin baru, kita perlu melakukan operasi sync lalu redeploy aplikasi ke perangkat. Untuk melakukannya, jalankan perintah berikut:

npx cap sync

Setelah menekan tombol, Anda bisa melihat dialog share native yang keren bekerja!

react-capacitor-share

Selanjutnya, buat aplikasi terasa lebih native di iOS dan Android dengan Capgo navigation dan transisi, serta perbaiki masalah layout iOS umum yang menyebabkan horizontal overflow atau area safe area terpotong.

UI rasa native dengan Capgo Native Navigation dan Transitions

Saya telah bekerja bertahun-tahun dengan Ionic untuk membangun aplikasi cross-platform, tapi mengintegrasikannya dengan React terasa kurang optimal dan jarang sepadan jika Anda sudah menggunakan Tailwind CSS.

Agar terasa seperti aplikasi mobile native di aplikasi React + Capacitor, gunakan plugin Capgo alih-alih UI kit khusus web seperti Konsta UI:

  • @capgo/capacitor-native-navigation — navbar native, Liquid Glass tab bar di iOS, dan gaya tab bar blur di Android. React router Anda mengelola state route; plugin yang mengelola native chrome.
  • @capgo/capacitor-transitions — transisi halaman ala Ionic dan fitur iOS edge swipe-back di layer WebView, tanpa harus menggunakan Ionic UI.

Install keduanya:

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

Konfigurasi navigasi native dengan mode CSS inset agar konten web menghormati area bar native:

import { NativeNavigation } from '@capgo/capacitor-native-navigation';

await NativeNavigation.configure({
  contentInsetMode: 'css',
  animationDuration: 360,
  glass: {
    effect: 'liquidGlass',
  },
});

Render Liquid Glass tab bar (iOS menggunakan rendering sistem; Android menggunakan backdrop WebView yang blur):

await NativeNavigation.setTabbar({
  selectedId: 'home',
  labelVisibilityMode: 'labeled',
  icons: true,
  colors: { dynamic: true },
  tabs: [
    { id: 'home', title: 'Home', icon: { svg: '...' } },
    { id: 'settings', title: 'Settings', icon: { svg: '...' } },
  ],
});

await NativeNavigation.addListener('tabSelect', ({ id }) => {
  navigate(`/${id}`);
});

Tambahkan transisi halaman native di app shell Anda:

import { useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/react';

initTransitions({ platform: 'auto' });

export function AppShell() {
  const navigate = useNavigate();
  const outletRef = useRef<HTMLElement>(null);

  useEffect(() => {
    if (outletRef.current) {
      setupRouterOutlet(outletRef.current, { platform: 'auto', swipeGesture: 'auto' });
    }
  }, []);

  const openSettings = () => {
    setDirection('forward');
    navigate('/settings');
  };

  return <cap-router-outlet ref={outletRef}>{/* routes */}</cap-router-outlet>;
}

Bungkus halaman yang di-route dengan cap-router-outlet, cap-page, dan cap-content, dan panggil setDirection('forward') atau setDirection('back') sebelum navigasi. Jangan duplikasi web header atau footer jika navigasi native sudah mengelola area tersebut.

Lihat panduan lengkapnya: Menggunakan @capgo/capacitor-native-navigation dan Menggunakan @capgo/capacitor-transitions.

Safe areas dengan Tailwind

Untuk device safe areas di Tailwind CSS, gunakan @capgo/tailwind-capacitor (dipublikasikan sebagai tailwind-capacitor pada npm). Ini menyediakan safe-areas utilitas dan plugin Tailwind Capacitor lainnya:

bun add -D tailwind-capacitor

Di src/index.css:

@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";

Gunakan utilitas seperti pt-safe, pb-safe, dan px-safe daripada menulis env(safe-area-inset-*) secara manual. Proyek ini aktif dikembangkan — jika ada yang kurang untuk setup React Anda, buka PR di GitHub.

Memperbaiki Masalah Layout iOS (Viewport, Safe Area, dan Horizontal Overflow)

Jika konten terlihat terpotong, bergeser, atau bisa di-scroll secara horizontal di iOS, menambah overflow-x: hidden atau sekadar mengubah tag viewport saja biasanya tidak cukup. Lakukan pengecekan berikut secara berurutan.

Pastikan viewport meta tag diterapkan dengan benar

Tambahkan viewport meta tag di index.html di dalam <head>:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />

Kelola iOS safe area cukup dari satu root wrapper saja

Buat satu app shell dan terapkan safe area padding di sana — jangan di banyak komponen bersarang:

html,
body,
#root {
  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-shell. Duplikasi safe-area padding pada header, modal, dan layout wrapper sering kali membuat UI terlihat terpotong atau terlalu besar.

Dengan @capgo/tailwind-capacitor, Anda bisa menggunakan padding yang sama dengan utility seperti pt-safe pb-safe px-safe pada single shell tersebut.

Atur Capacitor iOS contentInset ke never pertama

Di capacitor.config.ts, lebih baik nonaktifkan native inset dan biarkan CSS (atau Native Navigation) contentInsetMode: 'css') yang menangani safe area:

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

Mencampur automatic content inset dari Capacitor dengan CSS env(safe-area-inset-*) padding sering kali menyebabkan double spacing.

Cari elemen yang sebenarnya overflow

Penyebab umumnya adalah elemen yang menggunakan 100vw, Tailwind w-screen, lebar pixel tetap, atau 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, ganti w-screen dengan w-full jika memungkinkan. Banyak masalah overflow horizontal berasal dari 100vw / w-screen, duplikasi safe-area padding, atau container dengan lebar tetap — bukan dari viewport meta tag itu sendiri.

Kesimpulan

Capacitor adalah opsi terbaik untuk membangun aplikasi native berbasis proyek web yang sudah ada, menawarkan cara simpel untuk berbagi code dan menjaga UI tetap konsisten.

Dan dengan tambahan Capgo, kini makin mudah menambahkan Live Update ke aplikasi Anda, memastikan pengguna selalu mendapatkan fitur terbaru dan perbaikan bug.

Jika Anda ingin belajar cara menambahkan Capgo ke aplikasi React Anda, simak artikel berikutnya:

Lanjutkan dari Building Mobile Apps with React and Capacitor

Jika Anda menggunakan Membangun Aplikasi Mobile dengan React dan Capacitor untuk merencanakan otomatisasi CI/CD, hubungkan dengan CI/CD Capgo untuk workflow produk di Capgo CI/CD, Capgo Native Build untuk workflow produk di Capgo Native Builds, Integrasi Capgo untuk alur kerja produk di Integrasi Capgo, Integrasi CI/CD untuk detail implementasi di Integrasi CI/CD, dan Integrasi GitHub Actions untuk detail implementasi di Integrasi GitHub Actions.

Live updates untuk aplikasi Capacitor

Saat bug web-layer sudah live, kirim perbaikannya lewat Capgo alih-alih menunggu berhari-hari untuk persetujuan app store. Pengguna mendapat update di background, sementara perubahan native tetap mengikuti jalur review normal.

Terbaru dari Blog kami

Capgo memberikan insight terbaik yang Anda butuhkan untuk membuat aplikasi mobile yang benar-benar profesional.