In Cypress, what happens to a request whose host matches a `blockHosts` pattern?
answer
- The request never leaves the machine
- A specific status code comes back
- A response header names the rule
- Host only, no scheme
- Ports matter when non-standard
basics
~10 sCypress ends the request itself and answers 503, adding an x-cypress-matched-blocked-host header naming the pattern that matched. The request is never sent, so it resolves immediately instead of waiting on a third party.
solid answer
~40 sCypress ends the request and answers `503`, adding an `x-cypress-matched-blocked-host` response header naming the rule that matched, so you can see it in the browser's network panel. Nothing is sent to that host, which is why blocking analytics and monitoring endpoints speeds a suite up. Patterns are matched with the `minimatch` library against the **host only**: pass `metrics.pdfviewer.example`, never `https://metrics.pdfviewer.example`, and include the port when it is not `80` or `443`, as in `localhost:1234`. Wildcards work, with one trap: `*pdfviewer.example` matches the apex domain and its subdomains, while `*.pdfviewer.example` matches subdomains only. `blockHosts` runs in Cypress's request middleware, which is shared by the native browser network and the legacy path, so Chrome and Firefox behave the same here.
code
javascript · 17 lines// cypress.config.js
module.exports = {
e2e: {
baseUrl: 'http://localhost:3000',
blockHosts: [
'metrics.pdfviewer.example',
'*.telemetry.pdfviewer.example',
'errors.statements-bank.example',
],
},
}
// statements.cy.js
it('renders the August statement without third-party telemetry', () => {
cy.visit('/statements/2026-08')
cy.get('[data-cy=pdf-frame]').should('be.visible')
})go deeper
Be able to write a working entry from memory: host only, no scheme, wildcards allowed. Know that the blocked request comes back as a 503 rather than silently disappearing.
Explain how the match is performed and why the port rule exists. Be ready to say why blocking third-party hosts speeds a run up, and where the matched-rule header shows up.
Expect a scenario where a block appears not to fire. Show how you confirm it from the response header and the network panel rather than adding more patterns and hoping.
Frame it as a policy: which classes of third-party traffic a suite blocks by default, who owns that list, and when blocking hides a production question the team should be asking instead.
## What a block actually does `blockHosts` is a Cypress configuration option that takes a host pattern, or an array of them. When a request's host matches one, **Cypress ends the request itself**: nothing leaves your machine, no connection is opened to that third party, and the browser is answered with - status **`503`**, and - an **`x-cypress-matched-blocked-host`** response header naming the pattern that matched. That header is the debugging affordance. When a bank-statement suite blocks four telemetry hosts and one page still stalls, opening the browser's network panel and reading which rule matched tells you in seconds whether the block fired at all. Because the request never goes out, blocked requests resolve **immediately**. That is why blocking analytics, error-monitoring and A/B-testing hosts is a standard way to take dead time out of a suite: the third-party PDF viewer embedded in the statements page may ping a metrics endpoint on every render, and none of it is under test. ## Writing the pattern Patterns are matched with the `minimatch` library (also exposed to specs as `Cypress.minimatch`) against the **host** of the URL, after the protocol and the default ports are stripped. That gives four rules: - ✅ Pass **only the host**: `metrics.pdfviewer.example`. - ❌ Never include the protocol: `https://metrics.pdfviewer.example` matches nothing. - ✅ Use `*` wildcards: `*pdfviewer.example`, `*.pdfviewer.example`. - ✅ Include the port **when it is not `80` or `443`**: `localhost:1234` needs its port, an `https` host on `443` does not. Given `https://metrics.pdfviewer.example/collect`, all three of `metrics.pdfviewer.example`, `*.pdfviewer.example` and `*pdfviewer.example` match. Given `http://localhost:1234/statements.json`, only `localhost:1234` matches — `localhost` alone does not. ## The subdomain trap This is the mistake that costs an afternoon. For a URL with **no subdomain** — say `https://pdfviewer.example/embed.js`: 1. `pdfviewer.example` matches. 2. `*pdfviewer.example` matches, because the wildcard can expand to nothing. 3. `*.pdfviewer.example` does **not** match, because the literal dot has nothing before it. So a list written as `*.pdfviewer.example` silently lets the apex domain through, and the block appears not to work. When a pattern is not behaving, test it against the URL directly rather than staring at it. ## Where it sits relative to the network path `blockHosts` is enforced in Cypress's **request middleware**, which is shared by both transports: the native browser network used by Chrome, Chromium and Edge as of Cypress 16, and the legacy proxy path used by Firefox, WebKit and Electron. **The behaviour is identical on both**, so a cross-browser suite does not need a second rule set. That is worth knowing because several other network behaviours *do* differ by browser in Cypress 16, and this one deliberately does not. ## What it is not for - It is not a stub. A blocked host returns `503`; if your app needs a *shaped* response from that endpoint, blocking is the wrong tool. - It is not a security control. It removes noise from a test run; it says nothing about what your application does in production. - It is not a per-command switch. `blockHosts` is resolved as configuration, and the scope you set it at decides which tests see it — a suite or test configuration object is the way to narrow it to the specs that need it. - It is not a substitute for asking why the request exists. If the statements page fires a telemetry call on every scroll, blocking it in tests hides a question worth asking of production. ## Reading a block that did not fire When a suite is still slow and the telemetry request is still in the network panel, work the evidence rather than the pattern list: 1. Look for the **`x-cypress-matched-blocked-host`** header on the request. If it is there, the block fired and something else is costing the time. 2. If it is absent, compare the request's **host** — not its full URL — against your patterns, and remember that the path, the query string and a default port are not part of the match. 3. Check for the apex-domain case above; a `*.` prefix is the single most common reason a pattern looks right and matches nothing. 4. Check the **scope** the option was resolved at. `blockHosts` is configuration, so a value set on one suite does not apply to a spec that never enters it. ## Recognising a good answer A strong answer names the `503`, names host-only matching, and mentions at least one of the wildcard or port rules unprompted. It also treats blocking as a **suite-hygiene** decision rather than a per-test trick: a short, reviewed list of analytics, error-monitoring and A/B hosts that the whole suite blocks is maintainable, whereas a dozen ad-hoc patterns scattered through specs is not. A weak answer says "it blocks the request" and then writes `https://` into the pattern.
- Why does the pattern `*.pdfviewer.example` fail to block a request to `https://pdfviewer.example/embed.js`?Because the pattern requires a literal dot after the wildcard, and the apex domain has nothing before that dot. `*.pdfviewer.example` matches subdomains only. Use `*pdfviewer.example` to catch both the apex domain and its subdomains, or list the apex host explicitly alongside the subdomain pattern.
- Does `blockHosts` behave differently in Chrome and Firefox in Cypress 16?No. Chrome, Chromium and Edge intercept on the native browser network while Firefox, WebKit and Electron use the legacy proxy path, but `blockHosts` is enforced in request middleware that both transports share. A matched host is ended with a `503` in either browser, with the same matching rules.
saying these in an interview costs you the question
- Writes the protocol into the pattern
- Expects a 404 or a network error instead
- Thinks blockHosts stubs a response body
- Omits a non-standard port from the pattern
- Assumes *.host also matches the apex domain