src/app/extensions/ whose extension.tsx default-exports a defineExtension call with type: "record-tab". See App structure for the discovery rules.
Use it for content that doesn’t fit a widget: tables, timelines, a dashboard about the record. For UI that isn’t about one record, use a page.
Unlike widgets, record tabs don’t need to be added by hand. Once a workspace installs your app, the
tab appears on every record page it targets, after Attio’s own tabs.
Example
The tab component itself can live in a sibling file inside the extension folder:src/app/extensions/enrichment/extension.tsx
src/app/extensions/enrichment/enrichment-tab.tsx
Arguments
"record-tab"
required
Identifies this extension as a record tab.
string
required
The unique identifier for this tab. It is the last segment of the tab’s URL and the value you pass
as
tab when navigating to it. Never shown to the user.It must not be the slug of a built-in tab. Using one fails the build with
RECORD_TAB_ID_IS_NATIVE_TAB_SLUG. The reserved slugs are overview, activity, calls,
notes, tasks, emails, files, team, company, companies, associated_people and
associated_users.string
required
The label shown in the record page tab bar.
(props: { recordId: string, object: ObjectSlug }) => React.JSX.Element
required
A React component that renders the contents of the tab.It can suspend while loading data. Return an
EmptyState as the
only child when there is nothing to show yet.ObjectSlug | Array<ObjectSlug>
A single slug or an array of slugs selecting which objects the tab appears on.Defaults to
undefined, which shows the tab on all objects.The built-in slugs areWhere the tab appears
After install, the tab shows on every record page matchingobjects, placed after Attio’s built-in tabs. Workspace admins can remove it, add it back and reorder it through “Configure page” on the record page, the same editor they use for the built-in tabs. You don’t need to document any of that for your users: it works like every other tab.
Deep links
Every record tab has a stable URL:Destinations.record with the tab option rather than assembling the path yourself.