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
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. ๐๐โจ
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