v147 · Security · Local Network Access

Compatibility Lab

Probes service worker availability, classifies page origin context, and shows which WindowClient.navigate() target URLs are blocked in Chrome 147. Provides the postMessage-based alternative for service workers that need to signal navigation to private network resources.

API probes

WindowClient.navigate() LNA enforcement matrix

SW registration originnavigate() targetChrome 147 result
Public (https://example.com)http://192.168.1.1/adminBLOCKED — LNA restriction
Public (https://example.com)http://localhost:3000BLOCKED — LNA restriction
Public (https://example.com)https://example.com/otherALLOWED — same origin
Public (https://example.com)https://api.example.com/ALLOWED — public to public
Private (http://192.168.x.x)http://192.168.1.1/adminALLOWED — same tier
Localhost (http://localhost)http://localhost:3000ALLOWED — loopback to loopback

Live context probe

Service worker + LNA context check
Click "Run probe" to inspect service worker and LNA context…

postMessage alternative pattern

/* WindowClient.navigate() LNA restriction — Chrome 147 */ /* In Chrome 147+, a public-origin SW cannot navigate a window client to a private network URL. Instead of navigate(), send a message to the client and let the page handle the navigation itself (from its own origin). */ /* service-worker.js */ self.addEventListener('message', async (event) => { if (event.data.type !== 'nav-to-private') return; const clients = await self.clients.matchAll({ type: 'window' }); for (const client of clients) { /* BLOCKED in Chrome 147 from a public SW: */ // await client.navigate('http://192.168.1.1/admin'); /* SAFE alternative: postMessage back to the page */ client.postMessage({ type: 'navigate', url: event.data.url }); } }); /* page.js — handle the navigation message */ navigator.serviceWorker.addEventListener('message', (e) => { if (e.data.type === 'navigate') { window.location.href = e.data.url; } }); /* Classify a URL target for LNA purposes */ function isPrivateNetworkTarget(url) { try { const { hostname } = new URL(url); if (hostname === 'localhost' || hostname === '127.0.0.1') return true; if (/^192\.168\./.test(hostname)) return true; if (/^10\./.test(hostname)) return true; if (/^172\.(1[6-9]|2\d|3[01])\./.test(hostname)) return true; return false; } catch { return false; } }

references

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗