---
description: Learn how to detect the network status in a Capacitor app: check the connection type, listen for changes, and handle offline and metered connections.
title: How to Detect the Network Status in Capacitor - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/how-to-detect-the-network-status-in-a-capacitor-app.png
---

<!doctype html> 

[Skip to content ](#how-to-detect-the-network-status-in-capacitor) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Tauri ](/docs/sdks/capacitor/tauri/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Set Up Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Notifications
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Network Restrictions ](/docs/cloud/organizations/network-restrictions/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ Try Capawesome ](#try-capawesome)
* [ Conclusion ](#conclusion)

* Related links

# How to Detect the Network Status in Capacitor[¶](#how-to-detect-the-network-status-in-capacitor "Permanent link")

To detect the network status in a Capacitor app, install the [Capacitor Network plugin](/docs/sdks/capacitor/network/), call [getStatus()](/docs/sdks/capacitor/network/#getstatus) to read the current connection, and attach a [networkStatusChange](/docs/sdks/capacitor/network/#addlistenernetworkstatuschange-) listener to get notified whenever it changes. The plugin tells you whether the device is connected, how it is connected (Wi-Fi, cellular, ethernet, or VPN), and things the browser's `navigator.onLine` can't: whether the connection has verified internet access, whether it is metered, and whether the user has enabled a data-saving mode.

In this guide, we build network detection up step by step: reading the current status, reacting to changes, telling "connected" apart from "actually online", handling metered and data-saving connections, checking airplane mode, and putting it all together in an offline banner.

[ ![Build and deploy your Capacitor app with Capawesome Cloud](https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1) ](https://capawesome.io/) 

## Key Takeaways[¶](#key-takeaways "Permanent link")

* The [Capacitor Network plugin](/docs/sdks/capacitor/network/) (`@capawesome/capacitor-network`) reads the network status on Android, iOS, and the web through a single TypeScript API, with no permissions or configuration required.
* [getStatus()](/docs/sdks/capacitor/network/#getstatus) returns the connection state, the connection type (`WIFI`, `CELLULAR`, `ETHERNET`, `VPN`, `SATELLITE`, `NONE`, or `UNKNOWN`), and flags for constrained, expensive, and ultra-constrained connections.
* On Android, `internetReachable` reflects the system's [NET\_CAPABILITY\_VALIDATED](https://developer.android.com/reference/android/net/NetworkCapabilities#NET%5FCAPABILITY%5FVALIDATED) check, so captive portals and dead VPN tunnels don't count as "online".
* `constrained` detects Data Saver on Android and Low Data Mode on iOS; `expensive` detects metered Wi-Fi and cellular connections.
* The device is only observed while at least one listener is attached, so listening for changes doesn't cost battery when you don't need it.

## Getting the Current Network Status[¶](#getting-the-current-network-status "Permanent link")

Reading the network status takes a single call to [getStatus()](/docs/sdks/capacitor/network/#getstatus). To install the Capacitor Network plugin first, please refer to the [Installation](/docs/sdks/capacitor/network/#installation) section in the plugin documentation. Once installed, no configuration is needed; on Android, the plugin already declares the required `ACCESS_NETWORK_STATE` permission in its own manifest.

`[](#%5F%5Fcodelineno-0-1)import { Network } from '@capawesome/capacitor-network';
[](#%5F%5Fcodelineno-0-2)
[](#%5F%5Fcodelineno-0-3)const logNetworkStatus = async () => {
[](#%5F%5Fcodelineno-0-4)  const status = await Network.getStatus();
[](#%5F%5Fcodelineno-0-5)  console.log('Connected:', status.connected);
[](#%5F%5Fcodelineno-0-6)  console.log('Connection type:', status.connectionType);
[](#%5F%5Fcodelineno-0-7)};
`

The returned [GetStatusResult](/docs/sdks/capacitor/network/#getstatusresult) contains more than the two properties above:

* **`connected`**: whether the device is connected to any network.
* **`connectionType`**: how it is connected, as a typed [ConnectionType](/docs/sdks/capacitor/network/#connectiontype) enum (`WIFI`, `CELLULAR`, `ETHERNET`, `VPN`, `SATELLITE`, `NONE`, or `UNKNOWN`).
* **`internetReachable`**: whether the connection has verified access to the internet (Android only, `null` elsewhere).
* **`constrained`**: whether a data-saving mode restricts the connection.
* **`expensive`**: whether the connection is metered.
* **`ultraConstrained`**: whether bandwidth is severely limited, for example on a carrier-provided satellite network.

A word on the `null` values you'll see in some of these properties: the plugin returns `null` wherever a platform can't determine the answer, instead of guessing. That makes the API honest about platform limits, and it's why the examples below compare against `false` explicitly rather than relying on truthiness.

## Listening for Network Changes[¶](#listening-for-network-changes "Permanent link")

Polling `getStatus()` is the wrong tool for reacting to connectivity drops; instead, register a listener for the [networkStatusChange](/docs/sdks/capacitor/network/#addlistenernetworkstatuschange-) event and let the plugin push updates to you:

`[](#%5F%5Fcodelineno-1-1)import { Network } from '@capawesome/capacitor-network';
[](#%5F%5Fcodelineno-1-2)
[](#%5F%5Fcodelineno-1-3)const watchNetwork = async () => {
[](#%5F%5Fcodelineno-1-4)  await Network.addListener('networkStatusChange', status => {
[](#%5F%5Fcodelineno-1-5)    console.log('Network changed:', status.connectionType);
[](#%5F%5Fcodelineno-1-6)  });
[](#%5F%5Fcodelineno-1-7)};
`

The listener receives the same [GetStatusResult](/docs/sdks/capacitor/network/#getstatusresult) shape as `getStatus()`, so switching from Wi-Fi to cellular, losing the connection entirely, or entering Low Data Mode all arrive through the same event. The plugin only observes the device while at least one listener is attached, so there is no background cost once you clean up.

When your feature no longer needs updates, remove the listeners with [removeAllListeners()](/docs/sdks/capacitor/network/#removealllisteners):

`[](#%5F%5Fcodelineno-2-1)import { Network } from '@capawesome/capacitor-network';
[](#%5F%5Fcodelineno-2-2)
[](#%5F%5Fcodelineno-2-3)const stopWatching = async () => {
[](#%5F%5Fcodelineno-2-4)  await Network.removeAllListeners();
[](#%5F%5Fcodelineno-2-5)};
`

## Why "Connected" Doesn't Mean Online[¶](#why-connected-doesnt-mean-online "Permanent link")

A device can be connected to a network without reaching the internet. The classic case is a captive portal: hotel or airport Wi-Fi reports a healthy connection, but every request is redirected to a login page until the user signs in. A VPN whose tunnel has silently died behaves the same way. If your app starts a sync the moment `connected` turns `true`, both cases produce failed requests and confused users.

This is what the `internetReachable` property is for. On Android, it reflects the [NET\_CAPABILITY\_VALIDATED](https://developer.android.com/reference/android/net/NetworkCapabilities#NET%5FCAPABILITY%5FVALIDATED) capability, meaning the operating system has actually verified that the connection reaches the internet:

`[](#%5F%5Fcodelineno-3-1)import { Network } from '@capawesome/capacitor-network';
[](#%5F%5Fcodelineno-3-2)
[](#%5F%5Fcodelineno-3-3)const canSync = async () => {
[](#%5F%5Fcodelineno-3-4)  const { connected, internetReachable } = await Network.getStatus();
[](#%5F%5Fcodelineno-3-5)  return internetReachable ?? connected;
[](#%5F%5Fcodelineno-3-6)};
`

On iOS and the web, `internetReachable` is always `null`, because those platforms can't distinguish validated internet access from mere connectivity. The `?? connected` fallback above handles that cleanly: use the verified answer where the platform provides one, and fall back to the connection state everywhere else.

## Detecting Metered and Data-Saving Connections[¶](#detecting-metered-and-data-saving-connections "Permanent link")

Not every connection should be treated equally, even when it works perfectly. Users on metered hotspots or limited data plans don't want your app to pull hundreds of megabytes in the background, and both Android (Data Saver) and iOS (Low Data Mode) let them say so system-wide. The `expensive` and `constrained` properties expose exactly these signals, so a download queue can respect them:

`[](#%5F%5Fcodelineno-4-1)import { Network } from '@capawesome/capacitor-network';
[](#%5F%5Fcodelineno-4-2)
[](#%5F%5Fcodelineno-4-3)const shouldDownloadLargeFiles = async () => {
[](#%5F%5Fcodelineno-4-4)  const { connected, expensive, constrained } = await Network.getStatus();
[](#%5F%5Fcodelineno-4-5)  return connected && expensive === false && constrained === false;
[](#%5F%5Fcodelineno-4-6)};
`

The strict `=== false` comparisons matter here. Both properties are `null` on platforms that can't determine them (for example, most browsers), and treating "unknown" the same as "cheap and unrestricted" would defeat the purpose of the check.

## Checking Airplane Mode on Android[¶](#checking-airplane-mode-on-android "Permanent link")

When the connection type is `NONE`, it helps to tell the user why. On Android, [isAirplaneModeEnabled()](/docs/sdks/capacitor/network/#isairplanemodeenabled) answers one common cause directly:

`[](#%5F%5Fcodelineno-5-1)import { Network } from '@capawesome/capacitor-network';
[](#%5F%5Fcodelineno-5-2)
[](#%5F%5Fcodelineno-5-3)const explainOffline = async () => {
[](#%5F%5Fcodelineno-5-4)  const { enabled } = await Network.isAirplaneModeEnabled();
[](#%5F%5Fcodelineno-5-5)  return enabled
[](#%5F%5Fcodelineno-5-6)    ? 'Airplane mode is on. Disable it to reconnect.'
[](#%5F%5Fcodelineno-5-7)    : 'You are offline. Check your connection.';
[](#%5F%5Fcodelineno-5-8)};
`

This method is Android-only, since iOS offers no public API for reading the airplane mode state and browsers don't expose it either.

## Building an Offline Banner[¶](#building-an-offline-banner "Permanent link")

The most common use of network detection is also the simplest: an offline banner that appears when the connection drops and disappears when it comes back. Combining the initial status read with the change listener covers both the app launch and every change afterwards:

`[](#%5F%5Fcodelineno-6-1)import { Network } from '@capawesome/capacitor-network';
[](#%5F%5Fcodelineno-6-2)
[](#%5F%5Fcodelineno-6-3)const toggleOfflineBanner = (offline: boolean) => {
[](#%5F%5Fcodelineno-6-4)  document.getElementById('offline-banner')?.classList.toggle('hidden', !offline);
[](#%5F%5Fcodelineno-6-5)};
[](#%5F%5Fcodelineno-6-6)
[](#%5F%5Fcodelineno-6-7)const setupOfflineBanner = async () => {
[](#%5F%5Fcodelineno-6-8)  const status = await Network.getStatus();
[](#%5F%5Fcodelineno-6-9)  toggleOfflineBanner(!status.connected);
[](#%5F%5Fcodelineno-6-10)
[](#%5F%5Fcodelineno-6-11)  await Network.addListener('networkStatusChange', status => {
[](#%5F%5Fcodelineno-6-12)    toggleOfflineBanner(!(status.internetReachable ?? status.connected));
[](#%5F%5Fcodelineno-6-13)  });
[](#%5F%5Fcodelineno-6-14)};
`

The same pattern maps directly to a state variable in Angular, React, or Vue: read once on startup, subscribe for changes, and drive the banner from a single boolean. Note the reachability fallback from earlier reappearing in the listener, so Android users behind a captive portal see the banner even though they are technically connected.

## FAQ[¶](#faq "Permanent link")

### What is the difference between `connected` and `internetReachable`?[¶](#what-is-the-difference-between-connected-and-internetreachable "Permanent link")

`connected` tells you whether the device is on any network at all, while `internetReachable` tells you whether that network has verified access to the internet. The two disagree behind captive portals and broken VPN tunnels, where the device is connected but nothing gets through. `internetReachable` is only available on Android and is `null` on iOS and the web.

### How is this plugin different from the official Capacitor Network plugin?[¶](#how-is-this-plugin-different-from-the-official-capacitor-network-plugin "Permanent link")

The official `@capacitor/network` plugin reports the connection state and a basic connection type. The [Capacitor Network plugin](/docs/sdks/capacitor/network/) from Capawesome additionally reports verified internet reachability on Android, data-saving and metered connection flags, satellite and ultra-constrained network detection, an airplane mode check, and distinguishes ethernet and VPN connections as their own connection types.

### Do I need any permissions to detect the network status?[¶](#do-i-need-any-permissions-to-detect-the-network-status "Permanent link")

No. The plugin works without configuration on all platforms. The `ACCESS_NETWORK_STATE` permission it needs on Android is declared in the plugin's own manifest, so there is nothing to add to your app.

### Does network detection work in the browser?[¶](#does-network-detection-work-in-the-browser "Permanent link")

Yes. On the web, the plugin reads [navigator.onLine](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) and the [Network Information API](https://developer.mozilla.org/en-US/docs/Web/API/Network%5FInformation%5FAPI) where the browser supports it. Properties that browsers can't provide, such as `internetReachable`, are `null` there.

### Why is a VPN connection reported as `UNKNOWN` on iOS?[¶](#why-is-a-vpn-connection-reported-as-unknown-on-ios "Permanent link")

On iOS, the plugin reads the network status from the [NWPathMonitor](https://developer.apple.com/documentation/network/nwpathmonitor) of the Network framework, which does not identify VPN tunnels as a distinct interface type. The `VPN` connection type is therefore only reported on platforms that can detect it, such as Android.

## Try Capawesome[¶](#try-capawesome "Permanent link")

The quickest way to make this stick is to add the offline banner from this guide to your own app. Subscribe below to get new Capacitor guides like this one as they are published.

[Subscribe to the Capawesome Newsletter](https://capawesome.io/newsletter/)

## Conclusion[¶](#conclusion "Permanent link")

Detecting the network status in a Capacitor app comes down to two calls: [getStatus()](/docs/sdks/capacitor/network/#getstatus) for the current state and a [networkStatusChange](/docs/sdks/capacitor/network/#addlistenernetworkstatuschange-) listener for everything after. The properties beyond `connected` are where the real quality wins live: `internetReachable` keeps captive portals from looking like working connections, and `expensive` and `constrained` keep large downloads off networks where they hurt.

There is one connection type we deliberately skipped here: satellite. Detecting it, and adapting your app to its extreme bandwidth limits on Android 15+ and iOS 26, is covered in [How to Detect Satellite Networks in Capacitor](/blog/how-to-detect-satellite-networks-in-a-capacitor-app/). If you have questions, join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW), and subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/) to stay up to date with new plugins and guides.

August 8, 2026 

Back to top

```json
{
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      "headline": "How to Detect the Network Status in Capacitor",
      "description": "Learn how to detect the network status in a Capacitor app: check the connection type, listen for changes, and handle offline and metered connections.",
      "image": "https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png",
      "datePublished": "2026-08-08T00:00:00+00:00",
      "dateModified": "2026-08-08T00:00:00+00:00",
      "author": [
        {
          "@type": "Person",
          "name": "Robin Genz",
          "url": "https://github.com/robingenz"
        }
      ],
      "publisher": {
        "@type": "Organization",
        "name": "Capawesome",
        "url": "https://capawesome.io",
        "logo": {
          "@type": "ImageObject",
          "url": "https://capawesome.io/assets/images/logo.svg"
        }
      },
      "articleSection": "Capacitor",
      "keywords": ["Capacitor", "Guides", "SDKs"],
      "isPartOf": {
        "@type": "Blog",
        "@id": "https://capawesome.io/blog/#blog"
      },
      "mainEntityOfPage": "https://capawesome.io/blog/how-to-detect-the-network-status-in-a-capacitor-app/",
      "url": "https://capawesome.io/blog/how-to-detect-the-network-status-in-a-capacitor-app/"
    }
{
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://capawesome.io/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Blog",
          "item": "https://capawesome.io/blog/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "How to Detect the Network Status in Capacitor",
          "item": "https://capawesome.io/blog/how-to-detect-the-network-status-in-a-capacitor-app/"
        }
      ]
    }
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What is the difference between connected and internetReachable?", "acceptedAnswer": {"@type": "Answer", "text": "connected tells you whether the device is on any network at all, while internetReachable tells you whether that network has verified access to the internet. The two disagree behind captive portals and broken VPN tunnels, where the device is connected but nothing gets through. internetReachable is only available on Android and is null on iOS and the web."}}, {"@type": "Question", "name": "How is this plugin different from the official Capacitor Network plugin?", "acceptedAnswer": {"@type": "Answer", "text": "The official @capacitor/network plugin reports the connection state and a basic connection type. The Capacitor Network plugin from Capawesome additionally reports verified internet reachability on Android, data-saving and metered connection flags, satellite and ultra-constrained network detection, an airplane mode check, and distinguishes ethernet and VPN connections as their own connection types."}}, {"@type": "Question", "name": "Do I need any permissions to detect the network status?", "acceptedAnswer": {"@type": "Answer", "text": "No. The plugin works without configuration on all platforms. The ACCESS_NETWORK_STATE permission it needs on Android is declared in the plugin's own manifest, so there is nothing to add to your app."}}, {"@type": "Question", "name": "Does network detection work in the browser?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. On the web, the plugin reads navigator.onLine and the Network Information API where the browser supports it. Properties that browsers can't provide, such as internetReachable, are null there."}}, {"@type": "Question", "name": "Why is a VPN connection reported as UNKNOWN on iOS?", "acceptedAnswer": {"@type": "Answer", "text": "On iOS, the plugin reads the network status from the NWPathMonitor of the Network framework, which does not identify VPN tunnels as a distinct interface type. The VPN connection type is therefore only reported on platforms that can detect it, such as Android."}}], "url": "https://capawesome.io/blog/how-to-detect-the-network-status-in-a-capacitor-app/"}
```
