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. 😊📁✨