Uploading Large Files to S3 with Multipart Chunking
Here's how to upload large files to an S3 bucket using multipart chunking (5MB blobs at a time). The advantage is your server won't run out of RAM when someone uploads a massive file.
Node.js Backend
const express = require("express");
const companion = require("@uppy/companion");
const port = 1337;
const app = express();
app.use("/presign", companion.app({
providerOptions: {
s3: {
endpoint: S3_URL_ENDPOINT,
getKey: (req, filename) => `${req.body.metadata.folderName}/${filename}`,
key: YOUR_API_KEY,
secret: YOUR_API_SECRET,
bucket: YOUR_BUCKET_NAME,
region: YOUR_REGION,
},
},
server: { serverUrl: `localhost:${port}` },
}));
app.listen(port, () => {
console.log(`working on ${port}`);
});Vue Frontend
<template>
<div class="relative">
<div class="uppy"></div>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import Uppy from "@uppy/core";
import Dashboard from "@uppy/dashboard";
import AwsS3Multipart from "@uppy/aws-s3-multipart";
import "@uppy/core/dist/style.min.css";
import "@uppy/dashboard/dist/style.min.css";
const uppy = ref(null);
onMounted(() => {
uppy.value = new Uppy({
debug: false,
autoProceed: false,
meta: { folderName: "somefoldername" },
});
uppy.value
.use(Dashboard, {
target: ".uppy",
inline: true,
replaceTargetContent: true,
showProgressDetails: true,
height: 470,
browserBackButtonClose: true,
})
.use(AwsS3Multipart, {
companionUrl: `${import.meta.env.VITE_SERVER_ENDPOINT}/presign`,
limit: 5,
})
.on("complete", (result) => {
console.log("Upload complete:", result);
});
});
</script>The backend handles presigning S3 URLs, and the frontend uses Uppy's dashboard to chunk everything up. No faffing about with manual multipart logic, Uppy sorts it all out.
