How do I display images from an S3 bucket in Retool?

Hello Retool community! I've seen a couple of questions around displaying images from S3 in Retool apps, so I figured I'd write up a quick how to and see if anyone has anything to add. If you've got images stored in an S3 bucket, there are basically 3 ways to display them in Retool.

1) Rendering Base64

The file format that your images in S3 are stored in depends on how you got them there. In my case, I uploaded them from a Retool app using a File Picker component. When you upload a file to S3 in Retool, you can set a Content-Type – for this app, I chose binary.

On the other end, once you read these files back from S3 in Retool, they show in an octet-stream format. In most cases, you can just render that value directly as a Base64 image. We are aware of a few edge cases where this doesn't work (see here).

Note: this only works if you know the file format in advance, since rendering Base64 in HTML requires you to choose your file extension (.png, .jpeg, etc.). If you need to display images of varied formats, this method will be hard to work with.

2) Making your bucket public

If you're comfortable making your S3 bucket public (this obviously not always advisable!) then you can render images directly via their S3 URLs. The URL you're looking for general follows this format:

https://<bucket-name>.s3.amazonaws.com/<key>

So if your bucket name is krugerindustrialsmoothing and your object name is kruger, the URL would be https://krugerindustrialsmoothing.s3.amazonaws.com/kruger. Again, this only works if your S3 bucket is completely public and you have CORS configured properly since the request is going to be coming directly from your browser, unauthenticated.

3) Generating a signed URL (best)

Generating a signed URL gives you the security of only using authenticated requests (like option #1) but lets you render any image, irrespective of format, and you don't need to know the format in advance. To get started, you'll want to choose the "Generate a signed URL" action type from your S3 resource. Then you'll simply reference the signed URL in an image component:


Hope this helps! If you've figured out other ways to do this, or have any comments, chime in below!

4 Likes

Hi,

Looking for some insight in a problem I'm having displaying an image using a presigned URL for an S3 Object. I have verified that the link was working in my browser. And I have also confirmed that the link is working in retool by performing a GET request with the RESTQuery. I'm attempting to display the image using the Image Component but nothing is displaying, does anyone know what the problem is here. Any help would be really appreciated. Thanks!

Screenshot 2022-09-09 at 17.56.08

I have tried this also, but when I get the signed URL I get access denied...any ideas?

Hey @Guy_N! When are you getting this error? What does your current setup look like? Would something like this help?

Greetings! I have another problem. I have a form with user profile attributes, includeng avatar. Could you please tell me how should I orginize my code to do the following steps:

  1. User clicks 'Submit'
  2. Avatar will upload to ES3 bucket and I will get an URL
  3. After I get this url I will send all updated data (including URL to my endpoint)

Hi @Vladymyr_Radush,

For 2, you can create an s3 query that triggers on Submit:

Then, on success of that query, you can trigger your endpoint query:

If your avatar is populated by a url, you may need to run a REST query on that url to get the base64 of your avatar image (before the s3 query) so that you can upload it to s3

Thank you, it really helps!

1 Like