Skip to content

Commit 0adaf8a

Browse files
docs: use twenty-sdk/define subpath in docs and website demo (#19908)
## Summary Following the recent move of `defineXXX` exports (e.g. `defineLogicFunction`, `defineObject`, `defineFrontComponent`, …) from the `twenty-sdk` root entry to the `twenty-sdk/define` subpath, this PR aligns the documentation and the marketing site so users see the correct import paths. - `packages/twenty-docs/developers/extend/apps/building.mdx`: every code snippet now imports `defineXXX` and related types/enums (`FieldType`, `RelationType`, `OnDeleteAction`, `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`, `PermissionFlag`, `ViewKey`, `NavigationMenuItemType`, `PageLayoutTabLayoutMode`, `getPublicAssetUrl`, `DatabaseEventPayload`, `RoutePayload`, `InstallPayload`, …) from `twenty-sdk/define`. Mixed imports were split so that hooks and host-API helpers (`useRecordId`, `useUserId`, `useFrontComponentId`, `enqueueSnackbar`, `closeSidePanel`, `pageType`, `numberOfSelectedRecords`, `objectPermissions`, `everyEquals`, `isDefined`) come from `twenty-sdk/front-component`. - `packages/twenty-website-new/.../DraggableTerminal/TerminalEditor/editorData.ts`: the 29 demo source strings shown in the homepage's draggable terminal now import from `twenty-sdk/define`. Example apps under `packages/twenty-apps/{examples,internal,fixtures}` were already using the right subpaths, so no code changes were needed there. Translations under `packages/twenty-docs/l/` are intentionally left untouched — they will be refreshed via Crowdin from the English source. ## Test plan - [ ] Skim the rendered `building.mdx` on Mintlify preview to confirm code snippets look right. - [ ] Visual check on the website's draggable terminal demo. Made with [Cursor](https://cursor.com)
1 parent 41ee6ea commit 0adaf8a

2 files changed

Lines changed: 68 additions & 66 deletions

File tree

  • packages
    • twenty-docs/developers/extend/apps
    • twenty-website-new/src/sections/Hero/components/HomeVisual/DraggableTerminal/TerminalEditor

packages/twenty-docs/developers/extend/apps/building.mdx

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
defineRole,
2929
PermissionFlag,
3030
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
31-
} from 'twenty-sdk';
31+
} from 'twenty-sdk/define';
3232

3333
export default defineRole({
3434
universalIdentifier: '2c80f640-2083-4803-bb49-003e38279de6',
@@ -77,7 +77,7 @@ Every app must have exactly one `defineApplication` call that describes:
7777
- **(Optional) Pre-install / post-install functions**: logic functions that run before or after installation.
7878

7979
```ts src/application-config.ts
80-
import { defineApplication } from 'twenty-sdk';
80+
import { defineApplication } from 'twenty-sdk/define';
8181
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
8282

8383
export default defineApplication({
@@ -132,7 +132,7 @@ The `defaultRoleUniversalIdentifier` in `application-config.ts` designates the d
132132
When you scaffold a new app, the CLI creates a default role file:
133133

134134
```ts src/roles/default-role.ts
135-
import { defineRole, PermissionFlag } from 'twenty-sdk';
135+
import { defineRole, PermissionFlag } from 'twenty-sdk/define';
136136

137137
export const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER =
138138
'b648f87b-1d26-4961-b974-0908fd991061';
@@ -172,7 +172,7 @@ Notes:
172172
Custom objects describe both schema and behavior for records in your workspace. Use `defineObject()` to define objects with built-in validation:
173173

174174
```ts postCard.object.ts
175-
import { defineObject, FieldType } from 'twenty-sdk';
175+
import { defineObject, FieldType } from 'twenty-sdk/define';
176176

177177
enum PostCardStatus {
178178
DRAFT = 'DRAFT',
@@ -261,7 +261,7 @@ Key points:
261261
Use `defineField()` to add fields to objects you don't own — such as standard Twenty objects (Person, Company, etc.) or objects from other apps. Unlike inline fields in `defineObject()`, standalone fields require an `objectUniversalIdentifier` to specify which object they extend:
262262

263263
```ts src/fields/company-loyalty-tier.field.ts
264-
import { defineField, FieldType } from 'twenty-sdk';
264+
import { defineField, FieldType } from 'twenty-sdk/define';
265265

266266
export default defineField({
267267
universalIdentifier: 'f2a1b3c4-d5e6-7890-abcd-ef1234567890',
@@ -311,7 +311,7 @@ Suppose a `PostCard` can be sent to many `PostCardRecipient` records. Each recip
311311
**Step 1: Define the ONE_TO_MANY side on PostCard** (the "one" side):
312312

313313
```ts src/fields/post-card-recipients-on-post-card.field.ts
314-
import { defineField, FieldType, RelationType } from 'twenty-sdk';
314+
import { defineField, FieldType, RelationType } from 'twenty-sdk/define';
315315
import { POST_CARD_UNIVERSAL_IDENTIFIER } from '../objects/post-card.object';
316316
import { POST_CARD_RECIPIENT_UNIVERSAL_IDENTIFIER } from '../objects/post-card-recipient.object';
317317

@@ -338,7 +338,7 @@ export default defineField({
338338
**Step 2: Define the MANY_TO_ONE side on PostCardRecipient** (the "many" side — holds the foreign key):
339339

340340
```ts src/fields/post-card-on-post-card-recipient.field.ts
341-
import { defineField, FieldType, RelationType, OnDeleteAction } from 'twenty-sdk';
341+
import { defineField, FieldType, RelationType, OnDeleteAction } from 'twenty-sdk/define';
342342
import { POST_CARD_UNIVERSAL_IDENTIFIER } from '../objects/post-card.object';
343343
import { POST_CARD_RECIPIENT_UNIVERSAL_IDENTIFIER } from '../objects/post-card-recipient.object';
344344

@@ -379,7 +379,7 @@ import {
379379
RelationType,
380380
OnDeleteAction,
381381
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
382-
} from 'twenty-sdk';
382+
} from 'twenty-sdk/define';
383383
import { SELF_HOSTING_USER_UNIVERSAL_IDENTIFIER } from '../objects/self-hosting-user.object';
384384

385385
export const PERSON_FIELD_ID = 'c3333333-3333-3333-3333-333333333333';
@@ -448,8 +448,8 @@ export default defineObject({
448448
Each function file uses `defineLogicFunction()` to export a configuration with a handler and optional triggers.
449449

450450
```ts src/logic-functions/createPostCard.logic-function.ts
451-
import { defineLogicFunction } from 'twenty-sdk';
452-
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
451+
import { defineLogicFunction } from 'twenty-sdk/define';
452+
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk/define';
453453
import { CoreApiClient, type Person } from 'twenty-client-sdk/core';
454454

455455
const handler = async (params: RoutePayload) => {
@@ -519,7 +519,7 @@ When a route trigger invokes your logic function, it receives a `RoutePayload` o
519519
Import the `RoutePayload` type from `twenty-sdk`:
520520

521521
```ts
522-
import { defineLogicFunction, type RoutePayload } from 'twenty-sdk';
522+
import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define';
523523

524524
const handler = async (event: RoutePayload) => {
525525
const { headers, queryStringParameters, pathParameters, body } = event;
@@ -584,7 +584,7 @@ Logic functions can be exposed as **tools** for AI agents and workflows. When ma
584584
To mark a logic function as a tool, set `isTool: true`:
585585

586586
```ts src/logic-functions/enrich-company.logic-function.ts
587-
import { defineLogicFunction } from 'twenty-sdk';
587+
import { defineLogicFunction } from 'twenty-sdk/define';
588588
import { CoreApiClient } from 'twenty-client-sdk/core';
589589

590590
const handler = async (params: { companyName: string; domain?: string }) => {
@@ -650,7 +650,7 @@ export default defineLogicFunction({
650650
A post-install function is a logic function that runs automatically once your app has finished installing on a workspace. The server executes it **after** the app's metadata has been synchronized and the SDK client has been generated, so the workspace is fully ready to use and the new schema is in place. Typical use cases include seeding default data, creating initial records, configuring workspace settings, or provisioning resources on third-party services.
651651

652652
```ts src/logic-functions/post-install.ts
653-
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk';
653+
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
654654

655655
const handler = async (payload: InstallPayload): Promise<void> => {
656656
console.log('Post install logic function executed successfully!', payload.previousVersion);
@@ -693,7 +693,7 @@ Key points:
693693
A pre-install function is a logic function that runs automatically during installation, **before the workspace metadata migration is applied**. It shares the same payload shape as post-install (`InstallPayload`), but it is positioned earlier in the install flow so it can prepare state that the upcoming migration depends on — typical uses include backing up data, validating compatibility with the new schema, or archiving records that are about to be restructured or dropped.
694694

695695
```ts src/logic-functions/pre-install.ts
696-
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk';
696+
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
697697

698698
const handler = async (payload: InstallPayload): Promise<void> => {
699699
console.log('Pre install logic function executed successfully!', payload.previousVersion);
@@ -751,7 +751,7 @@ Pre-install is always **synchronous** (it blocks the install and can abort it).
751751
Example — seed a default `PostCard` record after install:
752752

753753
```ts src/logic-functions/post-install.ts
754-
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk';
754+
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
755755
import { createClient } from './generated/client';
756756

757757
const handler = async ({ previousVersion }: InstallPayload): Promise<void> => {
@@ -783,7 +783,7 @@ export default definePostInstallLogicFunction({
783783
Example — archive records before a destructive migration:
784784

785785
```ts src/logic-functions/pre-install.ts
786-
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk';
786+
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
787787
import { createClient } from './generated/client';
788788

789789
const handler = async ({ previousVersion, newVersion }: InstallPayload): Promise<void> => {
@@ -855,7 +855,7 @@ Front components can render in two locations within Twenty:
855855
The quickest way to see a front component in action is to register it as a **command**. Adding a `command` field with `isPinned: true` makes it appear as a quick-action button in the top-right corner of the page — no page layout needed:
856856

857857
```tsx src/front-components/hello-world.tsx
858-
import { defineFrontComponent } from 'twenty-sdk';
858+
import { defineFrontComponent } from 'twenty-sdk/define';
859859

860860
const HelloWorld = () => {
861861
return (
@@ -916,7 +916,8 @@ Front components come in two rendering modes controlled by the `isHeadless` opti
916916
**Headless (`isHeadless: true`)** — The component mounts invisibly in the background. It does not open the side panel. Headless components are designed for actions that execute logic and then unmount themselves — for example, running an async task, navigating to a page, or showing a confirmation modal. They pair naturally with the SDK Command components described below.
917917

918918
```tsx src/front-components/sync-tracker.tsx
919-
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
919+
import { defineFrontComponent } from 'twenty-sdk/define';
920+
import { useRecordId, enqueueSnackbar } from 'twenty-sdk/front-component';
920921
import { useEffect } from 'react';
921922

922923
const SyncTracker = () => {
@@ -954,7 +955,7 @@ Import them from `twenty-sdk/command`:
954955
Here is a full example of a headless front component using `Command` to run an action from the command menu:
955956

956957
```tsx src/front-components/run-action.tsx
957-
import { defineFrontComponent } from 'twenty-sdk';
958+
import { defineFrontComponent } from 'twenty-sdk/define';
958959
import { Command } from 'twenty-sdk/command';
959960
import { CoreApiClient } from 'twenty-sdk/clients';
960961

@@ -990,7 +991,7 @@ export default defineFrontComponent({
990991
And an example using `CommandModal` to ask for confirmation before executing:
991992

992993
```tsx src/front-components/delete-draft.tsx
993-
import { defineFrontComponent } from 'twenty-sdk';
994+
import { defineFrontComponent } from 'twenty-sdk/define';
994995
import { CommandModal } from 'twenty-sdk/command';
995996

996997
const DeleteDraft = () => {
@@ -1028,12 +1029,12 @@ export default defineFrontComponent({
10281029
Inside your component, use SDK hooks to access the current user, record, and component instance:
10291030

10301031
```tsx src/front-components/record-info.tsx
1032+
import { defineFrontComponent } from 'twenty-sdk/define';
10311033
import {
1032-
defineFrontComponent,
10331034
useUserId,
10341035
useRecordId,
10351036
useFrontComponentId,
1036-
} from 'twenty-sdk';
1037+
} from 'twenty-sdk/front-component';
10371038

10381039
const RecordInfo = () => {
10391040
const userId = useUserId();
@@ -1082,8 +1083,9 @@ Front components can trigger navigation, modals, and notifications using functio
10821083
Here is an example that uses the host API to show a snackbar and close the side panel after an action completes:
10831084

10841085
```tsx src/front-components/archive-record.tsx
1085-
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
1086-
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
1086+
import { defineFrontComponent } from 'twenty-sdk/define';
1087+
import { useRecordId } from 'twenty-sdk/front-component';
1088+
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component';
10871089
import { CoreApiClient } from 'twenty-sdk/clients';
10881090

10891091
const ArchiveRecord = () => {
@@ -1143,14 +1145,14 @@ Adding a `command` field to `defineFrontComponent` registers the component in th
11431145
The `conditionalAvailabilityExpression` field lets you control when a command is visible based on the current page context. Import typed variables and operators from `twenty-sdk` to build expressions:
11441146

11451147
```tsx
1148+
import { defineFrontComponent } from 'twenty-sdk/define';
11461149
import {
1147-
defineFrontComponent,
11481150
pageType,
11491151
numberOfSelectedRecords,
11501152
objectPermissions,
11511153
everyEquals,
11521154
isDefined,
1153-
} from 'twenty-sdk';
1155+
} from 'twenty-sdk/front-component';
11541156

11551157
export default defineFrontComponent({
11561158
universalIdentifier: '...',
@@ -1210,7 +1212,7 @@ export default defineFrontComponent({
12101212
Front components can access files from the app's `public/` directory using `getPublicAssetUrl`:
12111213

12121214
```tsx
1213-
import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk';
1215+
import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk/define';
12141216

12151217
const Logo = () => <img src={getPublicAssetUrl('logo.png')} alt="Logo" />;
12161218

@@ -1235,7 +1237,7 @@ Front components support multiple styling approaches. You can use:
12351237
- **Any CSS-in-JS library** compatible with React
12361238

12371239
```tsx
1238-
import { defineFrontComponent } from 'twenty-sdk';
1240+
import { defineFrontComponent } from 'twenty-sdk/define';
12391241
import { Button, Tag, Status } from 'twenty-sdk/ui';
12401242

12411243
const StyledWidget = () => {
@@ -1262,7 +1264,7 @@ export default defineFrontComponent({
12621264
Skills define reusable instructions and capabilities that AI agents can use within your workspace. Use `defineSkill()` to define skills with built-in validation:
12631265

12641266
```ts src/skills/example-skill.ts
1265-
import { defineSkill } from 'twenty-sdk';
1267+
import { defineSkill } from 'twenty-sdk/define';
12661268

12671269
export default defineSkill({
12681270
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
@@ -1291,7 +1293,7 @@ Key points:
12911293
Agents are AI assistants that live inside your workspace. Use `defineAgent()` to create agents with a custom system prompt:
12921294

12931295
```ts src/agents/example-agent.ts
1294-
import { defineAgent } from 'twenty-sdk';
1296+
import { defineAgent } from 'twenty-sdk/define';
12951297

12961298
export default defineAgent({
12971299
universalIdentifier: 'b3c4d5e6-f7a8-9012-bcde-f34567890123',
@@ -1317,7 +1319,7 @@ Key points:
13171319
Views are saved configurations for how records of an object are displayed — including which fields are visible, their order, and any filters or groups applied. Use `defineView()` to ship pre-configured views with your app:
13181320

13191321
```ts src/views/example-view.ts
1320-
import { defineView, ViewKey } from 'twenty-sdk';
1322+
import { defineView, ViewKey } from 'twenty-sdk/define';
13211323
import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from '../objects/example-object';
13221324
import { NAME_FIELD_UNIVERSAL_IDENTIFIER } from '../objects/example-object';
13231325

@@ -1353,7 +1355,7 @@ Key points:
13531355
Navigation menu items add custom entries to the workspace sidebar. Use `defineNavigationMenuItem()` to link to views, external URLs, or objects:
13541356

13551357
```ts src/navigation-menu-items/example-navigation-menu-item.ts
1356-
import { defineNavigationMenuItem, NavigationMenuItemType } from 'twenty-sdk';
1358+
import { defineNavigationMenuItem, NavigationMenuItemType } from 'twenty-sdk/define';
13571359
import { EXAMPLE_VIEW_UNIVERSAL_IDENTIFIER } from '../views/example-view';
13581360

13591361
export default defineNavigationMenuItem({
@@ -1379,7 +1381,7 @@ Key points:
13791381
Page layouts let you customize how a record detail page looks — which tabs appear, what widgets are inside each tab, and how they are arranged. Use `definePageLayout()` to ship custom layouts with your app:
13801382

13811383
```ts src/page-layouts/example-record-page-layout.ts
1382-
import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk';
1384+
import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk/define';
13831385
import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from '../objects/example-object';
13841386
import { HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from '../front-components/hello-world';
13851387

@@ -1442,7 +1444,7 @@ Use the `getPublicAssetUrl` helper from `twenty-sdk` to get the full URL of a fi
14421444
**In a logic function:**
14431445

14441446
```ts src/logic-functions/send-invoice.ts
1445-
import { defineLogicFunction, getPublicAssetUrl } from 'twenty-sdk';
1447+
import { defineLogicFunction, getPublicAssetUrl } from 'twenty-sdk/define';
14461448

14471449
const handler = async (): Promise<any> => {
14481450
const logoUrl = getPublicAssetUrl('logo.png');
@@ -1467,7 +1469,7 @@ export default defineLogicFunction({
14671469
**In a front component:**
14681470

14691471
```tsx src/front-components/company-card.tsx
1470-
import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk';
1472+
import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk/define';
14711473

14721474
export default defineFrontComponent(() => {
14731475
const logoUrl = getPublicAssetUrl('logo.png');
@@ -1491,7 +1493,7 @@ yarn add axios
14911493
Then import it in your code:
14921494

14931495
```ts src/logic-functions/fetch-data.ts
1494-
import { defineLogicFunction } from 'twenty-sdk';
1496+
import { defineLogicFunction } from 'twenty-sdk/define';
14951497
import axios from 'axios';
14961498

14971499
const handler = async (): Promise<any> => {
@@ -1512,7 +1514,7 @@ export default defineLogicFunction({
15121514
The same works for front components:
15131515

15141516
```tsx src/front-components/chart.tsx
1515-
import { defineFrontComponent } from 'twenty-sdk';
1517+
import { defineFrontComponent } from 'twenty-sdk/define';
15161518
import { format } from 'date-fns';
15171519

15181520
const DateWidget = () => {

0 commit comments

Comments
 (0)