File Uploads with Multer in Express
Handle file uploads in Node.js with Multer. Upload images, documents, and manage file storage.
File Uploads with Multer in Express
Multer handles multipart/form-data - the format for file uploads.
Setup
```bash npm install multer ```
Basic Configuration
```javascript const multer = require('multer');
// Simple memory storage const upload = multer({ dest: 'uploads/' });
// Or disk storage with custom naming const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { const uniqueName = Date.now() + '-' + file.originalname; cb(null, uniqueName); } });
const upload = multer({ storage }); ```
Single File Upload
```javascript app.post('/upload', upload.single('avatar'), (req, res) => { console.log(req.file); // { // fieldname: 'avatar', // originalname: 'photo.jpg', // filename: '1234567890-photo.jpg', // path: 'uploads/1234567890-photo.jpg', // size: 12345 // } res.json({ file: req.file }); }); ```
Multiple Files
```javascript // Multiple files, same field app.post('/photos', upload.array('photos', 5), (req, res) => { console.log(req.files); // Array of files res.json({ files: req.files }); });
// Multiple fields const cpUpload = upload.fields([ { name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 } ]);
app.post('/profile', cpUpload, (req, res) => { console.log(req.files.avatar); // Single file console.log(req.files.gallery); // Array of files }); ```
File Filtering
```javascript const imageFilter = (req, file, cb) => { const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error('Only images allowed'), false); } };
const upload = multer({ storage, fileFilter: imageFilter, limits: { fileSize: 5 * 1024 * 1024 // 5MB } }); ```
Error Handling
```javascript app.post('/upload', (req, res) => { upload.single('file')(req, res, (err) => { if (err instanceof multer.MulterError) { if (err.code === 'LIMIT_FILE_SIZE') { return res.status(400).json({ error: 'File too large' }); } return res.status(400).json({ error: err.message }); } if (err) { return res.status(400).json({ error: err.message }); } res.json({ file: req.file }); }); }); ```
Memory Storage (for cloud upload)
```javascript const upload = multer({ storage: multer.memoryStorage() });
app.post('/upload', upload.single('file'), async (req, res) => { // req.file.buffer contains file data // Upload to S3, Cloudinary, etc. const buffer = req.file.buffer; // await uploadToCloud(buffer); res.json({ message: 'Uploaded' }); }); ```
Complete Example
```javascript const express = require('express'); const multer = require('multer'); const path = require('path');
const app = express();
const storage = multer.diskStorage({ destination: 'uploads/', filename: (req, file, cb) => { const ext = path.extname(file.originalname); cb(null, `${Date.now()}${ext}`); } });
const upload = multer({ storage, limits: { fileSize: 5 * 1024 * 1024 }, fileFilter: (req, file, cb) => { const allowed = /jpeg|jpg|png|gif/; const ext = allowed.test(path.extname(file.originalname).toLowerCase()); const mime = allowed.test(file.mimetype); if (ext && mime) cb(null, true); else cb(new Error('Images only!')); } });
// Serve uploaded files app.use('/uploads', express.static('uploads'));
app.post('/api/upload', upload.single('image'), (req, res) => { if (!req.file) { return res.status(400).json({ error: 'No file uploaded' }); } res.json({ url: `/uploads/${req.file.filename}`, size: req.file.size }); });
app.listen(3000); ```
Key Takeaway
Multer handles file uploads in Express. Use `single()` for one file, `array()` for multiple. Filter by type/size for security. Use memory storage for cloud uploads, disk storage for local files.