How Airtable’s Blocks SDK handles attachment URLs
  • 14 Sep 2022
  • 2 Minutes to read
  • Dark
    Light

How Airtable’s Blocks SDK handles attachment URLs

  • Dark
    Light

On November 8, 2022, Airtable will improve the security of our attachment URLs by incorporating an expiring links functionality across our product surface areas. You can read more about this decision here.

This update includes changes to the way all versions of the Blocks SDK handles attachments.

If you use the following SDK methods to obtain attachment URLs, please keep in mind that the update impacts the following:

How does the SDK handle attachment URLs today?

Attachment URLs obtained via the SDK are persistent. Methods like getCellValue return a static URL that can be interpreted.

Attachment URLs currently look like this:

https://dl.airtable.com/.attachments/4df81a26d0a04015fa2935f99cd73014/1f055329/image_9201.jpg

What’s changing?

Attachment URLs obtained via the SDK will expire after a few hours. After those URLs expire, the Blocks SDK will refresh the URLs, pushing any expired URLs to your 3rd party extension. And finally, we're changing the format of the attachment URL so that it can not be interpreted.

Starting November 8th, attachment URLs will look like this:

https://v5.airtableusercontent.com/v1/3/3/1652918400000/2dxLFHD0M8rGi29amOeYiQ/RKjaja0qgtEUzIPu6HsnYbC3HPiCkiK4wfhB9**dJJJpVUlwitX0puZY9v485L0SUGnZEU3cSBDR6-wdZseNtg/hN5S51oabftFYcDU2rPOB838AzaI4u98-Wc-Li4GwB8

How can I prepare for this update and avoid a breaking change?

We recommend using hooks to review attachment URLs as they expire and refresh. For example, the following hooks allow you to confirm attachment URLs refresh:


// this component renders the first image from the record’s attachment field, and will automatically re-render the image when the URL is refreshed

function RenderFirstImage({table, recordId, attachmentField}) {
    // useRecordById hook watches for the attachment url refresh.
    const record = useRecordById(table, recordId);
    const imageAttachments = record.getCellValue(attachmentField);
    const coverImageAttachment = imageAttachments[0];
    const url = coverImageAttachment.url;
    const clientUrl = record.getAttachmentClientUrlFromCellValueUrl(coverImageAttachment.id, url);

 return <div>{clientUrl && <img src={clientUrl} alt="" height="100%" />}</div>;
}

How to prepare for URLs breaking

For workflows that are dependent on the format of the attachment URL or identifiers within it (eg: filename), after the changes to attachments go live in November, there will be nothing in the attachment URL that can be interpreted in a meaningful way. To reiterate, the attachment URL formatting is not part of our compatibility surface, so users should not attempt to parse or interpret attachment field URLs.


// the following parsing logic will break because filename is no longer included in the url.
const pathComponents = attachmentUrl.split('/')
const fileName = pathComponents[pathComponents.length -1]
console.log(fileName);

Keep in mind not to use URLs as stable identifiers. Attachment URLs will refresh after a short period.


/ the following logic will download the same attachment content repeatedly, because the attachmentUrl will refresh.

// downloadedAttachmentUrlsSet is a global set storing downloaded attachment urls
if (!downloadedAttachmentUrlsSet.has(attachmentUrl)) {
downloadedAttachmentUrlsSet.add(attachmentUrl);
triggerDownloadNewAttachment(attachmentUrl);
}

In addition, do not store URLs for future usage. Any URLs you store will expire after a few hours.


import \* as fs from 'fs';
fs.writeFileSync("attachmentUrls.txt", attachmentUrl);
// some time later
const savedAttachmentUrl = fs.readFileSync("attachmentUrls.txt");
// the savedAttachmentUrl may be expired.
triggerDownLoadNewAttachment(savedAttachmentUrl); 

Who can I contact if I have questions about the update?

Please reach out to Airtable Support with any questions.


Was this article helpful?

What's Next