DEV Community

Cover image for File Upload in MERN Stack
Madhav Ganesan
Madhav Ganesan

Posted on • Edited on

File Upload in MERN Stack

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Handled through forms:

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

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);
  }
};
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

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);
  }
});
Enter fullscreen mode Exit fullscreen mode

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')));
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

Feel free to reach out if you have any questions or need further assistance. 😊📁✨

Top comments (0)