Skip to main content
A page layout controls how a record’s detail page is arranged: which tabs appear and what widgets they contain. Use definePageLayout() to declare a layout for an object you own, or definePageLayoutTab() to add a single tab to a layout that already exists (yours or a standard Twenty one).

definePageLayout

Use this when you own the entire detail page — typically for a custom object you defined yourself.
src/page-layouts/example-record-page-layout.ts

Key points

  • type is one of 'RECORD_INDEX', 'RECORD_PAGE', 'DASHBOARD' or 'STANDALONE_PAGE'. Use 'RECORD_PAGE' to customize the detail view of a specific object.
  • objectUniversalIdentifier specifies which object this layout applies to.
  • Each tab defines a section of the page with a title, position, and layoutMode (VERTICAL_LIST for record pages, GRID for dashboards). A tab holding a single widget renders it full-bleed automatically; with several widgets they stack as cards.
  • Each widget inside a tab can render a front component, a relation list, or other built-in widget types.
  • position on tabs controls their order. Use higher values (e.g., 50) to place custom tabs after built-in ones.

definePageLayoutTab

Use this when you only want to add a tab to an existing layout — for example, an analytics tab on the standard Company page, or an AI summary tab attached to your own object’s layout.
src/page-layouts/example-extra-tab.ts

Key points

  • pageLayoutUniversalIdentifier is required and must point to a page layout that already exists at install time — either a standard Twenty layout or one defined by your own app. Cross-app references to layouts owned by another installed app are not supported today. When the parent layout is missing, installation fails with a clear validation error.
  • For standard Twenty layouts, import identifiers from twenty-sdk/define:
    Each layout entry also exposes its tabs and their widgets, so you can reference any level:
    A short alias STANDARD_PAGE_LAYOUT is also available:
  • widgets are scoped to this tab only — they reference front components, views, etc. exactly like widgets defined inline in definePageLayout.
  • position controls ordering against existing tabs on the targeted layout. Pick a value that places your tab where you want it relative to built-in tabs.
  • Use this instead of definePageLayout when you only want to add to an existing layout. Use definePageLayout when you own the entire layout.