W
Wasp•9mo ago
ivan

File upload preview

If all user uploads are images hosted in s3, how would I go about generating a preview of the image that is shown within the UI?
7 Replies
kapa.ai
kapa.ai•9mo ago
Hi @ivan. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To generate a preview of an image that is hosted on S3 and shown within the UI, you would typically use a presigned URL. This URL gives temporary access to the file, allowing it to be displayed in the UI. Here's a general idea of how you could implement this in your Wasp application: 1. First, you need to set up an S3 bucket and an IAM user. Add the following entries to your .env.server file:
AWS_S3_IAM_ACCESS_KEY=
AWS_S3_IAM_SECRET_KEY=
AWS_S3_FILES_BUCKET=
AWS_S3_REGION=
AWS_S3_IAM_ACCESS_KEY=
AWS_S3_IAM_SECRET_KEY=
AWS_S3_FILES_BUCKET=
AWS_S3_REGION=
2. Add the AWS SDK to your list of dependencies:
dependencies: [
...
("aws-sdk", "^2.1294.0"),
...
]
dependencies: [
...
("aws-sdk", "^2.1294.0"),
...
]
3. In your front end, set up a function for downloading files. This function would call a server-side function that generates a presigned URL for the file on S3. Once you have this URL, you can use it as the src attribute in an img tag to display the image.
const handleDownloadFile = async () => {
...
let data = await getDownloadFileSignedURL(...);
// key is the identifier of the file in S3
const { downloadUrl, key } = data;
// Use the downloadUrl as the src in an img tag
...
}
const handleDownloadFile = async () => {
...
let data = await getDownloadFileSignedURL(...);
// key is the identifier of the file in S3
const { downloadUrl, key } = data;
// Use the downloadUrl as the src in an img tag
...
}
Please note that this is a simplified example and you would need to implement the getDownloadFileSignedURL function on the server side, which interacts with AWS SDK to generate the presigned URL. For more details, you can refer to the Github Issue (open): Ability to serve and upload dynamic binary assets (images, pdfs) (https://github.com/wasp-lang/wasp/issues/494) and the Discord support thread: file download from s3 (https://discord.com/channels/686873244791210014/1207704500966789171). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @ivan, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
ivan
ivanOP•9mo ago
What parameters do I need for my function? I am having trouble writing it. @kapa.ai
kapa.ai
kapa.ai•9mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The parameters you need for your function will depend on the specific requirements of your application. However, in the context of generating a presigned URL for an S3 object, you would typically need the following: 1. Bucket Name: The name of the S3 bucket where the file is stored. 2. File Key: The key of the file in the S3 bucket. This is essentially the file's name in the bucket. 3. Expiration Time: The amount of time that the presigned URL should remain valid. This is typically provided in seconds. Here's a simplified example of what your server-side function might look like:
import AWS from 'aws-sdk';

const s3 = new AWS.S3({
accessKeyId: process.env.AWS_S3_IAM_ACCESS_KEY,
secretAccessKey: process.env.AWS_S3_IAM_SECRET_KEY,
region: process.env.AWS_S3_REGION
});

export const getDownloadFileSignedURL = async (key) => {
const params = {
Bucket: process.env.AWS_S3_FILES_BUCKET,
Key: key,
Expires: 60 * 5 // URL valid for 5 minutes
};

const url = await s3.getSignedUrlPromise('getObject', params);
return { downloadUrl: url, key: key };
};
import AWS from 'aws-sdk';

const s3 = new AWS.S3({
accessKeyId: process.env.AWS_S3_IAM_ACCESS_KEY,
secretAccessKey: process.env.AWS_S3_IAM_SECRET_KEY,
region: process.env.AWS_S3_REGION
});

export const getDownloadFileSignedURL = async (key) => {
const params = {
Bucket: process.env.AWS_S3_FILES_BUCKET,
Key: key,
Expires: 60 * 5 // URL valid for 5 minutes
};

const url = await s3.getSignedUrlPromise('getObject', params);
return { downloadUrl: url, key: key };
};
In this example, getDownloadFileSignedURL is an async function that takes a key parameter. This key is the identifier of the file in the S3 bucket. The function uses the AWS SDK to generate a presigned URL for the file, which is then returned along with the file key. Please note that this is a simplified example and you would need to handle errors and edge cases as appropriate for your application. Also, remember to install the AWS SDK in your project and to set the appropriate environment variables for your AWS credentials and S3 bucket information. For more details, you can refer to the AWS SDK for JavaScript API Reference (https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @ivan, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
martinsos
martinsos•9mo ago
So the bot is giving a generally sound advice here -> basically you do indeed need this URLs from S3, and you will use them in your app, on the frontend, in your React app, most likely in the img tag, or if you are previewing your image in some other way, then you will provide the URL in whatever way that other method expects it. Question is, how are you obtaining these URLs. So once user uploads image to S3, you will want to save its id in your database (or its URL, I can't rememrber exactly how it goes, but whatever identifies it on S3). Then, when you want to show images in the frontend, you will have a Wasp Query that will fetch relevant inforamtion from the database, basically fetching the image URLs you will then use in React. Now, how will that Query get those URLs? Well, if images are public and are set as so in your S3 bucket, then I believe you can get those URLs pretty easily. If not and images are private and not everybody can see them, then you will want to send a request toward S3 to give you those presigned URLs, and once you get them you will use them then. This is now S3 specific stuff, not really Wasp related, but I can try to help with if needed, let me know.
ivan
ivanOP•9mo ago
Thanks mate, ended up getting it working 🙂
MEE6
MEE6•9mo ago
Wohooo @ivan, you just became a Waspeteer level 1!
martinsos
martinsos•9mo ago
Awesome!
Want results from more Discord servers?
Add your server