How-to guide

How to Choose the Right MIME Type

A MIME type tells the browser what a response contains, in the form type/subtype — text/html, image/png, application/json. It comes from the Content-Type header, and the header wins over the file extension. Most rendering problems are a mismatch: a file served as text/plain or application/octet-stream downloads instead of displaying.

MIME Type Lookup

Find the MIME type for any file extension, and back.

Open the tool

The browser does not decide what a file is by looking at its name. It reads the Content-Type header, and if that header is wrong the extension will not save you — a stylesheet served as text/plain is ignored no matter what it is called.

This is deliberate. Trusting the extension, or sniffing the content, is how servers get tricked into treating an uploaded image as a script, which is why the header is authoritative and why nosniff exists.

Step by step

  1. Match the type to the actual content

    Use application/json for JSON, text/css for stylesheets, application/javascript for scripts, image/svg+xml for SVG. Guessing from the extension is usually right, but a generated response has no extension to guess from.

  2. Add a charset for text types

    Write text/html; charset=utf-8. Without it the browser guesses the encoding, which is how accented characters turn into mojibake. Binary types do not take a charset, and application/json is always UTF-8 by specification.

  3. Use octet-stream only when you mean download

    application/octet-stream means unknown binary and prompts a download. It is correct for an actual file download and wrong as a default, because it makes every previewable file unpreviewable.

  4. Control the disposition separately

    Whether a file displays or downloads is Content-Disposition, not the MIME type. Send inline to display and attachment to download. Using the wrong MIME type to force a download works, but breaks the file for anything else consuming it.

  5. Send X-Content-Type-Options: nosniff

    This stops the browser overriding your header by inspecting the bytes. Sniffing is a real security problem for user uploads, since a file that looks like a script may be treated as one. With nosniff, the header you send is the one that applies.

Example

The same JSON response with a wrong and a right Content-Type.

Wrong

Content-Type: text/plain

browsers show raw text
fetch().json() still works
some proxies mangle encoding

Right

Content-Type: application/json; charset=utf-8

browsers render a JSON viewer
tools recognise the payload
encoding is unambiguous

Frequently asked questions

What is a MIME type?
A two-part label of the form type/subtype that identifies what a file or response contains — text/html, image/png, application/json. Browsers use it to decide how to handle the bytes they receive. The modern name is media type, though MIME type remains in common use.
Why does my file download instead of displaying?
Either the Content-Type is application/octet-stream or another type the browser cannot render, or a Content-Disposition: attachment header is present. The disposition header takes priority, so check it first.
Does the file extension matter?
To the server, when it is choosing which type to send. To the browser, no — the header is authoritative. A .css file served as text/plain will not be applied as a stylesheet regardless of its name.
Should I use application/javascript or text/javascript?
Both work. text/javascript was long considered obsolete but has since been restored as the standard, so it is the safer choice today. Browsers have accepted either for many years.
What does the charset parameter do?
It tells the browser which character encoding to decode the bytes with. Omitting it on a text type means the browser guesses, which is the usual cause of accented characters displaying as symbols. Always send charset=utf-8 for text.

Tools used in this guide

All tools →
All guides →

Last reviewed .