Changing base schema
Learn how to create fields, update field options, and create tables from your custom extension.
Overview
The Blocks SDK provides the ability to read data from and write data to your base. This guide will showcase how you can use the SDK to also modify your base's underlying schema. This refers to what tables exist in the base, what fields make up those tables, and how those fields are configured.
The methods outlined below will allow you to programmatically create tables, create fields, and update field options, all from your custom extension. These tools are especially helpful if your extension requires a specific base schema. For example, a task tracking extension might rely on a date field to function properly. Rather than requiring the user to manually configure tables and fields accordingly, your extension can do it for them.
Create new fields
You can create a new field on an existing table using the Table.createFieldAsync
method. This method allows you to specify the field name, type, and options (if
any). For example, this could be used to automatically create a "Status" field
in a specified table, with options for "Not started", "In progress", and "Done":
import {FieldType} from '@airtable/blocks/models';import {colors} from '@airtable/blocks/ui';const newField = await table.createFieldAsync('Status', FieldType.SINGLE_SELECT, {choices: [{name: 'Not started', color: colors.RED_LIGHT_1},{name: 'In progress', color: colors.YELLOW_LIGHT_1},{name: 'Done', color: colors.GREEN_LIGHT_1},],});
Creating & updating fields via the SDK is currently supported for most field
types. Linked record fields and computed fields such as formulas, lookups, and
rollups are not currently supported. Reference the FieldType
documentation for a detailed list of supported fields & expected formats.
Update existing fields
You can update the configuration of an existing field using Field.updateOptionsAsync
. This lets you
modify field.options
, which represents the configuration of a field (for
instance, the choices of a single select field, or the precision of a number
field). The options format varies by field type, and not all field types have
configurable options. You can find the expected options format for each field
type on the FieldType
documentation page—look for "Field
options [write] format" under the appropriate field.
At this time, changing the field type is not supported. Additionally, the current API for updating options on a single or multiple select field only supports creating new options—existing options cannot be deleted.
Create new tables
You can use the Base.createTableAsync
method to create a new table, and define the initial set of fields for that
table. The first field in the list will become the primary field for your
table. Just like the main Airtable UI, only some field types can be the primary
field for a table—refer to this support article
for more details.
As an example, this method could be used to create a "Tasks" table with the following 4 fields:
- Name (text field, primary)
- Due date (date field)
- Assignee (collaborator field)
- Status (single select field)
import {base} from '@airtable/blocks';import {FieldType} from '@airtable/blocks/models';import {colors} from '@airtable/blocks/ui';const newTasksTable = await base.createTableAsync('Tasks', [{name: 'Name', type: FieldType.SINGLE_LINE_TEXT},{name: 'Due date', type: FieldType.DATE, options: {dateFormat: {name: 'us'}}},{name: 'Assignee', type: FieldType.SINGLE_COLLABORATOR},{name: 'Status',type: FieldType.SINGLE_SELECT,options: {choices: [{name: 'Not started', color: colors.RED_LIGHT_1},{name: 'In progress', color: colors.YELLOW_LIGHT_1},{name: 'Done', color: colors.GREEN_LIGHT_1},],},},]);
Usage
Just like the other SDK write methods for creating, updating, and deleting
records, each of these new methods comes with built-in permission check
helpers: checkPermissionsFor[Action]
and hasPermissionTo[Action]
. Reference
Write back to Airtable: Permissions
for an overview of how to use these helpers to ensure only permitted actions
can be performed in your extension.
Here’s an example of how to employ these permission checks:
import {FieldType} from '@airtable/blocks/models';import {Box, Button, Text} from '@airtable/blocks/ui';function CreateFieldButton({table}) {const permissionCheckResult = table.checkPermissionsForCreateField();function createField() {if (table.hasPermissionToCreateField()) {table.createFieldAsync('New field', FieldType.SINGLE_LINE_TEXT);}}return (<Box><Buttondisabled={permissionCheckResult.hasPermission}onClick={createField}>Create field</Button>{!permissionCheckResult.hasPermission && (<Text marginTop={2}>{permissionCheckResult.reasonDisplayString}</Text>)}</Box>);}
These new base schema methods also share the same principles as the other write methods for asynchronous execution and rate limiting.