An Interest In:
Web News this Week
- March 21, 2024
- March 20, 2024
- March 19, 2024
- March 18, 2024
- March 17, 2024
- March 16, 2024
- March 15, 2024
August 12, 2022 05:23 am GMT
Original Link: https://dev.to/crypticai/uploading-files-in-remix-to-an-s3-compatible-service-35c9
Uploading files in Remix to a S3 compatible service
Remix is a new react-based framework designed to be a full stack application. With many applications, you will need to be able to store files, sometimes in an S3 compatible service. Here is how I was able to accomplish this. I took heavy influence from this dev.to article.
Create a file named uploader-handler.server.ts
with the following contents:
import { s3Client } from './s3.server';import type { UploadHandler } from '@remix-run/node';import type { PutObjectCommandInput } from '@aws-sdk/client-s3';import { GetObjectCommand } from '@aws-sdk/client-s3';import { PutObjectCommand } from '@aws-sdk/client-s3';import { getSignedUrl } from '@aws-sdk/s3-request-presigner';const uploadStreamToS3 = async (data: AsyncIterable<Uint8Array>, key: string, contentType: string) => { const BUCKET_NAME = "my_bucket_name"; const params: PutObjectCommandInput = { Bucket: BUCKET_NAME, Key: key, Body: await convertToBuffer(data), ContentType: contentType, }; await s3Client.send(new PutObjectCommand(params)); let url = await getSignedUrl(s3Client, new GetObjectCommand({ Bucket: BUCKET_NAME, Key: key, }), { expiresIn: 15 * 60 }); console.log(url); return key;}// The UploadHandler gives us an AsyncIterable<Uint8Array>, so we need to convert that to something the aws-sdk can use. // Here, we are going to convert that to a buffer to be consumed by the aws-sdk.async function convertToBuffer(a: AsyncIterable<Uint8Array>) { const result = []; for await (const chunk of a) { result.push(chunk); } return Buffer.concat(result);}export const s3UploaderHandler: UploadHandler = async ({ filename, data, contentType }) => { return await uploadStreamToS3(data, filename!, contentType);}
Next, you will need to create the actual route to be able to upload a file. I have the following file: ~/routes/api/storage/upload.tsx
with the following contents
import type { ActionFunction } from "@remix-run/node";import { unstable_parseMultipartFormData } from "@remix-run/node";import { auth } from "~/server/auth.server";import { s3UploaderHandler } from "~/server/uploader-handler.server";export const action: ActionFunction = async ({ request }) => { await auth.isAuthenticated(request, { failureRedirect: '/login' }); const formData = await unstable_parseMultipartFormData(request, s3UploaderHandler); const fileName = formData.get('upload'); return { filename: fileName, }}
Now that you have the supporting files in place, let's upload a file.
<Form method="post" action={'/api/storage/upload'} encType="multipart/form-data"> <Input type="file" name="upload" /> <Button type="submit">Upload</Button></Form>
There you have it!
Version of sdks used:
- @remix-run/node: 1.6.5
- @remix-run/react: 1.6.5
- @aws-sdk/client-s3: 3.145.0
- @aws-sdk/s3-request-presigner: 3.145.0
Original Link: https://dev.to/crypticai/uploading-files-in-remix-to-an-s3-compatible-service-35c9
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To