Chrome Extension Proxy Setup
Chrome's Extension API provides the chrome.proxy namespace for routing browser traffic through proxy servers. This API is exclusive to browser extensions and offers capabilities not available through any other method: system-wide proxy routing, per-profile proxy isolation, PAC script support for complex routing rules, and programmatic proxy toggle.
Building a proxy extension with Hex Proxies lets end users switch between proxy-enabled and direct browsing with a single click. The extension handles authentication transparently through the webRequest.onAuthRequired listener, so users never see a proxy login prompt.
Prerequisites
Before you begin, make sure you have: - An active Hex Proxies account with proxy credentials - Chrome browser - Manifest V3 extension with proxy permission - webRequest and webRequestAuthProvider permissions
Manifest Configuration
Your manifest.json must declare the proxy, webRequest, and webRequestAuthProvider permissions. Without webRequestAuthProvider, Chrome cannot use asyncBlocking mode for the authentication listener.
Basic Proxy Configuration
Use chrome.proxy.settings.set() with a fixed_servers mode configuration pointing to gate.hexproxies.com:8080.
// manifest.json permissions needed:
// "permissions": ["proxy", "webRequest",// background.js - Configure proxy const config = { mode: 'fixed_servers', rules: { singleProxy: { scheme: 'http', host: 'gate.hexproxies.com', port: 8080, }, bypassList: ['localhost', '127.0.0.1'], }, };
chrome.proxy.settings.set( { value: config, scope: 'regular' }, () => console.log('Proxy configured') );
// Handle proxy authentication chrome.webRequest.onAuthRequired.addListener( (details, callback) => { callback({ authCredentials: { username: 'user', password: 'pass', }, }); }, { urls: ['<all_urls>'] }, ['asyncBlocking'] );
// Toggle proxy on/off function toggleProxy(enabled) { if (enabled) { chrome.proxy.settings.set( { value: config, scope: 'regular' } ); } else { chrome.proxy.settings.clear({ scope: 'regular' }); } } ```
PAC Script Mode for Advanced Routing
For complex routing rules like proxying only specific domains or using different proxies per destination, use mode: 'pac_script' with an inline PAC function. This lets you route social media through one Hex Proxies region and ecommerce through another.
Incognito Scope Isolation
Set scope: 'incognito_persistent' to apply proxy settings only in incognito windows, keeping regular browsing direct. This is useful for testing proxy behavior without affecting your normal browsing session.
Extension Conflict Resolution
Only one extension can control chrome.proxy.settings at a time. Chrome uses a priority system where the most recently installed extension wins. Use chrome.proxy.settings.get() to verify your settings are active and not overridden by another extension.
Configuration Options
- **Proxy Mode** -- fixed_servers for single proxy, pac_script for domain-based routing, direct for no proxy.
- **Bypass List** -- Array of domains and IP ranges excluded from proxy routing (localhost, internal networks).
- **Auth Handler** -- webRequest.onAuthRequired with asyncBlocking mode for transparent credential injection.
- **Scope** -- regular for all windows, incognito_persistent for incognito only.
- **Toggle** -- chrome.proxy.settings.clear() to disable, .set() to re-enable.
Error Handling
Chrome extension proxy errors require checking both the chrome.runtime.lastError and proxy-specific error events.
- chrome.proxy.settings.set() silently fails
- - Another extension is overriding your proxy settings
- - Check chrome://extensions for conflicting proxy extensions
- - Use chrome.proxy.settings.get() to verify your config is active
2. onAuthRequired not firing - Missing webRequestAuthProvider permission in manifest.json - Ensure asyncBlocking is in the extraInfoSpec array - Verify the listener URL filter matches the proxy auth challenge
3. ERR_PROXY_CONNECTION_FAILED in browser - The proxy server is unreachable from the user's network - Add a connectivity check in the extension popup - Fall back to direct mode with chrome.proxy.settings.clear()
4. Bypass list not working - Entries must be hostnames without protocol prefix - Use <local> keyword for all local addresses - Wildcards: *.example.com for all subdomains
5. Extension disabled after Chrome update - Manifest V2 extensions may be auto-disabled - Migrate to Manifest V3 with service workers - Use chrome.runtime.onInstalled to re-apply proxy settings after updates ```
Use chrome.proxy.onProxyError listener to catch and log proxy errors that occur during browsing.