File Upload in MERN Stack

Madhav GanesanMadhav Ganesan
3 min read

In this blog, we will delve into the concept of file uploads, which is essential for any web application built using JavaScript. Specifically, in the MERN stack, I have used the multer package to store files from the frontend to the backend without any compression.

Using Multer

Multer is an npm package used for handling file uploads (multipart/form-data). It is a middleware that integrates seamlessly with Express.js applications.

Steps for File Upload Using Multer

1. Install Multer Package:
First, install the multer package via npm:

npm install multer

2. Upload Button:
Instead of forms, I have handled the submit request through states in React.js:

<div>
  <input type="file" onChange={(event) => setImage(event.target.files[0])} />
</div>

Handled through forms:

<form onSubmit={handleSubmit} enctype="multipart/form-data">
  <input type="file" />
</form>

3. Handle Submit Function:
Here is the handleSubmit function in React.js:

const [image, setImage] = useState(null);

const handleSubmit = async (event) => {
  event.preventDefault();
  try {
    const formData = new FormData();
    // image is the state which has image details
    formData.append('file', image);
    var name;
    await axios.post("http://localhost:4100/upload", formData, {
      withCredentials: true,
    })
    .then((response) => {
      toast.success("Image uploaded successfully");
      name = response.data;
    });
  } catch (error) {
    console.log(error);
  }
};

Backend Part

4. Multer Setup:
Create a folder named 'uploads/' on the server-side. Add the following code to app.js. Refer to your project's folder structure for a complete MERN stack application setup.

// Import multer
const multer = require('multer');
const path = require('path');

// Configure multer storage
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');
  },
  filename: (req, file, cb) => {
    cb(null, `${Date.now()}-${file.originalname}`);
  }
});
const upload = multer({ storage: storage });

5. Upload API:
Note: The form data should have the key name 'file' in order to access the file inside the form data.

app.post('/upload', upload.single('file'), (req, res) => {
  try {
    res.json({ message: 'File uploaded successfully', name: req.file.filename });
  } catch (error) {
    console.log(error);
  }
});

6. Serve Static Files

Once the files are uploaded to the backend, they should be accessible from the browser to render on the frontend. To serve static files, use the built-in middleware function in Express.js: express.static().

app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

For example, if the link is "http://localhost:4100/uploads/example.jpg", in the /uploads API, it strips the file name alone and searches for it in the 'uploads' directory.

7. Optional: ES Modules
If you use CommonJS modules, the above code will work. If you are using ES modules, __dirname is not present by default. You need to create an equivalent for ES modules.

import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

Feel free to reach out if you have any questions or need further assistance. ๐Ÿ˜Š๐Ÿ“โœจ

10
Subscribe to my newsletter

Read articles from Madhav Ganesan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Madhav Ganesan
Madhav Ganesan

I am a computer science student passionate about web development and any other technologies that amazes me