Handle file uploads with validation for type, size, and storage configuration.
import multer from class=class="text-emerald-400">"text-emerald-400">'multer'
import path from class=class="text-emerald-400">"text-emerald-400">'path'
import crypto from class=class="text-emerald-400">"text-emerald-400">'crypto'
import type { Request } from class=class="text-emerald-400">"text-emerald-400">'express'
const ALLOWED_TYPES = [class=class="text-emerald-400">"text-emerald-400">'image/jpeg', class=class="text-emerald-400">"text-emerald-400">'image/png', class=class="text-emerald-400">"text-emerald-400">'image/webp', class=class="text-emerald-400">"text-emerald-400">'application/pdf']
const MAX_SIZE = 5 * 1024 * 1024 class=class="text-emerald-400">"text-gray">// 5MB
const storage = multer.diskStorage({
destination: class=class="text-emerald-400">"text-emerald-400">'./uploads',
filename: (_req, file, cb) => {
const unique = crypto.randomBytes(8).toString(class=class="text-emerald-400">"text-emerald-400">'hex')
const ext = path.extname(file.originalname)
cb(null, class="text-emerald-400">`${Date.now()}-${unique}${ext}`)
},
})
function fileFilter(_req: Request, file: Express.Multer.File, cb: multer.FileFilterCallback) {
if (ALLOWED_TYPES.includes(file.mimetype)) {
cb(null, true)
} else {
cb(new Error(class="text-emerald-400">`File type ${file.mimetype} is not allowed`))
}
}
export const upload = multer({ storage, fileFilter, limits: { fileSize: MAX_SIZE } })
class=class="text-emerald-400">"text-gray">// Usage: app.post(class=class="text-emerald-400">"text-emerald-400">'/upload', upload.single(class=class="text-emerald-400">"text-emerald-400">'file'), handler)
class=class="text-emerald-400">"text-gray">// Access file: req.file — contains path, size, mimetypeUse upload.single('file') for single file uploads or upload.array('files', 5) for multiple files. The file is saved to ./uploads with a unique name. Access metadata via req.file in your route handler.
Let's discuss how we can bring your idea to life. From initial concept to production-ready product — we've got you covered.