Learning & reference
MIME types: the right Content-Type for every file
The Content-Type header decides whether a browser renders a file, downloads it, or refuses it outright. Here is the correct type for every common extension — and the mistakes that quietly break things.
What a MIME type actually controls
The Content-Type header decides whether the browser renders a file, downloads it,
or refuses it. Get it wrong and a stylesheet is ignored, a script is blocked, or a PDF downloads instead of
opening.
Render vs. download
application/octet-stream (or Content-Disposition: attachment) forces a
download. A known type like application/pdf renders inline.
nosniff changes everything
With X-Content-Type-Options: nosniff the browser stops guessing. A stylesheet served as
text/plain is then rejected outright rather than silently working.
It is client-supplied on upload
The Content-Type on a multipart upload comes from the browser and can be set to anything.
Validate with a signature check, not this header.
Common types by extension
| Extension | MIME type | Notes |
|---|---|---|
.txt | text/plain | Add ; charset=utf-8 or browsers guess the encoding. |
.html .htm | text/html | |
.css | text/css | Served as anything else, browsers refuse to apply it. |
.js .mjs | text/javascript | The standard type. application/javascript is obsolete but still accepted. |
.json | application/json | No charset parameter - JSON is always UTF-8. |
.xml | application/xml | text/xml is legacy and treats it as text. |
.csv | text/csv | Excel often mislabels these as application/vnd.ms-excel. |
.pdf | application/pdf | |
.png | image/png | |
.jpg .jpeg | image/jpeg | Note: not image/jpg - that type does not exist. |
.gif | image/gif | |
.webp | image/webp | |
.svg | image/svg+xml | Can contain scripts - never serve user SVG from your main origin. |
.ico | image/x-icon | image/vnd.microsoft.icon is the registered name. |
.zip | application/zip | |
.gz | application/gzip | Not Content-Encoding: gzip - that is a different thing. |
.tar | application/x-tar | |
.7z | application/x-7z-compressed | |
.mp3 | audio/mpeg | Not audio/mp3. |
.wav | audio/wav | |
.mp4 | video/mp4 | |
.webm | video/webm | |
.woff | font/woff | Modern types are font/*; older ones used application/font-woff. |
.woff2 | font/woff2 | |
.ttf | font/ttf | |
.otf | font/otf | |
.docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | The long OOXML types are a classic source of typos. |
.xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | |
.pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation | |
.doc | application/msword | Legacy binary Office. |
.xls | application/vnd.ms-excel | |
.odt | application/vnd.oasis.opendocument.text | |
.epub | application/epub+zip | |
.wasm | application/wasm | Must be exact or streaming compilation fails. |
(unknown) | application/octet-stream | The safe default. Triggers a download rather than inline display. |
The mistakes that bite
image/jpg
Does not exist. The registered type is
image/jpeg; image/jpg is silently accepted by some stacks and rejected by others.
Missing charset
text/html without
; charset=utf-8 leaves the encoding to the browser - accented characters turn into mojibake.
gzip confusion
A .gz file is
application/gzip content. Content-Encoding: gzip means "this response was
compressed in transit" - set both and the client decompresses once too often.
SVG is executable
SVG can carry <script>. Serving
user-uploaded SVG as image/svg+xml from your own origin is stored XSS.
CSV vs Excel
Excel labels CSV exports
application/vnd.ms-excel. An importer that only accepts text/csv rejects a
perfectly valid file.
OOXML typos
The Office types are ~70 characters long. One wrong character and the download is treated as an unknown binary.
See it live
The generator echoes any content type you ask for, so you can watch how a browser reacts.