Menggunakan @capgo/capacitor-native-navigation
@capgo/capacitor-native-navigation merender navigasi atas native, chrome tab bawah, dan shell transisi rute di atas satu Capacitor WebView layar penuh. Framework web Anda tetap menangani rute dan konten, sementara native memegang frame aplikasi.
Instal dan sinkronkan
npm install @capgo/capacitor-native-navigation
npx cap sync
Konfigurasikan native frame
import { NativeNavigation } from '@capgo/capacitor-native-navigation';
await NativeNavigation.configure({
contentInsetMode: 'css',
animationDuration: 360,
colors: {
tint: '#0f172a',
inactiveTint: '#64748b',
},
});
Render navbar native
await NativeNavigation.setNavbar({
title: 'Inbox',
subtitle: 'Native chrome',
transparent: true,
backButton: { visible: false },
rightItems: [
{
id: 'compose',
title: 'Compose',
icon: {
svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>',
},
},
],
});
Tambahkan baris segmen multi-level di bawah navbar
Gunakan segments ke setNavbar untuk menumpuk baris segmen native di bawah bar, misalnya scope switcher di atas dan tab section di bawahnya. Baris dirender dari atas ke bawah dan masing-masing menambah 44pt (iOS) atau 48dp (Android) ke navbar dan insets yang dilaporkan. iOS menggunakan UISegmentedControl dan glass pills; Android menggunakan Material segmented buttons dan filter chips.
| iOS | Android |
|---|---|
![]() |
![]() |
const sections = {
account: ['General', 'Notifications', 'Password', 'Two-factor'],
organization: ['General', 'Members', 'Plans', 'Usage', 'Credits', 'Billing', 'Security', 'Webhooks'],
};
const selection = { scope: 'account', section: 'general' };
const renderNavbar = () =>
NativeNavigation.setNavbar({
title: 'Settings',
segments: [
{
id: 'scope',
selectedId: selection.scope,
items: [
{ id: 'account', title: 'Account' },
{ id: 'organization', title: 'Organization' },
],
},
{
id: 'section',
style: 'scroll', // scrolling chips; `auto` uses `segmented` for up to 4 items
selectedId: selection.section,
items: sections[selection.scope].map((title) => ({ id: title.toLowerCase(), title })),
},
],
});
await NativeNavigation.addListener('navbarSegmentSelect', async ({ groupId, id }) => {
if (groupId === 'scope') {
selection.scope = id;
selection.section = 'general'; // the second level depends on the first one
} else {
selection.section = id;
}
await renderNavbar();
});
await renderNavbar();
Seleksi berpindah secara native saat pengguna mengetuk, tetapi setiap setNavbar pemanggilan berlaku selectedId lagi. Simpan id yang dipilih di state Anda dan teruskan pada setiap setNavbar call; untuk menolak pilihan, kirimkan sebelumnya selectedId. Item juga menerima icon, accessibilityLabel, dan enabled. Pass segments: [] untuk menghapus baris. Tersedia sejak 8.13.0.
Render tabbar native
await NativeNavigation.setTabbar({
selectedId: 'inbox',
labelVisibilityMode: 'selected',
icons: true,
colors: {
dynamic: true,
tint: '#0f172a',
inactiveTint: '#64748b',
},
tabs: [
{
id: 'inbox',
title: 'Inbox',
icon: {
svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16v16H4z"/><path d="m4 13 4 4h8l4-4"/></svg>',
},
},
{
id: 'search',
title: 'Search',
icon: {
svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m20 20-3-3"/></svg>',
},
},
],
});
Hubungkan event native ke router Anda
Bar native memancarkan intent. Router Anda tetap melakukan perubahan rute:
await NativeNavigation.addListener('navbarBack', () => {
router.back();
});
await NativeNavigation.addListener('navbarItemTap', ({ id }) => {
if (id === 'compose') router.push('/compose');
});
await NativeNavigation.addListener('tabSelect', ({ id }) => {
router.push(`/${id}`);
});
Animasikan perubahan route
Gunakan transaksi transisi di sekitar pembaruan rute web normal Anda:
const transition = await NativeNavigation.beginTransition({
direction: 'forward',
});
router.push('/message/42');
await router.ready?.();
await NativeNavigation.setNavbar({
title: 'Message',
backButton: { visible: true, title: 'Inbox' },
});
await NativeNavigation.finishTransition({
id: transition.id,
direction: 'forward',
});
Tambahkan transisi zoom
Gunakan helper zoom untuk rute yang dibuka dari kartu, item grid, atau pratinjau media.
import { beginZoomTransition, finishZoomTransition } from '@capgo/capacitor-native-navigation';
const card = document.querySelector('[data-message-card]');
if (card) {
const transition = await beginZoomTransition(card, { cornerRadius: 18 });
router.push('/message/42');
await router.ready?.();
await NativeNavigation.setNavbar({
title: 'Message',
backButton: { visible: true, title: 'Inbox' },
});
await finishZoomTransition(undefined, {
id: transition.id,
cornerRadius: 18,
});
}
Beri padding konten dengan native insets
Saat contentInsetMode adalah css, plugin ini menulis variabel CSS untuk bar native:
.page {
padding-top: var(--cap-native-navigation-top);
padding-bottom: var(--cap-native-navigation-bottom);
}
Pilihan ikon
Ikon adalah deskriptor native, bukan node React atau Vue. Gunakan SVG jika Anda tidak ingin membundel aset native:
const icon = {
svg: '<svg viewBox="0 0 24 24"><path d="M3 10.5 12 3l9 7.5"/></svg>',
template: true,
ios: { sfSymbol: 'house.fill' },
android: { resource: 'ic_menu_view' },
};
Inline SVG mendukung path, line, polyline, polygon, circle, dan rect, yang mencakup set ikon umum seperti Lucide dan Feather.
Kombinasikan dengan @capgo/capacitor-transitions
Gunakan Native Navigation untuk navbar native, tabbar, safe-area insets, dan event intent native. Gunakan @capgo/capacitor-transitions untuk tumpukan halaman WebView di bawah chrome native tersebut.
npm install @capgo/capacitor-native-navigation @capgo/capacitor-transitions
npx cap sync
Inisialisasi kedua paket sekali:
import { NativeNavigation } from '@capgo/capacitor-native-navigation';
import '@capgo/capacitor-transitions';
import { initTransitions, setupRouterOutlet, setDirection } from '@capgo/capacitor-transitions/react';
initTransitions({ platform: 'auto' });
const outlet = document.querySelector('cap-router-outlet');
if (outlet) {
setupRouterOutlet(outlet, { platform: 'auto', swipeGesture: 'auto' });
}
await NativeNavigation.configure({
contentInsetMode: 'css',
});
Jaga agar outlet transisi berfokus pada halaman, bukan bar web duplikat:
<cap-router-outlet platform="auto" swipe-gesture="auto">
<cap-page>
<cap-content slot="content" fullscreen>
<main class="page">Inbox content</main>
</cap-content>
</cap-page>
</cap-router-outlet>
Kendalikan kedua package lewat router action yang sama:
async function openMessage(id: string) {
setDirection('forward');
await router.push(`/messages/${id}`);
await NativeNavigation.setNavbar({
title: 'Message',
backButton: { visible: true, title: 'Inbox' },
});
}
await NativeNavigation.addListener('navbarBack', () => {
setDirection('back');
router.back();
});
await NativeNavigation.addListener('tabSelect', ({ id }) => {
setDirection('root');
router.push(`/${id}`);
});
Pilih satu layer animasi per perubahan route. Biarkan @capgo/capacitor-transitions menganimasikan push halaman normal, dan gunakan helper zoom Native Navigation hanya untuk route shared-element atau zoom.
Referensi Lengkap
- GitHub: https://github.com/Cap-go/capacitor-native-navigation/
- Dokumentasi: /docs/plugins/native-navigation/
Lanjutkan dari Menggunakan @capgo/capacitor-native-navigation
Jika Anda menggunakan Menggunakan @capgo/capacitor-native-navigation untuk merencanakan perilaku media dan antarmuka native, hubungkan dengan @capgo/capacitor-native-navigation untuk detail implementasi di @capgo/capacitor-native-navigation, Panduan Memulai untuk detail implementasi di Getting Started, Menggunakan @capgo/capacitor-live-activities untuk kemampuan native di Menggunakan @capgo/capacitor-live-activities, @capgo/capacitor-live-activities untuk detail implementasi di @capgo/capacitor-live-activities, dan Menggunakan @capgo/capacitor-video-player untuk kapabilitas native saat menggunakan @capgo/capacitor-video-player.

