# Headers

###### Rewrite request headers per-endpoint with set / append / remove semantics, including a couple of template variables for dynamic hosts.

Header rules attach to an endpoint and apply to every request that matches it. They run before the request reaches your local server (and before LocalCan's tunnel forwards it across the public edge).

#### Short syntax

For a one-off `set`, write the header inline as `"Name: value"`:

```yaml
endpoints:
  - url: api.local
    headers:
      - "Host: api.example.com"
      - "X-Forwarded-Proto: https"
```

Short-syntax entries always use `mode: set` and are always enabled.

#### Long syntax

Use the long form when you need any of `mode`, `enabled`, or template variables:

```yaml
endpoints:
  - provider: localcan
    headers:
      - name: Host
        value: "{{target_host}}"
        mode: set
      - name: X-Trace-ID
        value: "{{original_host}}"
        mode: append
      - name: X-Powered-By
        mode: remove
      - name: Cookie
        value: session=preview
        mode: set
        enabled: false
```

| Key | Type | Default | Notes |
| --- | --- | --- | --- |
| `name` | string | — | Header name. Required. |
| `value` | string | `""` | New value. Ignored when `mode: remove`. |
| `mode` | string | `set` | `set`, `append`, or `remove`. |
| `enabled` | bool | `true` | Disable a rule without deleting it. |

#### Modes

- **`set`**: replace any existing value (or add the header if it wasn't there).
- **`append`**: add a new value without removing existing ones. Useful for headers that legitimately appear multiple times (`Set-Cookie`, `X-Forwarded-For`, custom tracing headers).
- **`remove`**: strip the header from the request. `value` is ignored.

#### Template variables

Header values may contain `{{variable}}` placeholders that are resolved per-request:

| Variable | Value |
| --- | --- |
| `{{target_host}}` | Hostname from the service `target` (e.g. `localhost` for `http://localhost:3000`). |
| `{{original_host}}` | The `Host` header the client sent before LocalCan rewrote it. |

Unknown variables resolve to the empty string. Literal `{{` followed by `}}` with nothing between is treated as the literal text `{{}}`.

#### Common recipes

**Make your local app think it's hosted on its production hostname:**

```yaml
headers:
  - "Host: app.example.com"
```

**Forward the Public URL's host to the local app for SaaS-style multi-tenancy testing:**

```yaml
endpoints:
  - provider: localcan
    headers:
      - name: Host
        value: "{{original_host}}"
        mode: set
```

**Strip a debug header your local server adds, before it reaches the public internet:**

```yaml
headers:
  - name: X-Debug-Tokens
    mode: remove
```

