note
Last checked with Wasp 0.23 and multer 2.1.1.
This guide depends on external libraries or services, so it may become outdated over time. We do our best to keep it up to date, but make sure to check their documentation for any changes.File Uploads
This guide shows you how to implement file uploads in your Wasp application using Multer.
Setting up File Uploads
1. Install Multer
Install the Multer package and its types:
npm install multer
npm install --save-dev @types/multer
2. Define the API endpoint in main.wasp
Create an API namespace with middleware configuration and the upload endpoint:
main.wasp
app FileUpload {
wasp: {
version: "^0.21.0"
},
title: "file-upload",
}
route RootRoute { path: "/", to: MainPage }
page MainPage {
component: import { MainPage } from "@src/MainPage"
}
apiNamespace fileUploadMiddleware {
middlewareConfigFn: import { addMiddleware } from "@src/apis",
path: "/api/upload"
}
api fileUpload {
httpRoute: (POST, "/api/upload"),
fn: import { uploadFile } from "@src/apis",
entities: []
}
3. Create the API handlers
Create the middleware configuration and upload handler:
- JavaScript
- TypeScript
src/apis.js
import multer from "multer";
const upload = multer({ dest: "uploads/" });
export const addMiddleware = (config) => {
config.set("multer", upload.single("file"));
return config;
};
export const uploadFile = (req, res) => {
console.log(req.body);
console.log(req.file);
const file = req.file;
return res.json({
fileExists: !!file,
});
};
src/apis.ts
import type { MiddlewareConfigFn } from "wasp/server";
import type { FileUpload } from "wasp/server/api";
import multer from "multer";
const upload = multer({ dest: "uploads/" });
export const addMiddleware: MiddlewareConfigFn = (config) => {
config.set("multer", upload.single("file"));
return config;
};
export const uploadFile: FileUpload = (req, res) => {
console.log(req.body);
console.log(req.file);
const file = req.file!;
return res.json({
fileExists: !!file,
});
};
4. Create the upload form
Create a form component to handle file uploads:
- JavaScript
- TypeScript
src/MainPage.jsx
import { useState } from "react";
import { api } from "wasp/client/api";
export const MainPage = () => {
const [name, setName] = useState("");
const [file, setFile] = useState();
const handleSubmit = async (e) => {
e.preventDefault();
if (!file) return;
const formData = new FormData();
formData.append("name", name);
formData.append("file", file);
const { data } = await api.post("/api/upload", formData);
alert(JSON.stringify(data, null, 2));
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<input type="file" onChange={(e) => setFile(e.target.files?.[0])} />
<button type="submit">Upload</button>
</form>
);
};
src/MainPage.tsx
import { useState } from "react";
import { api } from "wasp/client/api";
export const MainPage = () => {
const [name, setName] = useState("");
const [file, setFile] = useState<File>();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!file) return;
const formData = new FormData();
formData.append("name", name);
formData.append("file", file);
const { data } = await api.post("/api/upload", formData);
alert(JSON.stringify(data, null, 2));
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<input type="file" onChange={(e) => setFile(e.target.files?.[0])} />
<button type="submit">Upload</button>
</form>
);
};
Customizing Upload Settings
Change upload destination
You can customize where files are stored:
- JavaScript
- TypeScript
const upload = multer({ dest: "my-custom-uploads/" });
const upload = multer({ dest: "my-custom-uploads/" });
Limit file size
Add file size limits:
- JavaScript
- TypeScript
const upload = multer({
dest: "uploads/",
limits: {
fileSize: 5 * 1024 * 1024, // 5MB limit
},
});
const upload = multer({
dest: "uploads/",
limits: {
fileSize: 5 * 1024 * 1024, // 5MB limit
},
});
Filter file types
Only accept certain file types:
- JavaScript
- TypeScript
const upload = multer({
dest: "uploads/",
fileFilter: (req, file, cb) => {
if (file.mimetype.startsWith("image/")) {
cb(null, true);
} else {
cb(new Error("Only images are allowed"));
}
},
});
const upload = multer({
dest: "uploads/",
fileFilter: (req, file, cb) => {
if (file.mimetype.startsWith("image/")) {
cb(null, true);
} else {
cb(new Error("Only images are allowed"));
}
},
});
Handle multiple files
To handle multiple file uploads:
- JavaScript
- TypeScript
export const addMiddleware = (config) => {
config.set("multer", upload.array("files", 10)); // Max 10 files
return config;
};
export const addMiddleware: MiddlewareConfigFn = (config) => {
config.set("multer", upload.array("files", 10)); // Max 10 files
return config;
};
For more options, see the Multer documentation.