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.
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 (
.jpeg, etc.). If you need to display images of varied formats, this method will be hard to work with.
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:
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.
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!