Mengonfigurasi `@capacitor/splash-screen` untuk launch experience yang mulus, `@capacitor/status-bar` untuk styling dark/light mode, serta `@capacitor/keyboard` untuk behavior input — termasuk safe area insets dan edge-to-edge layout di Capacitor 8.

Setelah di episode 10 kita menyelesaikan masalah networking, pada episode ini kita fokus ke UI shell — lapisan native yang membungkus aplikasi web kalian: splash screen saat app launch, status bar di bagian atas layar, dan keyboard behavior saat user mengetik. Meskipun terlihat kecil, ketiganya sangat mempengaruhi kesan pertama user.
Mengapa UI shell penting? Karena user membentuk opini dalam 3 detik pertama. Splash screen yang lambat, status bar yang tidak match dengan tema, atau keyboard yang menutupi input field — semua ini menciptakan first impression yang buruk.
npm install @capacitor/splash-screen
npx cap syncconst config: CapacitorConfig = {
// ...
plugins: {
SplashScreen: {
launchShowDuration: 2000,
launchAutoHide: true,
backgroundColor: '#ffffff',
androidScaleType: 'CENTER_CROP',
showSpinner: true,
spinnerColor: '#999999',
splashFullScreen: true,
splashImmersive: true,
},
},
};| Opsi | Deskripsi |
|---|---|
launchShowDuration | Durasi splash screen dalam milidetik (default: 2000) |
launchAutoHide | Sembunyikan otomatis setelah web app siap |
backgroundColor | Warna latar splash screen |
showSpinner | Tampilkan loading spinner |
splashFullScreen | Sembunyikan status bar selama splash |
splashImmersive | Sembunyikan navigation bar (Android) |
Jika web app butuh waktu load, sembunyikan splash secara manual setelah siap:
import { SplashScreen } from '@capacitor/splash-screen';
// Setelah app siap
await SplashScreen.hide();Untuk splash screen custom, edit file storyboard (iOS) atau layout XML (Android) langsung di folder native. Di iOS, buka ios/App/App/LaunchScreen.storyboard. Di Android, buat layout custom di android/app/src/main/res/layout/.
Tip
Jangan gunakan splash screen sebagai loading screen yang panjang. Idealnya 1-2 detik — cukup untuk branding tanpa menunggu. Web app harus di-cache agar load cepat.
npm install @capacitor/status-bar
npx cap syncimport { StatusBar, Style } from '@capacitor/status-bar';
// Dark mode — status bar putih/terang
await StatusBar.setStyle({ style: Style.Light });
// Light mode — status bar gelap
await StatusBar.setStyle({ style: Style.Dark });
// Overlay status bar di atas konten
await StatusBar.setOverlaysWebView({ overlay: true });
// Ubah warna
await StatusBar.setBackgroundColor({ color: '#6366f1' });import { StatusBar, Style } from '@capacitor/status-bar';
function updateStatusBarForTheme(isDark: boolean) {
if (isDark) {
StatusBar.setStyle({ style: Style.Light });
StatusBar.setBackgroundColor({ color: '#1e1e2e' });
} else {
StatusBar.setStyle({ style: Style.Dark });
StatusBar.setBackgroundColor({ color: '#ffffff' });
}
}
// Panggil saat theme berubah
document.addEventListener('themeChange', (e: any) => {
updateStatusBarForTheme(e.detail.isDark);
});npm install @capacitor/keyboard
npx cap syncimport { Keyboard } from '@capacitor/keyboard';
// Keyboard akan muncul
Keyboard.addListener('keyboardWillShow', (info) => {
console.log('Keyboard height:', info.keyboardHeight);
// Geser konten agar input tidak tertutup
document.body.style.paddingBottom = `${info.keyboardHeight}px`;
});
// Keyboard sudah muncul
Keyboard.addListener('keyboardDidShow', (info) => {
// Fokus ke input field yang aktif
scrollToActiveInput();
});
// Keyboard akan sembunyi
Keyboard.addListener('keyboardWillHide', () => {
document.body.style.paddingBottom = '0';
});
// Keyboard sudah sembunyi
Keyboard.addListener('keyboardDidHide', () => {
// Bersihkan state
});function scrollToActiveInput() {
const active = document.activeElement as HTMLElement;
if (active && active.tagName === 'INPUT' || active.tagName === 'TEXTAREA') {
setTimeout(() => {
active.scrollIntoView({ behavior: 'smooth', block: 'center' });
}, 100);
}
}Note
Di iOS, Keyboard.setScroll({ isDisabled: true }) bisa menonaktifkan auto-scroll bawaan iOS yang kadang mengganggu layout kalian sendiri.
Layar modern memiliki notch, Dynamic Island, dan rounded corners. Safe area insets menjamin konten tidak tertutup oleh elemen hardware ini.
.app-container {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}Capacitor 8 memperbaiki dukungan SystemBars untuk edge-to-edge layout:
import { StatusBar } from '@capacitor/status-bar';
// Aktifkan overlay agar konten full-screen
await StatusBar.setOverlaysWebView({ overlay: true });
// Set transparan status bar
await StatusBar.setBackgroundColor({ color: '#00000000' });Kombinasikan dengan CSS safe area untuk konten yang tetap accessible:
body {
margin: 0;
background: #1e1e2e;
}
.content {
padding: env(safe-area-inset-top) 16px env(safe-area-inset-bottom);
}Pada episode 11 ini, kalian telah memahami:
Di episode 12 selanjutnya, kita akan membahas menulis Custom Plugin dengan Swift dan Kotlin — bridge API, anotasi native, method invocation, dan praktik plugin native sederhana yang dipanggil dari JavaScript. Sampai jumpa!