Skip to main content
Version: 0.24
note

Last checked with Wasp 0.24 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.tsโ€‹

Create an API namespace with middleware configuration and the upload endpoint:

main.wasp.ts
import { api, apiNamespace, app, page, route } from "@wasp.sh/spec"
import { configureFileUploadMiddleware, uploadFile } from "./src/apis" with { type: "ref" }
import { MainPage } from "./src/MainPage" with { type: "ref" }

export default app({
// ...
spec: [
route("RootRoute", "/", page(MainPage)),
apiNamespace("/api/upload", { middlewareConfigFn: configureFileUploadMiddleware }),
api("POST", "/api/upload", uploadFile),
],
})

3. Create the API handlersโ€‹

Create the middleware configuration and upload handler:

src/apis.js
import multer from "multer";

const upload = multer({ dest: "uploads/" });

export const configureFileUploadMiddleware = (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,
});
};

4. Create the upload formโ€‹

Create a form component to handle file uploads:

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", { body: formData }).json();
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:

const upload = multer({ dest: "my-custom-uploads/" });

Limit file sizeโ€‹

Add file size limits:

const upload = multer({
dest: "uploads/",
limits: {
fileSize: 5 * 1024 * 1024, // 5MB limit
},
});

Filter file typesโ€‹

Only accept certain file types:

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:

export const configureFileUploadMiddleware = (config) => {
config.set("multer", upload.array("files", 10)); // Max 10 files
return config;
};

For more options, see the Multer documentation.