References

Beginner-friendly references for web development, with live, editable examples.

The HTML enctype attribute

Attribute All modern browsers Updated
In short

The HTML enctype attribute sets how a form's data is encoded when it is sent with POST. The default is application/x-www-form-urlencoded. Use enctype="multipart/form-data" together with method="post" whenever the form uploads files.

Overview

The HTML enctype attribute sets how a <form> encodes its data when it is submitted with POST. It takes one of three values, application/x-www-form-urlencoded, multipart/form-data or text/plain, and the first one is used whenever the attribute is missing or invalid.

The default format joins fields into name=value pairs separated by &, with spaces written as + and other special characters percent-encoded. That suits text fields, but a file input sends only the file's name. multipart/form-data sends each field as its own block of data, which is how a file's contents reach the server.

The attribute is ignored on GET forms, because GET always puts the fields in the URL. An upload form therefore needs both method="post" and enctype="multipart/form-data". The PHP manual, for one, warns that file uploads won't work without the multipart encoding.

A single submit button can override the form's choice with formenctype. The third value, text/plain, is meant for debugging, and the HTML standard notes that a program can't reliably parse it.

Syntax

<form action="/upload" method="post" enctype="multipart/form-data">
  <label>Photo <input type="file" name="photo"></label>
  <button>Upload</button>
</form>

Values

Value
application/x-www-form-urlencoded (default) | multipart/form-data | text/plain

Example

Live example
<form id="demo" action="/signup" method="post">
  <label>City <input type="text" name="city" value="New York"></label>
  <label>Team <input type="text" name="team" value="Q&amp;A"></label>
  <button>Show the encoded body</button>
</form>
<p id="body"></p>
<script>
document.getElementById('demo').addEventListener('submit', function (e) {
  e.preventDefault();
  var data = new URLSearchParams(new FormData(this)).toString();
  document.getElementById('body').textContent = this.enctype + ' sends ' + data;
});
</script>

Best practices

  • Add method="post" and enctype="multipart/form-data" to every form that contains a file input.
  • Leave enctype off forms without files, since the URL-encoded default covers ordinary text fields.
  • Use formenctype on one button when only that submission uploads files.
  • Don't set a Content-Type header by hand when posting FormData with fetch(). The browser adds the boundary the server needs to split the parts.
  • Keep text/plain for debugging only.

Frequently asked questions

What does the enctype attribute do in a form?
The enctype attribute tells the browser how to encode a form's fields when it posts them. It has no effect on forms that use GET.
When do I need enctype=multipart/form-data?
You need enctype=multipart/form-data whenever a form uploads files. Without it the server receives only each file's name, not its contents.
What is the default enctype of an HTML form?
The default enctype is application/x-www-form-urlencoded. It joins fields as name=value pairs separated by ampersands and writes spaces as plus signs.
Why is $_FILES empty in PHP after submitting my form?
PHP fills $_FILES only for forms posted with enctype=multipart/form-data. Check that the form also uses method=post, since a GET form ignores enctype.
Does fetch with FormData need an enctype?
No, enctype only applies to forms the browser submits itself. A FormData body sent with fetch() is encoded as multipart/form-data automatically, and you shouldn't set the Content-Type header yourself.