How to Upload Images to your S3 Bucket through just their URLs on Appsmith

abhik varma
affinityanswers-tech
5 min readDec 14, 2021

We were recently working on an internal application to update the information of our client accounts. We chose Appsmith for this job. Being a low-code platform, it enables us to connect to our databases and quickly set up internal applications without any fuss. Of course, as with all low-code/ no-code platforms, we sacrifice some functionality for ease of use. We noticed this in Appsmith when trying to update our client logos.

Let me explain the problem in detail. When we update our client logos (or any images for internal use), we store them in our public S3 bucket, which acts as a Content Delivery Network. This way, we don’t have to worry about the image’s source website going down or getting deprecated. We wanted to enter the chosen logo’s URL and, with one click of a button, upload it to our bucket and update our MySQL database with the new URL (pointing to our S3 bucket). Now, Appsmith has the functionality to upload locally stored images straight to S3 buckets using their Filepicker widget, but it doesn’t let us do the same with image URLs.

No one wants their local storage littered with client logos, and so in a quest to streamline the process, we found a workaround. By using GET requests, we could get the image data straight from its URL. The URL entered can first be verified to make sure it points to an image. Once verified, the GET request’s response body data can be used to upload the image to the S3 bucket.

So now that you have a brief idea of our implementation let’s get into the details.

Placing the Widgets

We need a text input widget to get the URL, two buttons (verification and submission), and an image widget. We placed the image widget inside a dark-coloured container to view PNGs correctly.

Setting up the Data Sources

Data sources let Appsmith talk to various databases and make API calls with ease. We can easily connect to one by heading over to Datasources (on the left pane)> Create New and choosing the required data source.

We start by creating a new API and naming it get_logo_data. It is set to take the text from the input widget and perform a GET request.

Next, we need to connect our S3 service to Appsmith. It lets us connect to Amazon S3, Upcloud, Wasabi and virtually any other S3 service provider by filling in the required access details and hitting save.

We must set up two Create a new file queries under the S3 data source.

Appsmith converts the response body for URLs pointing to PNGs and JPGs to a Base64 encoded string. But if the URL points to an SVG, the response body contains the SVG+XML describing the image. These two cases need to be saved with different file extensions and data types, hence the two queries.

Note: you might notice variable names in the screenshots; these will be cleared up in the next section where we set up the widgets.

For PNGs and JPGs, the File Path should end with “.png”, File Data Type should be set to “Base64” and the type property of the Content object to “image/png”. We named it upload_img_base64.

For SVGs, the File Path should end with “.svg”, File Data Type should be set to “Text / Binary” and the type property of the Content object to “image/svg+xml”. We named it upload_img_svg.

In both cases, the data property of the Content object is given by the response data and the Bucket Name is set to the bucket of your choice. We recommend adding a version folder (use epoch time) for each image since new queries with the same file name don’t get overwritten.

Setting up the Widgets

Now that the widgets are in place and the data sources ready, we can add the logic in the widgets.

The onClick event on the verify button is set to

{{get_logo_data.run();}}

This runs the GET request, and we get a response. This response is used to enable the image widget and submit button using the following script.

{{
change_logo_link.text.length!=0 && JSON.stringify(get_logo_data.responseMeta).includes('Content-Type":["image')
}}

The widgets will be enabled when text is present in the input widget, and the response metadata indicates that it’s an image. The image widget displays the image using the text data in the input widget.

{{change_logo_link.text}}

Finally, the submit button’s onClick event is set to

{{
storeValue('logo_version',Date.now(),false);
storeValue('logo_data',get_logo_data.data,false);
storeValue('logo_link',change_logo_link.text,false);
get_logo_data.data.slice(-1)==='>'?
upload_img_svg.run(() =>
change_logo_query.run(()=> showAlert('Success','success'),
() => showAlert('Query Failed','error'))
:upload_img_base64.run(() =>
change_logo_query.run(()=> showAlert('Success','success'),
() => showAlert('Query Failed','error'))
}}

It stores the epoch time and response data for use in the file upload queries. It then checks for the last character in the response data. In the case of SVGs, the final character will always be set to ‘>’, and since this character isn’t found in Base64 encoded strings, it can be used to differentiate between the type of image and run the correct queries.

Now that everything is in place, you can easily upload images to your S3 bucket in one click.

--

--