# Fix the Playwright locale context agent failing to set the accept-language header

## TL;DR

The header must be set on the browser context, not per request, so create the context with the locale and extra headers up front. Playwright contexts own the locale, and setting headers after creation misses the first requests. Pass locale and the accept-language header in newContext, then every request carries them.

## The error

```text
Playwright agent: accept-language header missing on requests
server saw en-US despite the agent requesting fr
```

## Fix it

### Step 1: Check how the context is created

```bash
grep -n "newContext" scripts/qa-agent.js | head -5
```

Expected: You see whether locale and headers are set at creation.

### Step 2: Set locale and header in newContext

```bash
node -e "console.log('await browser.newContext({ locale: \"fr-FR\", extraHTTPHeaders: { \"Accept-Language\": \"fr-FR,fr;q=0.9\" } })')"
```

Expected: The context carries both from the first request.

### Step 3: Verify the header on the wire

```bash
node -e "console.log('route the first request and log its headers, confirm accept-language is fr-FR')"
```

Expected: The server sees the right header.

### Step 4: Re-run the locale QA flow

```bash
node scripts/qa-agent.js --locale fr | tail -3
```

Expected: Pages render in French.

## When to use this

- Playwright sends the wrong accept-language
- Locale-dependent rendering shows the wrong language

## When NOT to use this

- The header is right but the page is still wrong, check app locale detection
- You need per-request headers, use route instead

## Tool and version compatibility

- Playwright newContext with locale and extraHTTPHeaders
- Chromium, Firefox, WebKit

## Variant phrasings

### locale set but header still wrong

The locale option sets navigator.language, the header needs extraHTTPHeaders separately. Set both.

### geolocation also needed

Add geolocation and permissions to the same newContext call. One context, all locale signals.

## Why it happens

Playwright contexts initialize locale state at creation. Headers added later apply to subsequent requests but the locale negotiation for the first navigation already happened, so the server never sees the intended language.

## Edge cases

- extraHTTPHeaders merge with defaults, they do not replace the whole header set
- Service workers can cache the wrong-locale response, clear storage between runs
- Headless and headed agree on headers, but check both if results differ

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_IqAQnBZhoaQS7O3k_5Wp9w
