How to create a file upload form with formcarry in 5 steps

One of the most time consuming thing about forms is definitely uploading files, sometimes you may need an HTML form with file upload functionality, in this guide we are going to start by as simple as possible than we are going to jump to advanced techniques

After you read this guide

  • You can create a file upload form in 5 steps, under 3 minutes
  • You can get email notifications from your HTML form
  • You can export your contact form submissions as CSV and JSON
  • You don't have to deal with any back end code stuff (Php, Go, Node.js etc.)

Step 1 — Create your HTML Form

First, you'll need an HTML form in your web page, which is not a big deal, a basic HTML upload form will look like this.

<form action="#" method="POST" enctype="multipart/form-data">
	<label for="nameInput">Name</label>
	<input type="text" id="nameInput" />

	<label for="messageInput">Message</label>
	<textarea id="messageInput" cols="30" rows="2"></textarea>

	<input type="file" id="pictureInput" />

	<button type="submit">Submit</button>
</form>
Your form element have to include enctype="multipart/form-data" to upload files
A basic form in HTML is just a static thing that's only obligated to deliver the user input to a back-end script. You have to point the form to some script to actually process the data.

if you want to have a fully styled form you can use our free form generator tool to generate a customized form code.

By default, file input only allows you to choose a single file from your device, if you want it to allow multiple files then you can use the multiple attribute

<input type="file" id="pictureInput" multiple />

Step 2 — Structure your form data

In order to send your form data to a script you need to name each of your fields so the script can match the values with the names (or the key).

You can add as many fields as you want.

Let's uniquely name each of our fields using name attribution.

<form action="#" method="POST" enctype="multipart/form-data">
	<label for="nameInput">Name</label>
  	<input type="text" id="nameInput" name="name" />

	<label for="messageInput">Message</label>
	<textarea id="messageInput" cols="30" rows="2" name="message"></textarea>

	<label for="pictureInput">Picture</label>
	<input type="file" id="pictureInput" name="picture" />

	<button type="submit">Submit</button>
</form>

Now we have a file upload form that's ready to deliver the data to a script.

Step 3 — Point your form to backend

There are two ways to handle this step, this part is the most time consuming stuff due to you have to check files, rename them uniquely save to database and upload to somewhere along with you'll also probably going to need a email server to send emails, which you always have to make sure that emails are delivered.

Option 1 — Create your own form back-end

You need to have a form backend to collect submissions and files from your form, this is typically done by some backend languages such as PHP, Node.js, Go etc.

We have a detailed guide on How to create a form backend with file upload

How to create an HTML contact form with file upload | Actionable Guide
In this tutorial, we are going to create a sample app using Express.js to uploadfiles to Amazon S3, then we are going to save our submission to the MongoDB Prerequisites for the tutorialI don’t want to cover some things that would over-complicate this tutorial,therefore I assume you know how to:…

Take a look at that post if you want to build it on your own

Option 2 — Use Formcarry - File upload ready form backend

Formcarry is a free, no-code form backend for your HTML forms, in this tutorial I'm going to show you how can you create a file upload form under 3 minutes while it at least takes 1 hours if you do it on your own. Also you can get notification emails from your form, protected from spam by default and integrate your submission data with other apps using Zapier.

Sign Up to formcarry for free, then click Add New to get your unique form backend URL

Then copy your unique form endpoint

Step 4 — Integrate your form with formcarry

Copy your endpoint and paste it into action part of your form

- <form action="#" method="POST" enctype="multipart/form-data">
+ <form action="https://formcarry.com/s/{Your-Unique-Endpoint}" method="POST" enctype="multipart/form-data">

Step 5 — Collect submissions

Let's try out our form:

Now, let's take a look at our dashboard:

That's all you need to upload files when you are using formcarry, that's how deadly simple it is. We have covered the basics, now let's jump into something a little bit advanced.


Uploading files from your form using Javascript

Uploading files with raw HTML form is not so time consuming, but if you are trying to upload it with javascript it's possible that you are going to spend some time on figuring out what's going wrong.

First add our form id="formcarryForm"

- <form action="https://formcarry.com/s/{Your-Unique-Endpoint}" method="POST" enctype="multipart/form-data">
+ <form id="formcarryForm" method="POST" enctype="multipart/form-data">

Important note before we switch back to code

Common mistake while implementing a file upload in javascript is setting Content-Type as multipart/form-data while this is partly true, it's also very wrong approach.

Any content-type starts with multipart/* is required to have boundary, based on my own experiences and the support request we got from formcarry, we found out the ideal way to upload files from javascript is using the FormData class

const formElement = document.getElementById('formcarryForm')

const data = new FormData(formElement)

this will get each field from your form, but if you want to add some additional data, that you don't want to store in the HTML, you can add your additional data like that;

const formElement = document.getElementById('formcarryForm')

const data = new FormData(formElement)

data.append('language', window.navigator.language)

Uploading files from your form using Fetch API

Fetch API is an embedded request API for javascript, it's widely supported among modern browsers, check Fetch API compability.

Add this script before the </body> tag

<script>
  const formcarryForm = document.getElementById('formcarryForm')

  const sendFormData = async (event) => {
    // this will prevent your form to redirect to another page.
    event.preventDefault();
		
    // get our form data
    const formData = new FormData(formcarryForm)
    // add some additional data if you want
    // formData.append('language', window.navigator.language)

    fetch('https://formcarry.com/s/{Your-Unique-Endpoint}', {
      method: 'POST',
      body: formData,
      headers: {
		// you don't have to set Content-Type
		// otherwise it won't work due to boundary!
        Accept: 'application/json'
      }
    })
    // convert response to json
    .then(r => r.json())
    .then(res => {
      console.log(res);
    });
  }

  // Bind our sendFormData function to our forms submit event
  formcarryForm.addEventListener('submit', sendFormData);
</script>

Uploading files from your form using Axios

Axios is an promise based HTTP client for the browser and node.js, it's lightweight and a common library for making HTTP requests, it's a nice alternative for Fetch API

Add this script before the </body> tag

<script>
  const formcarryForm = document.getElementById('formcarryForm')

  const sendFormData = async (event) => {
    // this will prevent your form to redirect to another page.
    event.preventDefault();
		
	// get our form data
	const formData = new FormData(formcarryForm);
	// add some additional data if you want
	// formData.append('language', window.navigator.language)

    axios
      .post("https://formcarry.com/s/{Your-Unique-Endpoint}", formData, {
        headers: { 
			// you don't have to set Content-Type
			// otherwise it won't work due to boundary!
			Accept: "application/json" 
		},
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        // this is an error related to request
        console.log(error);
      });
  };

  // Bind our sendFormData function to our forms submit event
  formcarryForm.addEventListener('submit', sendFormData);
</script>

Uploading Files from your form with React

Using FormData class in React is a little bit tweaky, but let's take a look how to upload files with React.

We need to use useRef to access our form element, here's a sample component for you to upload files with React:

import React, { useRef } from "react"

const Form = () => {
  // create a Ref to access our form element
  const formRef = useRef(null)

  const sendFormData = async (event) => {
    // this will prevent your form to redirect to another page.
    event.preventDefault();

    if(!formRef.current){
      console.log('something wrong with form ref')
      return
    }
		
    // get our form data
    const formData = new FormData(formRef.current)

    // add some additional data if you want
    // formData.append('language', window.navigator.language)

    fetch('https://formcarry.com/s/{Your-Unique-Endpoint}', {
      method: 'POST',
      body: formData,
      headers: {
		// you don't have to set Content-Type
		// otherwise it won't work due to boundary!
        Accept: 'application/json'
      }
    })
    // convert response to json
    .then(r => r.json())
    .then(res => {
      console.log(res);
    });
  }

  return (
	// bind formRef to our form element
    <form ref={formRef} onSubmit={sendFormData}>
      <label htmlFor="nameInput">Name</label>
      <input type="text" id="nameInput" name="name" />

      <label htmlFor="messageInput">Message</label>
      <textarea id="messageInput" name="message"></textarea>

      <label htmlFor="pictureInput">Picture</label>
      <input type="file" id="pictureInput" name="picture" />

      <button type="submit">Submit</button>
    </form>
  )
}

export default Form

That's all! here's the live demo: codesandbox


Conclusion

I hope this guide was helpful for you, at formcarry our mission is providing an easy way to handle your HTML forms also we are trying to release form related in-depth guides, make sure you've subscribed our newsletter to get the latest posts.