Untuk mendeteksi status jaringan di aplikasi Capacitor, instal @capacitor/network, panggil Network.getStatus() untuk status saat ini, dan subscribe ke networkStatusChange untuk update. Ini memberi tahu apakah perangkat punya koneksi dan apakah itu Wi-Fi atau seluler. Untuk tahu apakah internet benar-benar berfungsi, atau apakah koneksinya berkuota, tambahkan pengecekan reachability atau @capgo/capacitor-network-diagnostics. Panduan ini membahas ketiga lapisan tersebut dengan Capacitor 8 code.
Tiga pertanyaan di balik “apakah user sedang online?”
| Pertanyaan | API | Catatan |
|---|---|---|
| Apakah ada interface jaringan yang aktif? | Network.getStatus().connected |
Cepat, event-driven, tapi tidak memberi info soal akses internet |
| Jenis koneksi apa yang digunakan? | connectionType |
wifi, cellular, none, unknown in the official plugin |
| Apakah internet benar-benar berfungsi? | Cek HTTP atau internetReachable |
Butuh request atau validasi OS |
| Haruskah saya menghindari download besar? | expensive, constrained |
Jaringan berkuota dan iOS Low Data Mode |
Kebanyakan bug offline muncul karena menganggap baris pertama sebagai baris ketiga. Wi-Fi hotel dengan halaman login melaporkan connected: true sementara setiap panggilan API mengalami timeout.
Pasang plugin Network
bun add @capacitor/network
bunx cap sync
Tidak perlu konfigurasi. Di Android, plugin ini menambahkan ACCESS_NETWORK_STATE ke merged manifest, izin normal yang diberikan saat instalasi. iOS tidak butuh apa-apa.
Baca status saat ini
import { Network } from '@capacitor/network';
const status = await Network.getStatus();
console.log(status.connected); // true or false
console.log(status.connectionType); // 'wifi' | 'cellular' | 'none' | 'unknown'
Panggil saat app start sebelum memutuskan mau load dari cache atau network. Hasilnya kembali dalam beberapa milidetik karena hanya membaca state OS, tidak mengirim traffic.
Pantau perubahan jaringan
import { Network, type ConnectionStatus } from '@capacitor/network';
import type { PluginListenerHandle } from '@capacitor/core';
let handle: PluginListenerHandle | undefined;
export async function watchNetwork(onChange: (s: ConnectionStatus) => void) {
onChange(await Network.getStatus());
handle = await Network.addListener('networkStatusChange', onChange);
}
export async function stopWatchingNetwork() {
await handle?.remove();
}
Dua detail praktis:
- Debounce event-nya. Saat beralih dari Wi-Fi ke seluler, kedua platform bisa saja melaporkan
nonesebelum link baru aktif. Debounce 1–2 detik sebelum menampilkan banner “offline” menghindari flicker. - Hapus listeners saat komponen unmount, atau callback akan berjalan beberapa kali setelah hot reload dan navigasi.
React hook
import { useEffect, useState } from 'react';
import { Network, type ConnectionStatus } from '@capacitor/network';
export function useNetworkStatus() {
const [status, setStatus] = useState<ConnectionStatus>({ connected: true, connectionType: 'unknown' });
useEffect(() => {
let timer: ReturnType<typeof setTimeout>;
const listener = Network.addListener('networkStatusChange', (s) => {
clearTimeout(timer);
timer = setTimeout(() => setStatus(s), s.connected ? 0 : 1500);
});
Network.getStatus().then(setStatus);
return () => {
clearTimeout(timer);
listener.then((l) => l.remove());
};
}, []);
return status;
}
Status online diterapkan segera, status offline menunggu 1,5 detik. Pola yang sama berfungsi sebagai composable Vue atau service Angular dengan BehaviorSubject.
Mengapa “connected” tidak berarti online
connected: true berasal dari stack jaringan OS. Nilai ini tetap true ketika:
- jaringan Wi-Fi memiliki captive portal (bandara, hotel, kereta)
- router tidak memiliki koneksi upstream
- DNS rusak atau difilter
- firewall perusahaan atau VPN memblokir domain API Anda
- backend Anda sendiri sedang down
Solusinya adalah pengecekan reachability ke sesuatu yang Anda kontrol:
export async function canReachApi(timeoutMs = 4000): Promise<boolean> {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {
const res = await fetch('https://api.example.com/health', {
method: 'HEAD',
cache: 'no-store',
signal: controller.signal,
});
return res.ok;
} catch {
return false;
} finally {
clearTimeout(timer);
}
}
Jalankan saat app start, ketika networkStatusChange laporan connected: true, dan setelah request gagal. Jangan poll setiap beberapa detik, itu menguras baterai dan data. Pastikan health endpoint mengizinkan origin app Anda di CORS (capacitor://localhost di iOS, https://localhost di Android secara default), atau gunakan CapacitorHttp untuk mengirimnya dari native code.
Dapatkan status lebih lengkap dengan diagnostik jaringan
@capgo/capacitor-network-diagnostics membaca lebih banyak informasi yang diketahui OS dan dapat menjalankan pemeriksaan native yang melewati CORS WebView:
bun add @capgo/capacitor-network-diagnostics
bunx cap sync
import { NetworkDiagnostics } from '@capgo/capacitor-network-diagnostics';
const status = await NetworkDiagnostics.getNetworkStatus();
// {
// connected: true,
// connectionType: 'wifi' | 'cellular' | 'ethernet' | 'vpn' | 'other' | 'unknown' | 'none',
// internetReachable: true,
// expensive: false, // metered / cellular
// constrained: false, // iOS Low Data Mode
// captivePortal: false, // Android only
// details: { ... }
// }
Bagaimana field-field ini dipetakan ke OS:
| Kolom | Android | iOS |
|---|---|---|
internetReachable |
NET_CAPABILITY_VALIDATED (Android memeriksa internet) |
Mencerminkan NWPathMonitor status path |
expensive |
isActiveNetworkMetered() |
NWPath.isExpensive |
constrained |
Selalu false |
NWPath.isConstrained (Mode Data Rendah) |
captivePortal |
NET_CAPABILITY_CAPTIVE_PORTAL |
Tidak dilaporkan |
vpn tipe |
Ya | Ya |
Di Android, internetReachable adalah sinyal yang kuat karena OS sudah menguji koneksinya. Pada iOS, ini lebih mendekati connected, jadi tetap gunakan pengecekan HTTP untuk alur kritis.
Pengecekan reachability native
const api = await NetworkDiagnostics.testUrl({
url: 'https://api.example.com/health',
method: 'HEAD',
timeoutMs: 4000,
});
// api.reachable, api.statusCode, api.durationMs, api.errorCode
const socket = await NetworkDiagnostics.testWebSocket({ url: 'wss://realtime.example.com' });
const port = await NetworkDiagnostics.testPort({ host: 'mqtt.example.com', port: 8883 });
Request native tidak terkena CORS, jadi Anda juga bisa menguji host pihak ketiga.
Layar “network report” untuk support
Saat user bilang “aplikasinya tidak jalan”, laporan diagnostik sekali tap bisa menghemat berjam-jam komunikasi bolak-balik:
const report = await NetworkDiagnostics.runDiagnostics({
urls: [{ url: 'https://api.example.com/health' }, { url: 'https://cdn.example.com/ping' }],
websockets: [{ url: 'wss://realtime.example.com' }],
download: { url: 'https://cdn.example.com/1mb.bin', maxBytes: 1_048_576 },
packetLoss: { url: 'https://api.example.com/health', count: 5 },
});
console.log(report.issues); // human-readable list of problems
console.log(report.download?.mbps);
console.log(report.packetLoss?.lossPercent);
Lampirkan JSON ke tiket support. Anda akan langsung tahu apakah masalahnya ada di DNS, WebSocket yang diblokir, captive portal, atau koneksi lambat.
Beradaptasi dengan koneksi metered dan Low Data Mode
Menghormati limit data adalah cara cepat mendapat review bagus di pasar dengan kuota mahal:
export async function shouldPrefetchMedia() {
const s = await NetworkDiagnostics.getNetworkStatus();
if (!s.connected) return false;
if (s.constrained) return false; // user asked iOS to save data
if (s.expensive) return false; // cellular or metered Wi-Fi
return true;
}
Gunakan ini untuk menentukan autoplay video, kualitas gambar, background sync, dan download besar. Di Android, user bisa menandai Wi-Fi sebagai metered, jadi jangan berasumsi Wi-Fi selalu gratis.
Buat banner offline
Banner kecil lebih jelas daripada request yang gagal. Dengan hook di atas:
export function OfflineBanner() {
const { connected } = useNetworkStatus();
if (connected) return null;
return (
<div role="status" aria-live="polite" className="offline-banner">
You are offline. Changes will sync when you reconnect.
</div>
);
}
role="status" dengan aria-live="polite" membuat screen reader mengumumkan perubahan. Untuk UI spesifik framework, lihat panduan kami tentang membangun layar offline di Vue, Angular, dan React.
Antrekan pekerjaan saat offline
Deteksi hanyalah separuh dari dukungan offline. Saat status berubah menjadi offline:
- Serve bacaan dari local storage. Database SQLite seperti
@capgo/capacitor-fast-sqlmenangani dataset besar lebih baik daripadalocalStorage. - Tulis aksi pengguna ke tabel outbox dengan timestamp dan idempotency key.
- Di
networkStatusChangeke connected, jalankancanReachApi(), lalu flush outbox secara berurutan. - Ulangi permintaan yang gagal dengan exponential backoff, dibatasi beberapa menit.
Untuk upload yang harus tetap berjalan saat aplikasi ditutup, serahkan prosesnya ke native uploader alih-alih fetch.
Fallback web
@capacitor/network juga berjalan di browser, di mana ia berbasis pada navigator.onLine dan online dan offline events. Artinya code Anda berfungsi di bun run dev dan di PWA tanpa perubahan, tetapi connectionType sering kali akan unknown di web. Chrome memiliki navigator.connection menyediakan effectiveType dan saveData, Safari tidak, jadi perlakukan sebagai petunjuk opsional.
Pemecahan Masalah
Listener tidak pernah memicu di iOS Simulator: simulator berbagi jaringan Mac. Aktifkan/nonaktifkan Wi-Fi di Mac atau uji di perangkat dengan mode pesawat.
connectionType adalah unknown di VPN: plugin resmi hanya melaporkan wifi, cellular, none dan unknown. Gunakan plugin diagnostik, yang mengembalikan vpn dan ethernet.
Aplikasi menampilkan status offline selama satu detik saat beralih jaringan: debounce transisi offline seperti yang ditunjukkan di atas.
Health check gagal di perangkat tetapi berfungsi di browser: CORS. Izinkan capacitor://localhost dan https://localhost, atau gunakan NetworkDiagnostics.testUrl, yang berjalan secara native.
navigator.onLine bernilai true saat plugin menyatakan offline: percaya pada plugin. Beberapa Android WebView tidak memperbarui navigator.onLine secara andal.
Kirim perbaikan offline over the air
Penanganan offline sebagian besar adalah JavaScript: ambang batas, banner, logika retry, aturan cache. Dengan Live updates Capgo, Anda dapat menyesuaikan semuanya untuk setiap pengguna pada hari yang sama. Capgo mengunduh bundle update di latar belakang dan mempertahankan versi saat ini jika unduhan gagal, sehingga koneksi buruk tidak pernah meninggalkan pengguna dengan update yang setengah terpasang. dokumen diagnostik jaringan menampilkan semua opsi.