devkult_
tools29converters34
home/headers/content-disposition

Content-Disposition

response headercontent

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.

Syntax

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

Defined in RFC 6266 — Content-Disposition in HTTP.

Values

inlinedisplay in the browser if possible (default)
attachmentdownload instead of displaying
filename="…"suggested file name (ASCII)
filename*=UTF-8''…percent-encoded file name for non-ASCII characters

Examples

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

force a download

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

non-ASCII name with an ASCII fallback

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.

Further reading: MIME types by file extension

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.

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

To compare response headers across many URLs at once, use the HTTP Status Checker.

Frequently asked questions

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