Tutorial ~19 min read

Route Chrome Only via Clash: PAC and System Proxy Steps (2026)

Many people want the opposite of “turn on system proxy and route the whole PC.” They need the office stack—Outlook, Teams, internal SSO, or a mandated corporate PAC—to keep using the paths IT expects, while Google Chrome alone talks to a local Clash listener for research tabs, docs, or APIs. Flipping Windows or macOS into global proxy mode breaks that balance: store apps misbehave, captive portals get weird, and you inherit every side effect we catalog in the Windows UWP and system proxy article. The fix is deliberate separation—leave the OS profile alone, run Clash Verge Rev (or any Meta-class GUI) with system proxy disabled, and hand Chrome a browser-only PAC or launch flag that forwards only the hostnames you choose to 127.0.0.1 on your mixed port. This walkthrough explains that stack end to end for 2026.

Clash Editorial Team Chrome · PAC · Clash · Windows · macOS

Why split the browser from system proxy?

System proxy settings on both Windows and macOS are coarse. They influence any application that asks the OS for “the current proxy configuration,” which includes more than your browser. A developer on a work laptop might rely on a corporate PAC for split tunneling to internal subnets while consumer sites exit through a regional head-end. A student might want direct routing for local LAN games but still need a foreign IP when reading papers. Turning on a consumer client’s system proxy toggle replaces that story with a single choke point—often correct for personal machines, wrong for mixed environments.

Chrome can honor its own proxy policy independently when you start it with explicit arguments or managed policies. A small PAC file is the classic way to express “these domains go to PROXY 127.0.0.1:PORT, everything else is DIRECT.” Meanwhile Clash continues to apply rules, proxy groups, and DNS logic to whatever actually reaches its inbound. You get two layers: the PAC decides whether the browser sends traffic to Clash at all; Clash decides which outbound and resolver path apply once the session arrives. That separation is powerful—and it is the mental model you should keep when debugging.

Clash baseline: mixed port on, system proxy off

Open your GUI—this article assumes Clash Verge Rev or an equivalent Meta frontend. Import your subscription, pick a healthy node or group, and note the mixed port (often 7890 in fresh profiles, but verify in the UI). The mixed listener accepts HTTP CONNECT and SOCKS on the same port depending on client behavior; Chrome’s PROXY directive in PAC targets HTTP-style forwarding, which Clash’s mixed port handles in typical setups.

Critically, disable the client’s system proxy toggle for this workflow. You want Windows or macOS to keep whatever they already use—direct, DHCP-only, or corporate automation. If you previously enabled system capture for testing, flip it off and confirm in OS network settings that manual proxy rows are cleared. On macOS, if a helper left stale entries behind, our macOS system proxy troubleshooting guide walks through Keychain and scutil --proxy verification so you are not fighting ghosts.

Rule mode still matters: Keep Clash in Rule mode with sensible defaults so that traffic you send to localhost is not accidentally forced through an unhealthy Global path. Your PAC is not a substitute for YAML hygiene.

Author a minimal PAC file

Save a text file such as chrome-clash.pac in a stable directory. The script below is illustrative: it sends common research and collaboration host patterns to your local mixed port and leaves the rest DIRECT. Expand the lists to match your actual browsing—there is no universal block list, and over-inclusive PAC files are how people accidentally steer payroll portals into Clash.

function FindProxyForURL(url, host) {
  // Local and RFC1918: never loop through Clash
  if (isPlainHostName(host) ||
      shExpMatch(host, "*.local") ||
      isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
      isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
      isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
      isInNet(dnsResolve(host), "127.0.0.0", "255.0.0.0")) {
    return "DIRECT";
  }

  // Example: send these trees to Clash mixed port (change if yours differs)
  if (dnsDomainIs(host, "google.com") ||
      dnsDomainIs(host, "youtube.com") ||
      dnsDomainIs(host, "gstatic.com") ||
      dnsDomainIs(host, "github.com") ||
      dnsDomainIs(host, "openai.com")) {
    return "PROXY 127.0.0.1:7890";
  }

  return "DIRECT";
}

A few PAC details trip newcomers. Calls like dnsResolve execute at evaluation time; if resolver behavior differs from Clash’s DNS section, you can see mismatches between what PAC thinks is DIRECT and what Clash would have done internally—usually fine for split-browser use, but worth remembering when a hostname resolves oddly on corporate Wi-Fi. Also keep literals honest: replace 7890 with your real mixed port from the GUI.

Windows: launch Chrome with a file PAC URL

On Windows, the reliable pattern is a desktop or Start Menu shortcut that invokes chrome.exe with --proxy-pac-url. The argument must be a URL; for local files use three slashes after file: and convert backslashes to forward slashes. If the PAC lives at C:\Users\you\proxy\chrome-clash.pac, the value looks like file:///C:/Users/you/proxy/chrome-clash.pac.

Close every Chrome window, then start Chrome from that shortcut. In the address bar, open chrome://net-export or inspect chrome://net-internals/#proxy on builds where available to confirm the effective PAC. You should see hits to your Clash Connections pane when visiting hosts matched in the script, while unrelated sites never appear there—proof the split is working.

If you also use WSL2 or dev tools that expect a different capture story, our WSL2, Git, and npm on Windows guide explains how Linux guests interact with the host proxy table; browser PAC does not replace that layer, it complements it.

macOS: same flags, different path quoting

On macOS, the binary lives inside the app bundle. A Terminal one-liner might look like open -na "Google Chrome" --args --proxy-pac-url="file:///Users/you/proxy/chrome-clash.pac", or you can build an Automator app that wraps the same arguments. Spaces in usernames are common; escape or quote carefully so the PAC URL is not truncated.

Safari and other browsers will continue to follow system proxy unless you configure them separately—exactly the outcome many readers want. If you later need machine-wide capture for stubborn binaries, graduate to TUN using the Clash Verge Rev TUN mode guide; that is a different contract than browser-only PAC and should not be mixed casually on locked-down laptops.

Optional: serve PAC over HTTP on localhost

Some teams prefer http://127.0.0.1:8089/chrome-clash.pac served by a tiny static file server instead of file:// URLs. That pattern makes iteration faster—you edit the PAC and reload, without re-launching Chrome—and it mirrors how enterprise IT often distributes scripts. Security-wise, bind only to loopback and treat the file like credentials-adjacent configuration: anyone with local code execution can already change your proxy, so the threat model is local misuse, not remote fetch.

Enterprise policies and separate Chrome profiles

Managed environments sometimes block raw launch flags. On Windows, administrators can map ProxyMode and ProxyPacUrl through Group Policy; on macOS, a configuration profile can do the same. If you control the machine, a dedicated Chrome profile (a separate user-data directory) keeps personal extensions and cookies away from the PAC experiment and avoids corrupting a default work profile.

Two policy layers: PAC versus Clash rules

When you send a tab to 127.0.0.1:7890, Clash still evaluates YAML: GEOIP, DOMAIN-SUFFIX, PROCESS-NAME, and the rest execute as usual. That means your PAC can be conservative—only domains you truly want inspected—and Clash can still split exits by rule once traffic arrives. Conversely, if your PAC returns DIRECT, Clash never sees that flow; no amount of beautiful rules will rewrite it.

DNS follows the same split-brain story. Browser DNS for PAC evaluation may use the system resolver, while Clash may use fake-ip or encrypted DNS for flows it captures. For most reader goals that is acceptable; if you need stricter alignment, study the Meta core DNS leak prevention article after you confirm baseline routing.

Failure modes and quick checks

Symptom: Chrome loads, but nothing hits Clash. Verify the mixed port, confirm Clash is running in Rule or Global as intended, and re-read your shortcut for typos—especially file:/// versus file://. Symptom: only some Google properties break. Modern Google surfaces span dozens of hostnames; widen PAC suffix coverage based on what you see in DevTools network columns or Clash logs. Symptom: intranet sites suddenly fail. Your PAC probably routes too aggressively; tighten conditions or add explicit DIRECT branches for corporate domains.

Symptom: performance feels worse than full system proxy. You are now paying for double evaluation—PAC matching plus Clash rules—and that is expected. The win is operational: fewer apps touched, less help-desk risk, cleaner rollback by simply closing the Chrome shortcut.

Compliance: Bypassing employer monitoring or exfiltrating data through personal proxies can violate policy or law. Use this architecture only where you have permission; the technical steps are neutral, the governance is not.

Checklist before you call it done

1Confirm Clash listens where PAC points

Mixed port matches, no firewall block on loopback, and the GUI shows active connections when you load a test site that should traverse the proxy.

2Prove OS proxy stayed untouched

On Windows, inspect Settings → Network → Proxy; on macOS, inspect the active interface’s proxy pane or run scutil --proxy. You should not see Clash’s port unless you deliberately enabled system mode elsewhere.

3Document your PAC and shortcut

Future you will forget whether 7890 or 7897 was canonical. Store the PAC in version control or a notes doc alongside a screenshot of the working shortcut target line.

Open source and downloads

Clash-class cores and their GUIs publish sources for audit and issue tracking; GitHub remains the right place for changelogs and signatures. When you need installers without hunting tags, use the site’s official download page so builds stay consistent with the tutorials you follow here.

Summary

Separating Chrome from system proxy is a pairing of discipline: keep Clash on a mixed port with OS capture disabled, then give Chrome a PAC that forwards only the hostnames you need through 127.0.0.1. Windows and macOS differ in shortcut syntax, but the architecture is identical—browser-local policy first, YAML second. Compared with toggling global proxies, you reduce collateral damage to store apps, corporate stacks, and background updaters while still leaning on Clash for the tabs that actually need it.

When you want a client that makes mixed ports, rule tuning, and optional TUN feel like one coherent toolkit rather than a pile of forum snippets, start from a distribution you trust and iterate in small steps—

Download Clash for free and experience the difference

Clash Client Chrome · PAC · System proxy

A PAC script lets Chrome use Clash exclusively while other browsers stay on a direct connection—combining PAC with system proxy separation gives per-app routing without touching each app's settings.

Official builds

Windows, macOS, Linux, Android from the download hub

Chrome-only proxy

PAC routes only Chrome through Clash rules

System proxy split

Other apps remain on a direct connection

Config guides

Pair with PAC and system proxy articles

Previous & Next

Related Reading

Chrome-only Clash routing?

Grab Clash from our download page, disable system proxy in the GUI, point Chrome at a PAC that forwards chosen hosts to your mixed port—keep the rest of the OS on direct or corporate paths.

Download Free Client