Kuovonne's Guide to Scripting in Airtable
Share
Explore
Free Scripts

Interface Sidesheet Url

Your donations tell Kuovonne that you value her content and want her to continue publishing.

Inspiration

I created an interface page with a sidesheet for linked records. These records do not have full interface pages on their own, only the sidesheet. I also wanted to send a notification email when data about the sidesheet records changed, including a link to the record in the sidesheet.
However the url for a sidesheet is more complicated than the url for single record in an interface page. You can grab the url for a particular sidesheet record when actually viewing the record, but you cannot build the url using a formula field.

Animation.gif

Discussion

Understanding the sidesheet url format

At first the url for a record in a sidesheet looks horribly complicated.
https://airtable.com/appXXXXXXXXXXXXXX/pagXXXXXXXXXXXXXX/?F2o88=recXXXXXXXXXXXXXX&detail=eyJwYWdlSWQiOiJwYWdYWFhYWFhYWFhYWFhYWCIsInJvd0lkIjoicmVjWFhYWFhYWFhYWFhYWFgifQ
The first part of the url before the ? is actually fairly straightforward. It’s the base ID appXXXXXXXXXXXXXX followed by the page ID of the interface page pagXXXXXXXXXXXXXX.
https://airtable.com/appXXXXXXXXXXXXXX/pagXXXXXXXXXXXXXX/
After the ? are the url parameters joined by &. The first url parameter identifies the ID of the record picker element on the main page and the ID of the record that is picked.
F2o88=recXXXXXXXXXXXXXX
The second url parameter identifies details about the sidesheet.
detail=eyJwYWdlSWQiOiJwYWdYWFhYWFhYWFhYWFhYWCIsInJvd0lkIjoicmVjWFhYWFhYWFhYWFhYWFgifQ
That value of the detail parameter is a base64 encoded JSON string. After base64 decoding, the above string looks like a JavaScript object with a pageId for the sidesheet and a rowId for the record ID.
{"pageId":"pagXXXXXXXXXXXXXX","rowId":"recXXXXXXXXXXXXXX"}
Here’s all the parts that go into the url for the sidesheet
base ID
page ID of the main interface page
element ID of the record picker in the main interface page
record ID of the record in the main interface page
page ID of the sidesheet
record ID of the record in the sidesheet

Gathering IDs from the Interface

First gather the IDs of the main interface page and its record picker from the url for the page. Notice that the record picker element ID is a short string of characters, not a three letter prefix followed by 14 other characters.
const mainInterfacePageId = "pagMainPageXXXXXX"
const mainInterfacePageRecordPickerId = "F2o88"
Then get the ID of the sidesheet. This ID isn’t exposed when the page is a sidesheet, but you can temporarily set the page to show full screen, and then get the ID from the url. ​
image.png
const sidesheetInterfacePageId = "pagSideSheetXXXXX"

Getting IDs for the records

This script will calculate the sidesheet URL for a single child record. The script needs to get that record.
const table = base.getTable("Child Table")
const childRecord = await input.recordAsync("Pick a record", table)
We can get the ID of the parent record from the field linking to the parent record.
const linkedRecordCellValue = childRecord.getCellValue("Link to Parent Record")
const parentRecordId = linkedRecordCellValue[0].id

Building the details portion of the url

Start building the details portion of the sidesheet url as a JavaScript object.
const sidesheetDetail = {
"pageId": sidesheetInterfacePageId,
"rowId": childRecord.id
}
Then convert that JavaScript object into JSON string.
const sidesheetDetailJson = JSON.stringify(sidesheetDetail)
And base64 encode that JSON string.
const base64encodedSidesheetDetail = btoa(sidesheetDetailJson)

Assemble the final url

You now have all the pieces to build the sidesheet url. This line of code probably displays on multiple lines, but it is really a single line of code.
const sidesheetUrl = `https://airtable.com/${base.id}/${mainInterfacePageId}/?${mainInterfacePageRecordPickerId}=${parentRecordId}&detail=${base64encodedSidesheetDetail}`
Finally, store the sidesheet url in an editable field in the child record.
await table.updateRecordAsync(childRecord, {
"Sidesheet Interface URL": sidesheetUrl
})

The full script

const mainInterfacePageId = "pagMainPageXXXXXX"
const mainInterfacePageRecordPickerId = "F2o88"
const sidesheetInterfacePageId = "pagSideSheetXXXXX"

const table = base.getTable("Child Table")
const childRecord = await input.recordAsync("Pick a record", table)
const linkedRecordCellValue = childRecord.getCellValue("Link to Parent Record")
const parentRecordId = linkedRecordCellValue[0].id

const sidesheetDetail = {
"pageId": sidesheetInterfacePageId,
"rowId": childRecord.id
}
const sidesheetDetailJson = JSON.stringify(sidesheetDetail)
const base64encodedSidesheetDetail = btoa(sidesheetDetailJson)
const sidesheetUrl = `https://airtable.com/${base.id}/${mainInterfacePageId}/?${mainInterfacePageRecordPickerId}=${parentRecordId}&detail=${base64encodedSidesheetDetail}`

await table.updateRecordAsync(childRecord, {
"Sidesheet Interface URL": sidesheetUrl
})

info
Note that this script only works in Scripting Extension for a single record. If you want to run this in an automation, you will need to make several changes, including how you get the triggering record and using a substitute for the btoa function, which is not available in automation scripts.
The content in this guide is free, but creating it takes time and money. If you like this content, .

Share
 
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.