--- title: Diseños de Página description: Personaliza las páginas de detalle de los registros — pestañas, widgets y dónde se renderizan los componentes de frontend — usando `definePageLayout` y `definePageLayoutTab`. icon: table-columns --- Un **page layout** controla cómo se organiza la página de detalle de un registro: qué pestañas aparecen y qué widgets contienen. Usa `definePageLayout()` para declarar un layout para un objeto que posees, o `definePageLayoutTab()` para agregar una sola pestaña a un layout que ya existe (tuyo o uno estándar de Twenty). | Caso de uso | Entidad | | -------------------------------------------------------------------------- | --------------------- | | Define todo el layout para una página de registro en un objeto que posees | `definePageLayout` | | Agrega una pestaña a un layout existente (tu propio objeto o uno estándar) | `definePageLayoutTab` | ## definePageLayout Usa esto cuando eres propietario de toda la página de detalle; normalmente para un objeto personalizado que definiste tú mismo. ```ts src/page-layouts/example-record-page-layout.ts import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk/define'; import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from '../objects/example-object'; import { HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from '../front-components/hello-world'; export default definePageLayout({ universalIdentifier: '203aeb94-6701-46d6-9af1-be2bbcc9e134', name: 'Example Record Page', type: 'RECORD_PAGE', objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER, tabs: [ { universalIdentifier: '6ed26b60-a51d-4ad7-86dd-1c04c7f3cac5', title: 'Hello World', position: 50, icon: 'IconWorld', layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, widgets: [ { universalIdentifier: 'aa4234e0-2e5f-4c02-a96a-573449e2351d', title: 'Hello World', type: 'FRONT_COMPONENT', configuration: { configurationType: 'FRONT_COMPONENT', frontComponentUniversalIdentifier: HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER, }, }, ], }, ], }); ``` ### Puntos clave * `type` es uno de `'RECORD_INDEX'`, `'RECORD_PAGE'`, `'DASHBOARD'` o `'STANDALONE_PAGE'`. Use `'RECORD_PAGE'` para personalizar la vista de detalles de un objeto específico. * `objectUniversalIdentifier` especifica a qué objeto se aplica este diseño. * Cada `tab` define una sección de la página con un `title`, `position` y `layoutMode`: `VERTICAL_LIST` para páginas de registros y páginas independientes, `GRID` para paneles. En una pestaña `VERTICAL_LIST`, un solo widget se muestra a todo lo ancho y ocupa toda la pestaña; con varios widgets, se apilan como tarjetas. Una pestaña `GRID` siempre distribuye sus widgets como tarjetas en una cuadrícula de 12 columnas, sea cual sea su número, así que elige `VERTICAL_LIST` cuando quieras que un widget llene la página. * Establece `layoutMode` explícitamente. Omitirlo te da `VERTICAL_LIST` en una `STANDALONE_PAGE` y `GRID` en todos los demás casos, lo cual rara vez es lo que quieres en una página de registro. * Cada `widget` dentro de una pestaña puede renderizar un [componente de frontend](/l/es/developers/extend/apps/layout/front-components), una lista de relaciones u otros tipos de widget integrados. * `position` en las pestañas controla su orden. Usa valores más altos (p. ej., 50) para colocar pestañas personalizadas después de las integradas. ## definePageLayoutTab Usa esto cuando solo quieras **agregar** una pestaña a un layout existente; por ejemplo, una pestaña de analíticas en la página estándar de Company o una pestaña de resumen de IA añadida al layout de tu propio objeto. ```ts src/page-layouts/example-extra-tab.ts import { definePageLayoutTab, PageLayoutTabLayoutMode, STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS, } from 'twenty-sdk/define'; import { HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from '../front-components/hello-world'; export default definePageLayoutTab({ universalIdentifier: 'b1b2b3b4-b5b6-4000-8000-000000000001', pageLayoutUniversalIdentifier: STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.companyRecordPage .universalIdentifier, title: 'Hello World', position: 1000, icon: 'IconWorld', layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, widgets: [ { universalIdentifier: 'b1b2b3b4-b5b6-4000-8000-000000000002', title: 'Hello World', type: 'FRONT_COMPONENT', configuration: { configurationType: 'FRONT_COMPONENT', frontComponentUniversalIdentifier: HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER, }, }, ], }); ``` ### Puntos clave * `pageLayoutUniversalIdentifier` es **obligatorio** y debe apuntar a un page layout que ya exista en el momento de la instalación, ya sea un layout estándar de Twenty o uno definido por tu propia app. Las referencias entre apps a layouts que pertenecen a otra app instalada no son compatibles hoy en día. Cuando falta el layout padre, la instalación falla con un error de validación claro. * Para los diseños estándar de Twenty, importa los identificadores desde `twenty-sdk/define`: ```ts import { STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk/define'; // STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.companyRecordPage.universalIdentifier // STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.personRecordPage.universalIdentifier // STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.taskRecordPage.universalIdentifier // STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.opportunityRecordPage.universalIdentifier // STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.noteRecordPage.universalIdentifier // … ``` Cada entrada de diseño también expone sus `tabs` y sus `widgets`, para que puedas hacer referencia a cualquier nivel: ```ts STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.taskRecordPage.tabs.home.universalIdentifier STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS.taskRecordPage.tabs.home.widgets.fields.universalIdentifier ``` También hay disponible un alias corto `STANDARD_PAGE_LAYOUT`: ```ts import { STANDARD_PAGE_LAYOUT } from 'twenty-sdk/define'; STANDARD_PAGE_LAYOUT.companyRecordPage.universalIdentifier; ``` * `widgets` están limitados solo a esta pestaña: hacen referencia a [componentes de frontend](/l/es/developers/extend/apps/layout/front-components), vistas, etc., exactamente igual que los widgets definidos en línea en `definePageLayout`. * `position` controla el orden con respecto a las pestañas existentes en el diseño de página de destino. Elige un valor que sitúe tu pestaña donde la quieras, en relación con las pestañas integradas. * Usa esto en lugar de `definePageLayout` cuando solo quieras agregar a un layout existente. Usa `definePageLayout` cuando eres propietario de todo el layout.