# Local Network Access: a local-request prompt

> How Chrome shows a Local Network Access permission prompt before a public page can reach a device on the local network, replacing silent preflight-only checks.

**In one line:** Local Network Access is a browser permission prompt, shown before a page
running on the public internet is allowed to send a request to a device on the user's
local network (for example a router, printer, or local app server).

## Why a prompt, not just a preflight

The specification's predecessor, Private Network Access, let a local device opt in to
being contacted by sending a CORS preflight response header — no user in the loop at all.
Per the explainer, that preflight-only model required changes to devices on the local
network, whereas sites are far easier to update. Local Network Access replaces the PNA
preflight gate with a browser-side permission prompt instead, shifting the burden to the
public-origin website rather than to the local device. Per the specification, a user
agent may persist this permission decision to reduce permission fatigue, but the exact
scope of the grant — for example per origin, per device, or per network — is left
implementation-defined.

## How the prompt is triggered

Per the Chrome for Developers blog, a public page's own request to a local-network or
loopback address is what triggers the prompt — a developer does not call a separate API to
ask for the permission first:

```js
// A page served from a public origin, fetching a device on the
// user's local network (e.g. a router's status endpoint).
const response = await fetch('http://192.168.1.1/status');
```

Chrome began offering this behind a flag (`chrome://flags/#local-network-access-check`,
set to "Enabled (Blocking)") from Chrome 138, and turned the prompt on by default in
Chrome 142. Per the Chrome blog, pages that rely on it must be served over a secure
context (HTTPS), must handle a denied prompt gracefully, and can use Permissions Policy to
delegate the access to an iframe.

## Where it is supported

Per the Chrome for Developers blog, the Local Network Access prompt shipped by default in
Chrome 142, after an opt-in testing period starting in Chrome 138. The specification is
developed in the WICG and, per the explainer, some of its behaviour — such as whether
cross-origin requests between two local-network origins are also gated — is left to each
implementer's discretion; the explainer states that Chromium currently only enforces the
permission for requests from a public origin to a local or loopback address, not for
local-to-local cross-origin requests.

## Feature detection and fallback

There is no dedicated "does this browser gate Local Network Access" call, but the
`targetAddressSpace` property on `Request` is part of the same effort and its presence is
a reasonable signal that the browser's fetch stack understands local-network address
spaces at all. Check that alongside the secure-context requirement before attempting the
request, and treat any resulting failure generically — a rejected or throwing request can
mean an unsupported browser, an insecure context, a user-denied prompt, a CORS failure, or
simply an offline device, and (before Local Network Access shipped) a public page could
reach local addresses without any of this failing at all, so a failure must not be
attributed to a specific cause:

```js
function supportsLocalNetworkAddressSpaces() {
  return typeof Request !== 'undefined' && 'targetAddressSpace' in Request.prototype;
}

async function pingLocalDevice(url) {
  if (!window.isSecureContext || !supportsLocalNetworkAddressSpaces()) {
    // Either this browser doesn't expose the local-network address-space surface,
    // or the page isn't in a secure context, so the request cannot rely on it.
    return false;
  }
  try {
    const res = await fetch(url);
    return res.ok;
  } catch {
    // The request failed for an unknown reason (denied prompt, CORS, offline
    // device, or something else): fall back to asking the user to check the
    // device manually instead of retrying silently or guessing the cause.
    return false;
  }
}
```

## Practical checklist

- [ ] Per the Chrome blog, the requesting page must run in a secure context (HTTPS) —
      local-network requests from an insecure page are not eligible for the prompt at all.
- [ ] Treat a denied or unsupported request as a normal, expected outcome: catch the
      failure and show the user a manual fallback rather than retrying the same request.
- [ ] Do not rely on a device's old Private Network Access preflight opt-in header to
      bypass the prompt — Local Network Access replaced that server-side opt-in with a
      browser-side permission the local device cannot control.
- [ ] Per the explainer, Chromium does not currently gate local-to-local cross-origin
      requests the same way it gates public-to-local ones — do not assume every
      local-network request path is covered.
- [ ] If embedding local-network functionality in an iframe, delegate the permission
      explicitly with Permissions Policy rather than assuming it is inherited.

## Where to go next

- [Web Locks API](/reference/capabilities/web-locks/)
- [Idle Detection API](/reference/capabilities/idle-detection/)