In this article we'll look at how to download all files in a folder from Supabase storage as a ZIP file with Next.js.
By default, Supabase doesn't provide a way to download all files in a folder using the download
method.
So the only way to do this is to download each file individually and then zip them up.
Let's assume you have a folder called images
in your Supabase storage bucket my-bucket
and you want to download all the files in that folder.
First, we'll need to get a list of all the files in the folder.
We can do this by using the list
method on the storage
object.
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs';
const supabaseClient = createClientComponentClient();
const bucket = "my-bucket";
const folder = "images";
// Get a list of all the files in the path /my-bucket/images
const { data: files, error } = await supabaseClient.storage
.from(bucket)
.list(folder);
if (error) {
throw error;
}
// If there are no files in the folder, throw an error
if (!files || !files.length) {
throw new Error("No files to download");
}
Once we have a list of all the files in the folder, we can download each file individually.
const promises = [];
// Download each file in the folder
files.forEach((file) => {
promises.push(
supabaseClient.storage.from(bucket).download(`${folder}/${file.name}`)
);
});
// Wait for all the files to download
const response = await Promise.allSettled(promises);
// Map the response to an array of objects containing the file name and blob
const downloadedFiles = response.map((result, index) => {
if (result.status === "fulfilled") {
return {
name: files[index].name,
blob: result.value.data,
};
}
});
We'll need to install the @zip.js/zip.js
package to create the zip file.
npm install @zip.js/zip.js
Make sure you import the BlobReader
, BlobWriter
and ZipWriter
classes your file.
import { BlobReader, BlobWriter, ZipWriter } from "@zip.js/zip.js";
Now that we have an array of objects containing the file name and blob, we can zip them up and download them.
// Create a new zip file
const zipFileWriter = new BlobWriter("application/zip");
const zipWriter = new ZipWriter(zipFileWriter, { bufferedWrite: true });
// Add each file to the zip file
downloadedFiles.forEach((downloadedFile) => {
if (downloadedFile) {
zipWriter.add(downloadedFile.name, new BlobReader(downloadedFile.blob));
}
});
// Download the zip file
const url = URL.createObjectURL(await zipWriter.close());
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "documents.zip");
document.body.appendChild(link);
link.click();