TXT MIME Type – Free, Online, Private
text/plain is the type for a text file with no markup. Send charset=utf-8, because the historical default is US-ASCII.
What .txt is
A .txt file is characters and line breaks. It has no elements, no records, and no media type inside the media type. RFC 2046 defines text/plain. The historical default charset for text/* when the parameter is missing is US-ASCII, which means a UTF-8 file can be misread if you omit the parameter. Send text/plain; charset=utf-8. Line endings may be LF or CRLF. The type does not record which one you used. A client that displays the body will usually tolerate both. A client that hashes the bytes will not.
IANA registers text/plain in RFC 2046, with later notes in RFC 3676 and RFC 5147. The media type is text/plain. Extensions that use it on this page: .txt. A client compares the type, not the filename, once the response has arrived. The filename still matters on disk and in Content-Disposition, which is why a wrong extension and a wrong header are two different bugs.
What sends text/plain
What sends text/plain: Send text/plain; charset=utf-8 for notes, logs you are willing to show, robots.txt, and an error body that is intentionally not HTML. robots.txt is fetched as a URL, and crawlers accept text/plain. An API that returns a bare string can use text/plain when the contract is a string and JSON would add quotes the client does not want. Do not use text/plain for HTML, CSV, or JavaScript just because those files are 'readable'. Each of those has a type that changes what the browser does. The file on disk is still .txt. Once the response exists, a client trusts text/plain, not the filename. If the text is Markdown, serve text/markdown so a client can choose to render it. If it is a log you want a browser to show without download, text/plain is right and Content-Disposition should be inline or absent. attachment is for a file the user should save.
Content-Type for .txt
Send text/plain; charset=utf-8. The charset parameter names the encoding of the body. Leaving it off forces the client to guess, and for several text types the registered default is not UTF-8. Do not send a charset on a redirect. The header belongs on the response that contains the bytes.
Content-TypeContent-Type: text/plain; charset=utf-8
nginx, Apache, and Express
These snippets map .txt to text/plain. nginx reads the types block when it picks a type from the URL's extension. A location that sets default_type, or an application that sets the header itself, overrides that map. Apache AddType applies in the directory context where you put it. The Express static example writes the header for files ending in .txt so a stale mime database in the framework cannot disagree with the type on this page.
nginx# /etc/nginx/mime.types, inside the types { } block
text/plain txt;
charset utf-8;
charset_types text/plain;
ApacheAddType text/plain .txt
AddCharset UTF-8 .txt
Expressimport express from "express";
const app = express();
app.use(express.static("public", {
setHeaders(res, filePath) {
if (filePath.endsWith(".txt")) {
res.setHeader("Content-Type", "text/plain; charset=utf-8");
}
},
}));
Pitfalls for text/plain
Pitfalls that show up for text/plain, and not for a neighboring type with a similar extension: The dangerous use is a file of user text served as text/plain from your origin and then sniffed as HTML. A body that starts with <script> has been sniffed by browsers when nosniff was absent. Send X-Content-Type-Options: nosniff with text/plain if the bytes are not yours. Another trap is a log file that contains secrets, served with this type and a public cache. The type is not a privacy control. Cache-Control is. A third is UTF-16 text labeled UTF-8. The browser shows CJK-looking noise or replacement characters. Convert the bytes.
- text/plain does not mean 'safe to put in an HTML page'. You still have to escape it if you interpolate it into markup.
- A BOM at the start is the bytes EF BB BF for UTF-8. Some tools treat it as visible content.
- RFC 5147 defines a fragment for character and line ranges. Support is rare. Do not depend on it.
- Gzip helps a lot. Text compresses. Leave the type as text/plain.
Frequently asked questions
Which charset parameter should I send?
charset=utf-8. Omitting it leaves the old US-ASCII default in play for some clients.
Can I serve HTML as text/plain to make it safe?
Only together with nosniff. Without nosniff, browsers have sniffed HTML out of text/plain.
Is text/plain correct for robots.txt?
Yes. Crawlers expect the file at /robots.txt and accept text/plain.
Does the type include the line ending?
No. LF and CRLF are both plain text. Pick one if a checksum has to match.