# Content-Disposition Header — Syntax, Values & Examples

> Tells the browser to display a response inline or download it as a file, and with what file name.

Content-Disposition: attachment makes the browser download the response instead of displaying it, and `filename` suggests the name to save it under. `inline` (the default) displays it if the browser can, which is how PDFs open in a tab.

- Type: Response header
- Category: Content
- Defined in: [RFC 6266 — Content-Disposition in HTTP](https://www.rfc-editor.org/rfc/rfc6266.html)

## Syntax

```http
Content-Disposition: inline | attachment[; filename="<name>"][; filename*=UTF-8''<encoded-name>]
```

## Values

| Value | Meaning |
|---|---|
| `inline` | display in the browser if possible (default) |
| `attachment` | download instead of displaying |
| `filename="…"` | suggested file name (ASCII) |
| `filename*=UTF-8''…` | percent-encoded file name for non-ASCII characters |

## Examples

```http
Content-Disposition: attachment; filename="report.csv"
```

force a download

```http
Content-Disposition: attachment; filename="resume.pdf"; filename*=UTF-8''r%C3%A9sum%C3%A9.pdf
```

non-ASCII name with an ASCII fallback

```http
Content-Disposition: inline; filename="invoice.pdf"
```

open in the browser, but name it if saved

## Good to know

- Strip quotes, slashes and line breaks from user-supplied file names before putting them in this header.
- The HTML `download` attribute does the same for same-origin links: `<a href="/report.csv" download>`.
- Serving user uploads as `attachment` also stops them running as HTML on your origin.

## How to set Content-Disposition

### Express

```
res.attachment("report.csv"); // sets Content-Disposition and Content-Type
res.send(csv);

// or stream a file from disk:
res.download("/data/report.csv", "report.csv");
```

### Next.js (route handler)

```
return new Response(csv, {
  headers: {
    "Content-Type": "text/csv; charset=utf-8",
    "Content-Disposition": 'attachment; filename="report.csv"',
  },
});
```

### Flask

```
from flask import send_file

return send_file("report.csv", as_attachment=True, download_name="report.csv")
```

### nginx

```
location /downloads/ {
  add_header Content-Disposition "attachment" always;
}
```

## Check it

Fetch only the response headers and filter for Content-Disposition. In the browser, it's under Response Headers in DevTools → Network.

```sh
curl -sI https://example.com/ | grep -i '^content-disposition:'
```

## FAQ

### How do I force a PDF to download instead of opening?

Serve it with Content-Disposition: attachment; filename="file.pdf". Users can still choose to open it afterwards.

## Related headers

- [Content-Type](https://www.devkult.com/headers/content-type.md): States the media type of the body — HTML, JSON, form data, an image — and often its character encoding.
- [X-Content-Type-Options](https://www.devkult.com/headers/x-content-type-options.md): With nosniff, stops browsers guessing a response's type, so a text file can't be run as a script.

## Further reading

- [MIME types by file extension](https://www.devkult.com/mime.md)

Open the interactive page: https://www.devkult.com/headers/content-disposition