Airtable Extensions user interface guidelines
Introduction
Airtable provides a toolkit of components that users can assemble to create their own software. By composing tables, views, fields, and records, users can create the ideal structure, logic, and interfaces for their workflows. You can extend this kit by building blocks to let users visualize, collaborate, and analyze their information in new ways.
Extensions are installed inside Airtable bases, and each extension can be installed multiple times. Each extension installation has its own settings, perhaps for different collaborators or distinct workflows. Each extension can read and write data in all tables in the base it’s installed in, but typically extensions rely on a single source table and view. This allows users to specify which slice of their data they want to display or update. Each extension defines its own UI based on what it does — for the most part, these fall into one of a few common Archetypes . Extension installations are displayed in a dashboard, which can either be viewed alongside a table in a sidebar or viewed in fullscreen mode.
The goal of these guidelines is to convey the core design principles for extensions, along with specific practical UI and UX recommendations you can implement for better consistency and cohesion with the Airtable platform. By following these patterns, your extension will feel more familiar to Airtable users. They will be able to learn how to use your extension more quickly and effectively.
Principles
Extensions follow three core product principles — they should be composable, flexible, and collaborative. Use these themes to make design decisions and inform the ideal behavior of your extension.
Composable
Extensions are modular extensions that compose with the rest of the base and with one another. Whenever possible, an extension should reuse configuration defined elsewhere in the base, such as view settings or field options. This allows users to define something once and use it in multiple places — this reduces the effort needed to set up an extension and makes it easier to maintain and change the configuration in the future. Generally, extensions should treat the base as the source of truth for application data. By fetching data from and saving data back to the base, each extension installation can automatically stay in sync with one another and operations can “flow” between them. For example, a user could modify a table with the batch update extension and instantly see those changes reflected in a summary extension pointing to the same table. You don’t need to build charting into your extension if users can install the existing chart extension alongside your extension.
Flexible
Airtable is used for a wide range of different use cases across industries. Even within a single use case, bases can look totally different depending on the specific team or workflow. As a result, extensions should be flexible and integrate into a variety of bases. An extension should not make too many assumptions about the schema of the base it’s installed in. The more requirements an extension has, the harder it is for an end user to set up. However, this doesn’t mean that an extension shouldn’t make any assumptions — often, extensions rely on the existence of certain fields for their core functionality. For example, the timeline and Gantt extensions both require start and end date fields. Extensions should have customization options to support different use cases and user preferences. These options can be unique to the extension or inherited from a source view (e.g. record coloring).
Collaborative
Extensions are used in a real-time, collaborative environment where it’s possible for multiple users to access or modify some of the same data simultaneously. Generally speaking, an extension should use the most up-to-date information from the base it’s installed in, so that users always see current, accurate data and have a more responsive multi-user experience. In certain scenarios, an extension might need to break out of this constraint and “freeze” data in local state. This is usually the case for actions or procedures that might take an extended period of time, such as mapping fields for an import extension or editing code in the scripting extension. Occasionally, the table, view, or fields that an extension installation relies on might get reconfigured or deleted entirely. Other times, the user of an extension might not have the necessary permissions to perform a particular action. Extensions should be robust enough to handle these states gracefully.
Archetypes
The extensions that have been released so far mostly fall into one of the following archetypes, each with its own architectural patterns. If the extension you’re building fits into one of these categories, we recommend that you look at the relevant examples for reference. Not every extension maps neatly to one of the archetypes and we anticipate new archetypes emerging as the Extensions platform grows.
Visualization
image.png
image.png
image.png
Examples: Gantt, simple chart, flowchart
Visualization extensions take lists of records and display them in a particular UI. This can be a static visualization like a bar chart or an interactive visualization like a Gantt chart. Typically, these extensions consist of a settings sidebar, where the user can pick the source table, view, and fields and customize the visualization itself. These extensions should always display up-to-date data from the base and should offer an easy way to navigate to expanded records for full details and convenient editing. For improved ergonomics, the most important types of edits for that visualization can be implemented in the extension as a first-class feature, like drag and drop for changing categories in matrix extension or rescheduling in Gantt extension.
Wizard
image.png
image.png
Examples: Dedupe, update records
Wizard extensions perform actions or guide users through structured flows. These tend to either be “push button” interfaces or linear procedures. Usually, these extensions are set up once and are not regularly reconfigured — it’s more likely that these extensions will be installed multiple times for different flows. For these extensions, descriptive headings and instructional help text should be included for each step of the process. Moreover, it’s important to include some sort of confirmation step or the ability to revert updates if there’s a possibility for destructive changes to the base.
Import/sync/enrichment
image.png
image.png
Examples: CSV import, wikipedia enrichment
Import, sync, and enrichment extensions are a particular type of wizard extensions that take data from an external source (either a file or a third-party API) and save them to an Airtable base. In the file import case, the initial screen of the extension will usually be a file upload/dropper UI. In the third-party API case, the extension will typically feature more detailed onboarding to guide the user through the process of creating an API key for the service and adding it to the extension. Both kinds usually involve a field mapping step, where the user defines how the source data should be saved in Airtable.
Editor environment
image.png
image.png
Examples: Page designer, scripting
Editor environment extensions have distinct “edit” and “view” modes. Typically the extension will be set up and edited by a smaller set of creators, while other collaborators mostly consume or use the end product. These extensions are unique in that much of their content is stored in global config, even though extensions usually save data back to a table. For example, the page designer extension saves the layout information and the scripting extension saves the script code in global config, since this data does not directly describe records in the base. This content is specific to a particular extension installation, so it does not need to be shared with other extension installations in the base.
Patterns
For more information, also refer to the Polishing your extension guide.
Architecture
Onboarding
image.png
image.png
Determine if your extension requires a dedicated onboarding flow for first-time users. If your extension requires involved setup or user input (typically Wizard extensions), consider adding an introductory sequence with those instructions. For simpler extensions, you can start directly on the settings screen or rely on clear, descriptive help text to assist the user.
Settings
The first time your extension is run, pre-populate the extension settings with sensible defaults and “best guesses”. For example, the timeline extension automatically uses the active table and view for source data, the first date field for the start date, and the first select field for record coloring. This optimizes for having something actually show up when a user initially installs the extension.
In most cases, the settings for your extension should live within a dedicated settings screen or sidebar. These settings should be ordered in terms of importance — picking a source table, view, and fields should be at the top, followed by optional fields or other customization options. For Visualization extensions, use a settings sidebar and reflect changes in real-time, so that the user can fine-tune options as they go without having to switch back and forth between screens.
If there is an invalid setting or a required setting is missing, your extension should call this out to the user with an actionable validation error. One common UI pattern is to add a persistent bottom bar to your settings screen or sidebar:
image.png
You can also call out these configuration issues on the main screen of the extension, either by using a bottom bar or an empty state.
In some Wizard extensions, certain settings like field mappings might actually change with every session — these can be lifted out of the settings screen and put on the main screen. As an example, the CSV import extension doesn’t have a separate settings screen that the user toggles on/off. Instead, each time a user uploads a file, they can change the settings as part of the import flow.
image.png
Infrequently changed configuration settings like API keys should still be kept on a separate settings screen.
Communication
All screens should have a heading, unless it’s the main screen/canvas of a Visualization extension. Optionally, you can add help text underneath the heading for more detail. For all UI copy, use sentence case rather than title case (e.g. “Choose a date field” rather than “Choose a Date Field”).
On every screen, there should be at most one primary action button (or danger button, if the primary action is dangerous). Buttons that only have an icon without a text label should be used sparingly — they are best used in a toolbar of buttons of the same variant. Buttons should be labeled with simple verbs (e.g. “Update” or “Publish”) that describe the action that will be performed. One notable exception to this rule is the “Done” button.
For actions that a user cannot perform, it is better to disable controls rather than conditionally hide them. For example, if your extension requires editor permissions to run, you could disable the primary action button for read-only collaborators and wrap it in a tooltip that explains the necessary permissions.
When referring to a table, view, field, or record from the base, use the model’s name (or primary cell value, in the case of records) followed by the model type. You can wrap the model name in quotation marks or make the text strong to distinguish it from the rest of the UI copy. For example:
- Good:
Are you sure you want to delete the "Table" record?
Are you sure you want to delete the Table record? - Bad:
Are you sure you want to delete this record?
Are you sure you want to delete Table?
In some cases, you may need to truncate long strings to one line — you can do this by adding ellipses at the end of the displayed string.
Data persistence
In general, your extension should use the base as the source of truth and write back to the base when making updates. Besides the base, there are two other options for data persistence: global config and local storage.
Global config is a key-value store for each extension installation and should be used for storing extension-specific settings like the IDs of the source table and view. For example, the todo list extension stores the IDs of a tasks table, a tasks view, and a “Done” field in global config. This data is shared between all collaborators and most extensions automatically update when a value in global config changes.
Occasionally, extensions will not only store its configuration in global config, but also its content. As an example, the description extension stores markdown in global config. It doesn’t really make sense to save this back to a table, since it isn’t an attribute of particular record or set of records in the base. One caveat is that global config can only store up to 100kB of data.
In cases where the source table may change (e.g. field mappings), you may want to consider storing the configuration per table, so that switching tables doesn’t clear out previous settings. You don’t need to clean up global config if models get deleted — this way, the configuration is retained if the user undoes the deletion or restores the deleted item from trash.
Local storage is for per-user (per-browser, to be precise) configuration and should be used sparingly. This is most useful for more transient UI state, like zoom level or whether a certain panel is collapsed or expanded.
Viewports
By default, an extension installation runs in fullscreen mode the first time it runs. In future sessions, the extension installation can be run in one of three viewports: fullscreen, in the sidebar dashboard, or in a fullscreen dashboard.
image.png
image.png
image.png
Within each of these viewports, the extension frame can be resized. Your extension can gracefully handle different viewport sizes by conditionally showing different UI. You can use responsive web design techniques like stacking your layout vertically or changing the settings sidebar to a side sheet or full settings screen. You could also consider displaying a summary or single primary action button when the extension is small.
As a last resort, the extension can define a minimum viewport size, which means that installations of the extension will be disabled when they’re smaller than a certain size. For some interactions, you may want to force the extension installation to enter fullscreen mode — for example, when displaying UI that requires significant screen real estate, like the scripting extension code editor or the dedupe extension merge interface.
Your extension can also define a maximum viewport size when it’s in fullscreen mode. This can be useful for screens in your extension that don’t have much content or screens where you want finer-grained control over the sizing of the UI, like during the introductory sequence of your onboarding flow.
FAQ
What is the difference between an extension and a script?
With the launch of the scripting extension, we introduced a new component to the Airtable toolkit. Scripts are small programs that users can run by clicking a button. They are ideal for reducing time spent on repetitive tasks or creating guided user flows. By contrast, every extension is a full React app. Building an extension requires knowledge of React and a local development environment. Scripting works in the browser and only requires basic familiarity with JavaScript. As a result, the extensions SDK has a much wider surface area than the scripting extension APIs.
When deciding whether to build an extension or a script, consider the following:
- Do you need custom UIs beyond basic form inputs?
- Do you need real-time interaction between multiple users?
- Do you need to persist settings between sessions?
- Do you need to display information or visuals without user interaction?
If you answered “yes” to any of these questions, it’s likely that you should be building an extension instead of a script.