Hey everyone,
I recently got a question about how to access an image from an attachment field in Grist and display it in a custom widget. I’ll try to summarize it here for anyone interested.
To download an attachment Grist exposes an API endpoint available here.
Unfortunately, the Grist API isn’t directly accessible from the browser for security reasons, but there’s a special endpoint you can use to get a short-lived access token. This token lets you safely access attachments within your custom widget (even those built using Custom widget builder).
I’ve created a demo you can check out here: Attachments in builder - Grist
Here’s how to do it:
- Get the Attachment ID
The column in Grist stores a list of attachment IDs. You can grab the first one withrecord.ColumnName[0]
. - Get the Access Token
Usegrist.docApi.getAccessToken()
to get a short-lived token and the base URL for the document. - Build the URL
Join the base URL, attachment ID, and token to form the full URL for the attachment data. - Display the Image
Use the URL in an<img>
tag to display the image or use it in any other way you like.
Here is a very simple code that demonstrate it (part of the example above):
grist.ready({ requiredAccess: 'full' });
const imageEl = document.getElementById("image");
let token = "";
let baseUrl = "";
function updateImageUrl(id) {
const url = `${baseUrl}/attachments/${id}/download?auth=${token}`;
imageEl.src = url; // Set the URL as the image source
}
// Get the access token and base URL
grist.docApi.getAccessToken({ readOnly: true }).then(response => {
token = response.token;
baseUrl = response.baseUrl;
});
// Listen for changes to the current record
grist.onRecord(record => {
const attachmentId = record.Image?.[0]; // Get the first attachment ID
if (attachmentId) {
updateImageUrl(attachmentId);
}
});