i18n - docs translations (#23555)

Created by Github action

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23555?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
github-actions[bot]
2026-07-30 11:35:44 +02:00
committed by GitHub
parent 40dd01c47d
commit 9a1a057d8f
30 changed files with 766 additions and 16 deletions
@@ -6,6 +6,10 @@ icon: window-maximize
المكوّنات الأمامية هي مكوّنات React تُعرَض مباشرة داخل واجهة مستخدم Twenty. تعمل ضمن **Web Worker معزول** باستخدام Remote DOM — تُنفَّذ شيفرتك داخل iframe معزول ذو منشأ غير شفاف، ومع ذلك لا تزال واجهتها تُعرَض محليًا داخل الصفحة بدلًا من أن تظل محصورة داخل ذلك الـ iframe.
<Warning>
Front components are still under active development. Your code runs against a partial DOM, not a real browser page, so advanced usages can fail, often silently. See [Current limitations](#current-limitations).
</Warning>
## أين يمكن استخدام مكوّنات الواجهة الأمامية
يمكن عرض مكوّنات الواجهة الأمامية في ثلاثة مواقع داخل Twenty:
@@ -69,10 +73,10 @@ export default defineCommandMenuItem({
| الحقل | مطلوب | الوصف |
| --------------------- | ----- | ------------------------------------------------------------- |
| `universalIdentifier` | نعم | معرّف فريد ثابت لهذا المكوّن |
| `universalIdentifier` | Yes | معرّف فريد ثابت لهذا المكوّن |
| `component` | نعم | دالة مكوّن React |
| `name` | لا | الاسم المعروض |
| `description` | لا | وصف لما يفعله المكوّن |
| `name` | No | الاسم المعروض |
| `description` | No | وصف لما يفعله المكوّن |
| `isHeadless` | لا | عيّنه على `true` إذا كان المكوّن بلا واجهة مرئية (انظر أدناه) |
## وضع مكوّن أمامي على صفحة
@@ -696,3 +700,72 @@ const Card = () => {
نظرًا لأن `useTheme()` خطّاف، فإنك تقرأ الرموز داخل جسم المكوّن، لذا تعكس القيم دائمًا النسق المباشر (الحالي). تُصدَّر خريطة الرموز نفسها أيضًا كثابت `themeCssVariables`، لكن يُفضَّل استخدام `useTheme()` في المكوّنات الأمامية — إذ يمكن أن يكون الثابت على مستوى الوحدة الذي يفكّ مرجعية `themeCssVariables` غير معرَّف أثناء استخراج بيان التطبيق (app manifest).
للتفرّع بناءً على النظام النشِط (active scheme) صراحةً، اقرأه باستخدام `useColorScheme()` من `twenty-sdk/front-component`، والذي يعيد `'light'` أو `'dark'`.
## Current limitations
Front components are under active development. Rendering, styling and handling events works well. Anything that reaches *past* rendering (measuring an element, calling a DOM method on a ref, portaling outside your tree, touching browser storage) is missing or incomplete today, and most of it fails silently: no exception, and no TypeScript error either, since the scaffold is typed against the full browser DOM.
If one of these blocks you, [open an issue](https://github.com/twentyhq/twenty/issues/new/choose) so it gets prioritized.
### Layout and measurement
Nothing can measure itself yet.
| API | What happens |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Throws |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Silently `undefined`, so `width ?? 0` yields `0` and `width > 600` is always false |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (`typeof` guards do work) |
| `window.matchMedia()`, `window.getComputedStyle()` | Throws |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Silently `undefined` |
| `new MutationObserver(fn)` | Constructs, then `.observe()` throws |
So recharts `ResponsiveContainer`, Floating UI / Popper, list virtualization and drag-to-resize do not work yet. Do layout in CSS instead: your stylesheet reaches the real page, so flexbox, grid, `aspect-ratio`, `clamp()` and `@container` all behave normally.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` and `queueMicrotask` work without the `window.` prefix. Only `window.requestAnimationFrame(...)` and friends throw.
</Note>
### DOM access
A `ref` gives you a sandbox element, not an `HTMLElement`.
| What you write | What happens | Use instead |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Throws | Controlled components; read values from `event.target` |
| `element.classList.add(...)` | Throws (`classList` is `undefined`) | Build the `className` string yourself |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Throws | `querySelector()` / `querySelectorAll()`, which work |
| `document.activeElement` | Always `undefined` | Track focus with `onFocus` / `onBlur` |
| `\<canvas>` | Renders nothing, no error | SVG, or draw offscreen and show an `<img src={dataUrl}>` |
| `createPortal(node, document.body)` | Renders nothing, while `isConnected` reports success | Overlays inline with `position: absolute`, or pass the library your own container element |
The portal gap is why Radix, Headless UI, MUI and react-select popovers render nothing by default. Most accept a container prop; point it at an element you rendered.
### Events
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/ar/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/ar/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/ar/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ icon: table-columns
| **قائمة الأوامر (Cmd+K)** | إجراء سريع مُثبّت أو أمر مخفي | `defineCommandMenuItem` |
تعمل مكوّنات الواجهة الأمامية داخل Web Worker معزول باستخدام Remote DOM — يتم عرضها بشكل أصيل داخل الصفحة (وليس داخل iframe)، لكنها لا تستطيع الوصول مباشرةً إلى صفحة المضيف أو إلى DOM. يحدث التواصل مع Twenty من خلال واجهة API للمضيف تعتمد تمرير الرسائل.
لا تزال قيد التطوير النشط: يطبّق الـ sandbox شجرة DOM جزئية، لذلك قد تفشل حالات الاستخدام المتقدمة. راجع [القيود الحالية](/l/ar/developers/extend/apps/layout/front-components#current-limitations).
@@ -60,7 +60,7 @@ export default defineFrontComponent({
**الدوال المنطقية** تعمل في بيئة Node.js. الوحدات المدمجة في Node (`fs` و`path` و`crypto` و`http` وغيرها) متاحة ولا تحتاج إلى تثبيت.
**المكوّنات الأمامية** تعمل ضمن Web Worker. وحدات Node المدمجة غير متاحة — المتاح فقط واجهات برمجة المتصفّح وحِزَم npm التي تعمل في بيئة المتصفّح.
**المكوّنات الأمامية** تعمل ضمن Web Worker. وحدات Node المدمجة **غير** متاحة — المتوفّر فقط حِزَم npm التي تعمل في بيئة المتصفّح. لاحظ أن الـ sandbox يطبّق نموذج DOM *جزئيًا*، لذلك قد تتمكّن الحزمة من البناء بنجاح ولكنها قد تفشل أثناء وقت التشغيل؛ راجع [القيود الحالية](/l/ar/developers/extend/apps/layout/front-components#current-limitations).
كلتا البيئتين تحتويان على `twenty-client-sdk/core` و`twenty-client-sdk/metadata` كوحدات متاحة مُسبقًا — لا تُضمَّن هذه ضمن الحزم بل تُحلّ وقت التشغيل بواسطة الخادم.
@@ -6,6 +6,10 @@ icon: window-maximize
Frontendové komponenty jsou React komponenty, které se vykreslují přímo v uživatelském rozhraní Twenty. Běží v **izolovaném Web Workeru** s využitím Remote DOM — váš kód se spouští uvnitř sandboxovaného iframe s nejasným původem (opaque-origin), ale jeho UI se stále vykresluje nativně na stránce, místo aby bylo omezené na tento iframe.
<Warning>
Komponenty Front jsou stále aktivně vyvíjeny. Váš kód běží nad částečným DOMem, nikoli nad skutečnou stránkou prohlížeče, takže pokročilé způsoby použití mohou selhávat, často bez zjevných chyb. Viz [Současná omezení](#current-limitations).
</Warning>
## Kde lze použít frontendové komponenty
Frontendové komponenty se mohou vykreslovat na třech místech v rámci Twenty:
@@ -696,3 +700,72 @@ const Card = () => {
Protože `useTheme()` je hook, čtete tokeny uvnitř těla komponenty, takže hodnoty vždy odrážejí aktuální motiv. Stejná mapa tokenů je také exportována jako konstanta `themeCssVariables`, ale ve frontendových komponentách preferujte `useTheme()` — modulová konstanta, která dereferencuje `themeCssVariables`, může být během extrakce manifestu aplikace nedefinovaná.
Chcete-li se explicitně větvit podle aktivního schématu, načtěte jej pomocí `useColorScheme()` z `twenty-sdk/front-component`, která vrací `'light'` nebo `'dark'`.
## Aktuální omezení
Front components are under active development. Rendering, styling and handling events works well. Anything that reaches *past* rendering (measuring an element, calling a DOM method on a ref, portaling outside your tree, touching browser storage) is missing or incomplete today, and most of it fails silently: no exception, and no TypeScript error either, since the scaffold is typed against the full browser DOM.
If one of these blocks you, [open an issue](https://github.com/twentyhq/twenty/issues/new/choose) so it gets prioritized.
### Layout and measurement
Nothing can measure itself yet.
| API | What happens |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Throws |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Silently `undefined`, so `width ?? 0` yields `0` and `width > 600` is always false |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (`typeof` guards do work) |
| `window.matchMedia()`, `window.getComputedStyle()` | Throws |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Silently `undefined` |
| `new MutationObserver(fn)` | Constructs, then `.observe()` throws |
So recharts `ResponsiveContainer`, Floating UI / Popper, list virtualization and drag-to-resize do not work yet. Do layout in CSS instead: your stylesheet reaches the real page, so flexbox, grid, `aspect-ratio`, `clamp()` and `@container` all behave normally.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` and `queueMicrotask` work without the `window.` prefix. Only `window.requestAnimationFrame(...)` and friends throw.
</Note>
### DOM access
A `ref` gives you a sandbox element, not an `HTMLElement`.
| What you write | What happens | Use instead |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Throws | Controlled components; read values from `event.target` |
| `element.classList.add(...)` | Throws (`classList` is `undefined`) | Build the `className` string yourself |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Throws | `querySelector()` / `querySelectorAll()`, which work |
| `document.activeElement` | Always `undefined` | Track focus with `onFocus` / `onBlur` |
| `\<canvas>` | Renders nothing, no error | SVG, or draw offscreen and show an `<img src={dataUrl}>` |
| `createPortal(node, document.body)` | Renders nothing, while `isConnected` reports success | Overlays inline with `position: absolute`, or pass the library your own container element |
The portal gap is why Radix, Headless UI, MUI and react-select popovers render nothing by default. Most accept a container prop; point it at an element you rendered.
### Události
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/cs/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/cs/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/cs/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ icon: table-columns
| **Příkazová nabídka (Cmd+K)** | Připnutá rychlá akce nebo skrytý příkaz | `defineCommandMenuItem` |
Frontendové komponenty běží uvnitř izolovaného Web Workeru pomocí Remote DOM — vykreslují se na stránce nativně (ne uvnitř iframe), ale nemají přímý přístup k hostitelské stránce ani DOM. Komunikace s Twenty probíhá prostřednictvím hostitelského API pro předávání zpráv.
Stále jsou ve vývoji: sandbox implementuje částečné DOM, takže pokročilá použití mohou selhat. Viz [Aktuální omezení](/l/cs/developers/extend/apps/layout/front-components#current-limitations).
@@ -60,7 +60,7 @@ Krok sestavení používá esbuild k vytvoření jediného samostatného souboru
**Logické funkce** běží v prostředí Node.js. Vestavěné moduly Node (`fs`, `path`, `crypto`, `http` atd.) jsou k dispozici a není je třeba instalovat.
**Frontendové komponenty** běží ve Web Workeru. Vestavěné moduly Node nejsou k dispozici — pouze prohlížečová API a balíčky npm, které fungují v prohlížečovém prostředí.
**Frontendové komponenty** běží ve Web Workeru. Vestavěné moduly Node nejsou k dispozici — pouze balíčky npm, které fungují v prohlížečovém prostředí. Všimněte si, že sandbox implementuje *částečné* DOM, takže balíček se může bez problémů sestavit, ale přesto selhat za běhu; viz [Aktuální omezení](/l/cs/developers/extend/apps/layout/front-components#current-limitations).
V obou prostředích jsou jako předpřipravené moduly k dispozici `twenty-client-sdk/core` a `twenty-client-sdk/metadata` — nejsou součástí bundlu, ale server je za běhu načítá.
@@ -6,6 +6,10 @@ icon: window-maximize
Front-Komponenten sind React-Komponenten, die direkt innerhalb der Twenty-UI gerendert werden. Sie laufen in einem **isolierten Web Worker** unter Verwendung von Remote DOM — Ihr Code wird in einem sandboxed iframe mit opaker Origin ausgeführt, wobei die UI dennoch nativ auf der Seite gerendert wird und nicht auf dieses iframe beschränkt ist.
<Warning>
Front-Komponenten befinden sich noch in aktiver Entwicklung. Ihr Code wird gegen ein teilweises DOM und nicht gegen eine echte Browserseite ausgeführt, sodass fortgeschrittene Anwendungsfälle fehlschlagen können oft ohne sichtbare Fehlermeldung. Siehe [Aktuelle Einschränkungen](#current-limitations).
</Warning>
## Wo Front-Komponenten verwendet werden können
Front-Komponenten können an drei Stellen innerhalb von Twenty gerendert werden:
@@ -696,3 +700,72 @@ const Card = () => {
Da `useTheme()` ein Hook ist, lesen Sie Tokens im Komponenten-Body aus, sodass die Werte immer das aktuelle Theme widerspiegeln. Dieselbe Token-Map wird auch als Konstante `themeCssVariables` exportiert, aber bevorzugen Sie `useTheme()` in Frontend-Komponenten eine modulweite Konstante, die `themeCssVariables` dereferenziert, kann undefiniert sein, während das App-Manifest extrahiert wird.
Um explizit nach dem aktiven Schema zu verzweigen, lesen Sie es mit `useColorScheme()` aus `twenty-sdk/front-component` aus; der Hook gibt 'light' oder 'dark' zurück.
## Aktuelle Einschränkungen
Front components are under active development. Rendering, styling and handling events works well. Anything that reaches *past* rendering (measuring an element, calling a DOM method on a ref, portaling outside your tree, touching browser storage) is missing or incomplete today, and most of it fails silently: no exception, and no TypeScript error either, since the scaffold is typed against the full browser DOM.
If one of these blocks you, [open an issue](https://github.com/twentyhq/twenty/issues/new/choose) so it gets prioritized.
### Layout and measurement
Nothing can measure itself yet.
| API | What happens |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Throws |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Silently `undefined`, so `width ?? 0` yields `0` and `width > 600` is always false |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (`typeof` guards do work) |
| `window.matchMedia()`, `window.getComputedStyle()` | Throws |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Silently `undefined` |
| `new MutationObserver(fn)` | Constructs, then `.observe()` throws |
So recharts `ResponsiveContainer`, Floating UI / Popper, list virtualization and drag-to-resize do not work yet. Do layout in CSS instead: your stylesheet reaches the real page, so flexbox, grid, `aspect-ratio`, `clamp()` and `@container` all behave normally.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` and `queueMicrotask` work without the `window.` prefix. Only `window.requestAnimationFrame(...)` and friends throw.
</Note>
### DOM access
A `ref` gives you a sandbox element, not an `HTMLElement`.
| What you write | What happens | Use instead |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Throws | Controlled components; read values from `event.target` |
| `element.classList.add(...)` | Throws (`classList` is `undefined`) | Build the `className` string yourself |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Throws | `querySelector()` / `querySelectorAll()`, which work |
| `document.activeElement` | Always `undefined` | Track focus with `onFocus` / `onBlur` |
| `\<canvas>` | Renders nothing, no error | SVG, or draw offscreen and show an `<img src={dataUrl}>` |
| `createPortal(node, document.body)` | Renders nothing, while `isConnected` reports success | Overlays inline with `position: absolute`, or pass the library your own container element |
The portal gap is why Radix, Headless UI, MUI and react-select popovers render nothing by default. Most accept a container prop; point it at an element you rendered.
### Ereignisse
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/de/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/de/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/de/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ Die **Layout-Ebene** einer Twenty-App umfasst alles, was der Benutzer sieht: wo
| **Befehlsmenü (Cmd+K)** | Eine angeheftete Schnellaktion oder ein versteckter Befehl | `defineCommandMenuItem` |
Frontend-Komponenten laufen in einem isolierten Web Worker unter Verwendung von Remote DOM sie werden nativ auf der Seite gerendert (nicht in einem iframe), können aber die Hostseite oder das DOM nicht direkt erreichen. Die Kommunikation mit Twenty erfolgt über eine Message-Passing-Host-API.
Sie befinden sich noch in aktiver Entwicklung: Die Sandbox implementiert ein partielles DOM, daher können fortgeschrittene Anwendungsfälle fehlschlagen. Siehe [Aktuelle Einschränkungen](/l/de/developers/extend/apps/layout/front-components#current-limitations).
@@ -60,7 +60,7 @@ Der Build-Schritt verwendet esbuild, um pro Logikfunktion und pro Frontend-Kompo
**Logikfunktionen** laufen in einer Node.js-Umgebung. Eingebaute Node.js-Module (`fs`, `path`, `crypto`, `http` usw.) stehen zur Verfügung und müssen nicht installiert werden.
**Frontend-Komponenten** laufen in einem Web Worker. Eingebaute Node.js-Module sind **nicht** verfügbar — nur Browser-APIs und npm-Pakete, die in einer Browserumgebung funktionieren.
**Frontend-Komponenten** laufen in einem Web Worker. Eingebaute Node.js-Module sind **nicht** verfügbar — nur npm-Pakete, die in einer Browserumgebung funktionieren. Beachte, dass die Sandbox nur ein *teilweises* DOM implementiert, sodass ein Paket sauber gebaut werden kann und trotzdem zur Laufzeit fehlschlägt; siehe [Aktuelle Einschränkungen](/l/de/developers/extend/apps/layout/front-components#current-limitations).
In beiden Umgebungen stehen `twenty-client-sdk/core` und `twenty-client-sdk/metadata` als vorab bereitgestellte Module zur Verfügung — sie werden nicht gebündelt, sondern zur Laufzeit vom Server aufgelöst.
@@ -6,6 +6,10 @@ icon: window-maximize
Los componentes de frontend son componentes de React que se renderizan directamente dentro de la UI de Twenty. Se ejecutan en un **Web Worker aislado** usando Remote DOM: tu código se ejecuta dentro de un iframe de origen opaco y aislado (sandboxed), pero su interfaz de usuario sigue renderizándose de forma nativa en la página en lugar de quedar confinada a ese iframe.
<Warning>
Los componentes de Front todavía están en desarrollo activo. Tu código se ejecuta contra un DOM parcial, no una página real del navegador, por lo que los usos avanzados pueden fallar, a menudo de forma silenciosa. Consulta [Limitaciones actuales](#current-limitations).
</Warning>
## Dónde se pueden usar los componentes de front
Los componentes de front pueden renderizarse en tres ubicaciones dentro de Twenty:
@@ -696,3 +700,72 @@ const Card = () => {
Como `useTheme()` es un hook, lees los tokens dentro del cuerpo del componente, por lo que los valores siempre reflejan el tema activo. El mismo mapa de tokens también se exporta como la constante `themeCssVariables`, pero es preferible usar `useTheme()` en los componentes de frontend: una constante a nivel de módulo que desreferencie `themeCssVariables` puede ser indefinida mientras se extrae el manifiesto de la aplicación.
Para hacer bifurcaciones explícitamente según el esquema activo, léelo con `useColorScheme()` de `twenty-sdk/front-component`, que devuelve `'light'` o `'dark'`.
## Limitaciones actuales
Front components are under active development. Rendering, styling and handling events works well. Anything that reaches *past* rendering (measuring an element, calling a DOM method on a ref, portaling outside your tree, touching browser storage) is missing or incomplete today, and most of it fails silently: no exception, and no TypeScript error either, since the scaffold is typed against the full browser DOM.
If one of these blocks you, [open an issue](https://github.com/twentyhq/twenty/issues/new/choose) so it gets prioritized.
### Layout and measurement
Nothing can measure itself yet.
| API | What happens |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Throws |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Silently `undefined`, so `width ?? 0` yields `0` and `width > 600` is always false |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (`typeof` guards do work) |
| `window.matchMedia()`, `window.getComputedStyle()` | Throws |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Silently `undefined` |
| `new MutationObserver(fn)` | Constructs, then `.observe()` throws |
So recharts `ResponsiveContainer`, Floating UI / Popper, list virtualization and drag-to-resize do not work yet. Do layout in CSS instead: your stylesheet reaches the real page, so flexbox, grid, `aspect-ratio`, `clamp()` and `@container` all behave normally.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` and `queueMicrotask` work without the `window.` prefix. Only `window.requestAnimationFrame(...)` and friends throw.
</Note>
### DOM access
A `ref` gives you a sandbox element, not an `HTMLElement`.
| What you write | What happens | Use instead |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Throws | Controlled components; read values from `event.target` |
| `element.classList.add(...)` | Throws (`classList` is `undefined`) | Build the `className` string yourself |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Throws | `querySelector()` / `querySelectorAll()`, which work |
| `document.activeElement` | Always `undefined` | Track focus with `onFocus` / `onBlur` |
| `\<canvas>` | Renders nothing, no error | SVG, or draw offscreen and show an `<img src={dataUrl}>` |
| `createPortal(node, document.body)` | Renders nothing, while `isConnected` reports success | Overlays inline with `position: absolute`, or pass the library your own container element |
The portal gap is why Radix, Headless UI, MUI and react-select popovers render nothing by default. Most accept a container prop; point it at an element you rendered.
### Eventos
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/es/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/es/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/es/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ La **capa de diseño** de una aplicación de Twenty es todo lo que el usuario ve
| **Menú de comandos (Cmd+K)** | Una acción rápida fijada o un comando oculto | `defineCommandMenuItem` |
Los componentes de frontend se ejecutan dentro de un Web Worker aislado usando Remote DOM — se renderizan de forma nativa en la página (no dentro de un iframe), pero no pueden acceder directamente a la página o al DOM del host. La comunicación con Twenty ocurre a través de una API de host de paso de mensajes.
Todavía están en desarrollo activo: el sandbox implementa un DOM parcial, por lo que los usos avanzados pueden fallar. Consulta [Limitaciones actuales](/l/es/developers/extend/apps/layout/front-components#current-limitations).
@@ -60,7 +60,7 @@ El paso de compilación usa esbuild para producir un solo archivo autónomo por
**Las funciones de lógica** se ejecutan en un entorno Node.js. Los módulos integrados de Node (`fs`, `path`, `crypto`, `http`, etc.) están disponibles y no necesitan instalarse.
**Los componentes de frontend** se ejecutan en un Web Worker. Los módulos integrados de Node **no** están disponibles — solo las APIs del navegador y paquetes de npm que funcionen en un entorno de navegador.
**Los componentes de frontend** se ejecutan en un Web Worker. Los módulos integrados de Node **no** están disponibles — solo paquetes de npm que funcionen en un entorno de navegador. Ten en cuenta que la sandbox implementa un DOM *parcial*, por lo que un paquete puede compilarse correctamente y aun así fallar en tiempo de ejecución; consulta [Limitaciones actuales](/l/es/developers/extend/apps/layout/front-components#current-limitations).
Ambos entornos tienen `twenty-client-sdk/core` y `twenty-client-sdk/metadata` disponibles como módulos preproporcionados — estos no se incluyen en el bundle sino que se resuelven en tiempo de ejecución por el servidor.
@@ -6,6 +6,10 @@ icon: window-maximize
Les composants frontaux sont des composants React qui s'affichent directement dans l'interface utilisateur de Twenty. Ils s'exécutent dans un **Web Worker isolé** en utilisant Remote DOM — votre code s'exécute dans un iframe à origine opaque et sandboxé, mais son interface utilisateur continue de s'afficher nativement dans la page plutôt que d'être confinée à cet iframe.
<Warning>
Front components are still under active development. Your code runs against a partial DOM, not a real browser page, so advanced usages can fail, often silently. See [Current limitations](#current-limitations).
</Warning>
## Où les composants frontaux peuvent être utilisés
Les composants frontaux peuvent s'afficher à trois emplacements au sein de Twenty :
@@ -69,10 +73,10 @@ Cliquez dessus pour afficher le composant en ligne.
| Champ | Obligatoire | Description |
| --------------------- | ----------- | -------------------------------------------------------------------------------- |
| `universalIdentifier` | Oui | ID unique et stable pour ce composant |
| `universalIdentifier` | Yes | ID unique et stable pour ce composant |
| `component` | Oui | Une fonction de composant React |
| `name` | Non | Nom d'affichage |
| `description` | Non | Description de ce que fait le composant |
| `name` | No | Nom d'affichage |
| `description` | No | Description de ce que fait le composant |
| `isHeadless` | Non | Définir sur `true` si le composant n'a pas d'interface visible (voir ci-dessous) |
## Placer un composant frontal sur une page
@@ -696,3 +700,72 @@ const Card = () => {
Comme `useTheme()` est un hook, vous lisez les jetons à lintérieur du corps du composant, de sorte que les valeurs reflètent toujours le thème en cours. La même table de jetons est également exportée en tant que constante `themeCssVariables`, mais privilégiez `useTheme()` dans les composants front — une constante au niveau du module qui déréférence `themeCssVariables` peut être indéfinie pendant lextraction du manifeste de lapplication.
Pour bifurquer explicitement selon le jeu de couleurs actif, lisez-le avec `useColorScheme()` depuis `twenty-sdk/front-component`, qui renvoie `'light'` ou `'dark'`.
## Current limitations
Front components are under active development. Rendering, styling and handling events works well. Anything that reaches *past* rendering (measuring an element, calling a DOM method on a ref, portaling outside your tree, touching browser storage) is missing or incomplete today, and most of it fails silently: no exception, and no TypeScript error either, since the scaffold is typed against the full browser DOM.
If one of these blocks you, [open an issue](https://github.com/twentyhq/twenty/issues/new/choose) so it gets prioritized.
### Layout and measurement
Nothing can measure itself yet.
| API | What happens |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Throws |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Silently `undefined`, so `width ?? 0` yields `0` and `width > 600` is always false |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (`typeof` guards do work) |
| `window.matchMedia()`, `window.getComputedStyle()` | Throws |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Silently `undefined` |
| `new MutationObserver(fn)` | Constructs, then `.observe()` throws |
So recharts `ResponsiveContainer`, Floating UI / Popper, list virtualization and drag-to-resize do not work yet. Do layout in CSS instead: your stylesheet reaches the real page, so flexbox, grid, `aspect-ratio`, `clamp()` and `@container` all behave normally.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` and `queueMicrotask` work without the `window.` prefix. Only `window.requestAnimationFrame(...)` and friends throw.
</Note>
### DOM access
A `ref` gives you a sandbox element, not an `HTMLElement`.
| What you write | What happens | Use instead |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Throws | Controlled components; read values from `event.target` |
| `element.classList.add(...)` | Throws (`classList` is `undefined`) | Build the `className` string yourself |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Throws | `querySelector()` / `querySelectorAll()`, which work |
| `document.activeElement` | Always `undefined` | Track focus with `onFocus` / `onBlur` |
| `\<canvas>` | Renders nothing, no error | SVG, or draw offscreen and show an `<img src={dataUrl}>` |
| `createPortal(node, document.body)` | Renders nothing, while `isConnected` reports success | Overlays inline with `position: absolute`, or pass the library your own container element |
The portal gap is why Radix, Headless UI, MUI and react-select popovers render nothing by default. Most accept a container prop; point it at an element you rendered.
### Events
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/fr/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/fr/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/fr/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ La **couche de mise en page** dune application Twenty est tout ce que luti
| **Menu de commande (Cmd+K)** | Une action rapide épinglée ou une commande masquée | `defineCommandMenuItem` |
Les composants frontaux sexécutent à lintérieur dun Web Worker isolé en utilisant Remote DOM — ils sont rendus *nativement* dans la page (et non dans une iframe), mais ne peuvent pas accéder directement à la page hôte ou au DOM. La communication avec Twenty se fait via une API hôte de passage de messages.
Elles sont encore en cours de développement actif : le bac à sable implémente un DOM partiel, donc les usages avancés peuvent échouer. Voir [limitations actuelles](/l/fr/developers/extend/apps/layout/front-components#current-limitations).
@@ -60,7 +60,7 @@ L'étape de build utilise esbuild pour produire un seul fichier autonome par fon
**Les fonctions logiques** s'exécutent dans un environnement Node.js. Les modules intégrés de Node (`fs`, `path`, `crypto`, `http`, etc.) sont disponibles et n'ont pas besoin d'être installés.
**Les composants frontaux** s'exécutent dans un Web Worker. Les modules intégrés de Node ne sont **pas** disponibles — seules les API du navigateur et les packages npm qui fonctionnent dans un environnement navigateur sont pris en charge.
**Les composants frontaux** s'exécutent dans un Web Worker. Les modules intégrés de Node ne sont **pas** disponibles — seuls les packages npm qui fonctionnent dans un environnement navigateur sont pris en charge. Notez que le bac à sable implémente un DOM *partiel*, de sorte quun package peut être compilé sans erreur tout en échouant à lexécution ; voir [Limitations actuelles](/l/fr/developers/extend/apps/layout/front-components#current-limitations).
Les deux environnements disposent de `twenty-client-sdk/core` et `twenty-client-sdk/metadata` en tant que modules pré-fournis — ils ne sont pas intégrés au bundle mais résolus à l'exécution par le serveur.
@@ -6,6 +6,10 @@ icon: window-maximize
I componenti front-end sono componenti React che vengono renderizzati direttamente all'interno della UI di Twenty. Vengono eseguiti in un **Web Worker isolato** utilizzando Remote DOM — il tuo codice viene eseguito all'interno di un iframe con origine opaca e in sandbox, ma la sua interfaccia utente continua a essere renderizzata in modo nativo nella pagina invece di essere confinata in quell'iframe.
<Warning>
I componenti Front sono ancora in fase di sviluppo attivo. Il tuo codice viene eseguito su un DOM parziale, non su una vera pagina del browser, quindi gli utilizzi avanzati possono fallire, spesso in modo silenzioso. Vedi [Limitazioni attuali](#current-limitations).
</Warning>
## Dove possono essere utilizzati i componenti front-end
I componenti front-end possono essere renderizzati in tre posizioni all'interno di Twenty:
@@ -696,3 +700,72 @@ const Card = () => {
Poiché `useTheme()` è un hook, leggi i token allinterno del corpo del componente, così i valori riflettono sempre il tema attivo in tempo reale. La stessa mappa di token è anche esportata come costante `themeCssVariables`, ma nei componenti front-end è preferibile usare `useTheme()`: una costante a livello di modulo che dereferenzia `themeCssVariables` può essere undefined mentre il manifest dellapp viene estratto.
Per diramare esplicitamente in base allo schema attivo, leggilo con `useColorScheme()` da `twenty-sdk/front-component`, che restituisce `'light'` o `'dark'`.
## Limitazioni attuali
Front components are under active development. Rendering, styling and handling events works well. Anything that reaches *past* rendering (measuring an element, calling a DOM method on a ref, portaling outside your tree, touching browser storage) is missing or incomplete today, and most of it fails silently: no exception, and no TypeScript error either, since the scaffold is typed against the full browser DOM.
If one of these blocks you, [open an issue](https://github.com/twentyhq/twenty/issues/new/choose) so it gets prioritized.
### Layout and measurement
Nothing can measure itself yet.
| API | What happens |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Throws |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Silently `undefined`, so `width ?? 0` yields `0` and `width > 600` is always false |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (`typeof` guards do work) |
| `window.matchMedia()`, `window.getComputedStyle()` | Throws |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Silently `undefined` |
| `new MutationObserver(fn)` | Constructs, then `.observe()` throws |
So recharts `ResponsiveContainer`, Floating UI / Popper, list virtualization and drag-to-resize do not work yet. Do layout in CSS instead: your stylesheet reaches the real page, so flexbox, grid, `aspect-ratio`, `clamp()` and `@container` all behave normally.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` and `queueMicrotask` work without the `window.` prefix. Only `window.requestAnimationFrame(...)` and friends throw.
</Note>
### DOM access
A `ref` gives you a sandbox element, not an `HTMLElement`.
| What you write | What happens | Use instead |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Throws | Controlled components; read values from `event.target` |
| `element.classList.add(...)` | Throws (`classList` is `undefined`) | Build the `className` string yourself |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Throws | `querySelector()` / `querySelectorAll()`, which work |
| `document.activeElement` | Always `undefined` | Track focus with `onFocus` / `onBlur` |
| `\<canvas>` | Renders nothing, no error | SVG, or draw offscreen and show an `<img src={dataUrl}>` |
| `createPortal(node, document.body)` | Renders nothing, while `isConnected` reports success | Overlays inline with `position: absolute`, or pass the library your own container element |
The portal gap is why Radix, Headless UI, MUI and react-select popovers render nothing by default. Most accept a container prop; point it at an element you rendered.
### Eventi
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/it/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/it/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/it/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ Il **livello di layout** di un'app Twenty è tutto ciò che l'utente vede: dove
| **Menu comandi (Cmd+K)** | Un'azione rapida fissata o un comando nascosto | `defineCommandMenuItem` |
I componenti front-end vengono eseguiti all'interno di un Web Worker isolato usando Remote DOM: vengono renderizzati in modo nativo nella pagina (non all'interno di un iframe), ma non possono accedere direttamente alla pagina host o al DOM. La comunicazione con Twenty avviene tramite un'API host basata sul passaggio di messaggi.
Sono ancora in fase di sviluppo attivo: il sandbox implementa un DOM parziale, quindi gli utilizzi avanzati possono non funzionare. Vedi [Limitazioni attuali](/l/it/developers/extend/apps/layout/front-components#current-limitations).
@@ -60,7 +60,7 @@ La fase di build usa esbuild per produrre un singolo file autonomo per ogni funz
**Le funzioni logiche** vengono eseguite in un ambiente Node.js. I moduli integrati di Node (`fs`, `path`, `crypto`, `http`, ecc.) sono disponibili e non necessitano di essere installati.
**I componenti front-end** vengono eseguiti in un Web Worker. I moduli integrati di Node non sono disponibili — solo le API del browser e i pacchetti npm che funzionano in un ambiente browser.
**I componenti front-end** vengono eseguiti in un Web Worker. I moduli integrati di Node **non** sono disponibili — solo i pacchetti npm che funzionano in un ambiente browser. Nota che la sandbox implementa un DOM *parziale*, quindi un pacchetto può compilarsi correttamente e comunque fallire in fase di esecuzione; vedi [Limitazioni attuali](/l/it/developers/extend/apps/layout/front-components#current-limitations).
Entrambi gli ambienti hanno `twenty-client-sdk/core` e `twenty-client-sdk/metadata` disponibili come moduli preforniti — questi non vengono inclusi nel bundle ma vengono risolti a runtime dal server.
@@ -6,6 +6,10 @@ icon: window-maximize
フロントコンポーネントは、Twenty の UI 内で直接レンダリングされる React コンポーネントです。 フロントコンポーネントは Remote DOM を使用する**分離された Web Worker**内で実行されます。コードはサンドボックス化され、不透明なオリジンの iframe 内で動作しますが、その UI はその iframe 内に制限されるのではなく、ページ内でネイティブにレンダリングされます。
<Warning>
Front components は現在も積極的に開発が進められています。 あなたのコードは実際のブラウザページではなく不完全な DOM に対して実行されるため、高度な使い方では、しばしば何の表示もなく失敗することがあります。 [現在の制限](#current-limitations) を参照してください。
</Warning>
## フロントコンポーネントを使用できる場所
フロントコンポーネントは、Twenty 内の3つの場所でレンダリングできます:
@@ -696,3 +700,72 @@ const Card = () => {
`useTheme()` はフックなので、コンポーネント本体の中でトークンを読み取り、値が常に現在のテーマを反映するようにできます。 同じトークンマップは `themeCssVariables` 定数としてもエクスポートされていますが、フロントエンドコンポーネントでは `useTheme()` を優先してください。アプリのマニフェストを抽出している間は、`themeCssVariables` を参照するモジュールレベルの定数が未定義になる可能性があります。
アクティブなスキームを明示的に分岐させるには、`twenty-sdk/front-component` の `useColorScheme()` を使って取得します。このフックは `'light'` または `'dark'` を返します。
## 現在の制限
Front components は現在も積極的に開発が進められています。 レンダリング、スタイリング、イベント処理は問題なく動作します。 レンダリングを*越えた*処理(要素の計測、ref に対する DOM メソッドの呼び出し、ツリーの外へのポータル、ブラウザー ストレージへのアクセス)については、現在は未実装または不完全であり、そのほとんどは例外も出さずに黙って失敗します。スキャフォールドがフルなブラウザー DOM を前提に型付けされているため、TypeScript エラーも発生しません。
これらのいずれかが原因でブロックされている場合は、[issue を作成](https://github.com/twentyhq/twenty/issues/new/choose)して、優先度を上げてもらってください。
### レイアウトと計測
まだ自分自身を計測できるものはありません。
| API | 何が起きるか |
| ------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | 例外を投げます |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | 黙って `undefined` になるため、`width ?? 0` は `0` になり、`width > 600` は常に false になります |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError``typeof` ガードは機能します) |
| `window.matchMedia()`, `window.getComputedStyle()` | 例外を投げます |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | 黙って `undefined` になります |
| `new MutationObserver(fn)` | コンストラクタ呼び出しは成功しますが、その後の `.observe()` が例外を投げます |
そのため、recharts の `ResponsiveContainer`、Floating UI / Popper、リストの仮想化、およびドラッグによるサイズ変更はまだ動作しません。 代わりに CSS でレイアウトしてください。スタイルシートは実際のページに適用されるので、flexbox、grid、`aspect-ratio`、`clamp()`、`@container` はすべて通常どおり動作します。
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout`, `queueMicrotask` は、`window.` プレフィックスなしで動作します。 `window.requestAnimationFrame(...)` などを使った場合だけ例外が投げられます。
</Note>
### DOM アクセス
`ref` が返すのは `HTMLElement` ではなくサンドボックス要素です。
| 記述するコード | 何が起きるか | 代わりに使うもの |
| ----------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | 例外を投げます | 制御されたコンポーネントを使い、値は `event.target` から読み取ります |
| `element.classList.add(...)` | 例外を投げます(`classList` は `undefined` です) | `className` 文字列を自分で組み立ててください |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | 例外を投げます | 動作する `querySelector()` / `querySelectorAll()` を使ってください |
| `document.activeElement` | 常に `undefined` です | `onFocus` / `onBlur` でフォーカスを追跡してください |
| `\<canvas>` | 何もレンダリングされず、エラーも出ません | SVG を使うか、オフスクリーンで描画して `<img src={dataUrl}>` として表示してください |
| `createPortal(node, document.body)` | `isConnected` は成功を報告しますが、何もレンダリングされません | `position: absolute` によるインラインのオーバーレイを使うか、ライブラリに自前のコンテナー要素を渡してください |
このポータルのギャップが原因で、Radix、Headless UI、MUI、react-select のポップオーバーはデフォルトでは何もレンダリングしません。 ほとんどのライブラリは container プロップを受け付けるので、自分がレンダリングした要素を指定してください。
### イベント
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/ja/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/ja/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/ja/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ Twenty アプリの **レイアウトレイヤー** とは、ユーザーに見
| **コマンドメニュー (Cmd+K)** | ピン留めされたクイックアクションまたは非表示コマンド | `defineCommandMenuItem` |
フロントコンポーネントは Remote DOM を使用して、分離された Web Worker 内で実行されます。ページ内に *ネイティブに*(iframe 内ではなく)レンダリングされますが、ホストページや DOM へ直接アクセスすることはできません。 Twenty との通信は、メッセージパッシング型のホスト API を通じて行われます。
これらは依然として積極的に開発中です。サンドボックスは DOM を部分的にのみ実装しているため、高度な利用方法では失敗する場合があります。 [現在の制限事項](/l/ja/developers/extend/apps/layout/front-components#current-limitations)を参照してください。
@@ -60,7 +60,7 @@ export default defineFrontComponent({
**ロジック関数**は Node.js 環境で実行されます。 Node の組み込みモジュール(`fs`、`path`、`crypto`、`http` など) は利用可能で、インストールは不要です。
**フロントコンポーネント**は Web Worker で実行されます。 Node の組み込みモジュールは利用できません—ブラウザー環境で動作するブラウザー API と npm パッケージのみが使用できます。
**フロントコンポーネント**は Web Worker で実行されます。 Node の組み込みモジュールは利用できません—ブラウザー環境で動作する npm パッケージのみが使用できます。 サンドボックスは *一部のみ* の DOM を実装しているため、パッケージはクリーンにビルドできても実行時に失敗する可能性があります。詳しくは [Current limitations](/l/ja/developers/extend/apps/layout/front-components#current-limitations) を参照してください。
どちらの環境でも、`twenty-client-sdk/core` および `twenty-client-sdk/metadata` が事前提供モジュールとして利用可能です—これらはバンドルされず、実行時にサーバーによって解決されます。
@@ -6,6 +6,10 @@ icon: window-maximize
프런트 컴포넌트는 Twenty의 UI 내부에서 직접 렌더링되는 React 컴포넌트입니다. 이들은 Remote DOM을 사용하는 **격리된 Web Worker**에서 실행됩니다 — 코드는 샌드박스 처리된 opaque-origin iframe 내부에서 실행되지만, UI는 해당 iframe 안에 갇히지 않고 페이지 내에서 네이티브로 렌더링됩니다.
<Warning>
Front 컴포넌트는 여전히 활발히 개발 중입니다. 실제 브라우저 페이지가 아닌 부분적인 DOM을 대상으로 코드를 실행하므로 고급 사용 시에는 종종 아무런 표시 없이 실패할 수 있습니다. [현재 제한 사항](#current-limitations)을 참고하세요.
</Warning>
## 프런트 컴포넌트를 사용할 수 있는 위치
프런트 컴포넌트는 Twenty 내에서 세 위치에 렌더링될 수 있습니다:
@@ -696,3 +700,72 @@ const Card = () => {
`useTheme()` 는 훅이므로, 컴포넌트 본문 안에서 토큰을 읽게 되어 값이 항상 실제 활성 테마를 반영합니다. 동일한 토큰 맵은 `themeCssVariables` 상수로도 export 되지만, 프론트 컴포넌트에서는 `useTheme()` 를 우선적으로 사용하세요. `themeCssVariables` 를 역참조하는 모듈 레벨 상수는 앱 매니페스트가 추출되는 동안에는 정의되지 않았을 수 있습니다.
활성 스킴에 따라 분기해야 할 경우, `twenty-sdk/front-component` 의 `useColorScheme()` 으로 값을 읽으세요. 이 훅은 `'light'` 또는 `'dark'` 를 반환합니다.
## 현재 제한 사항
Front 컴포넌트는 활발히 개발 중입니다. 렌더링, 스타일링 및 이벤트 처리는 잘 작동합니다. 렌더링 *이후* 단계에 해당하는 작업(요소 측정, ref에서 DOM 메서드 호출, 트리 외부로의 포털링, 브라우저 스토리지 접근 등)은 현재 누락되어 있거나 불완전하며, 대부분은 조용히 실패합니다. 예외도 발생하지 않고, 스캐폴드가 전체 브라우저 DOM을 기준으로 타입이 지정되어 있기 때문에 TypeScript 오류도 발생하지 않습니다.
이 중 하나가 작업을 막고 있다면, 우선순위를 높일 수 있도록 [issue를 생성](https://github.com/twentyhq/twenty/issues/new/choose)해 주세요.
### 레이아웃과 측정
아직 어떤 요소도 스스로를 측정할 수 없습니다.
| API | 무슨 일이 일어나는지 |
| ------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `getBoundingClientRect()`, `getClientRects()` | 예외 발생(Throws) |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | 조용히 `undefined`가 되어 `width ?? 0`은 `0`을 반환하고, `width > 600`은 항상 false입니다. |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError`가 발생합니다(`typeof` 가드는 동작함). |
| `window.matchMedia()`, `window.getComputedStyle()` | 예외 발생(Throws) |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | 조용히 `undefined`가 됩니다. |
| `new MutationObserver(fn)` | 생성은 되지만 이후 `.observe()`에서 예외가 발생합니다. |
따라서 recharts의 `ResponsiveContainer`, Floating UI / Popper, 리스트 가상화, 드래그로 크기 조절 등은 아직 동작하지 않습니다. 대신 CSS로 레이아웃을 구성하세요. 스타일시트는 실제 페이지에 도달하므로 flexbox, grid, `aspect-ratio`, `clamp()`, `@container`는 모두 정상적으로 동작합니다.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout`, `queueMicrotask`는 `window.` 접두사 없이도 동작합니다. `window.requestAnimationFrame(...)` 등만 예외를 발생시킵니다.
</Note>
### DOM 액세스
`ref`는 `HTMLElement`가 아닌 샌드박스 요소를 제공합니다.
| 작성한 코드 | 무슨 일이 일어나는지 | 대신 사용할 것 |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | 예외 발생(Throws) | 제어 컴포넌트 사용; 값을 `event.target`에서 읽기 |
| `element.classList.add(...)` | 예외 발생(`classList`가 `undefined`임) | `className` 문자열을 직접 구성하세요. |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | 예외 발생(Throws) | 정상 동작하는 `querySelector()` / `querySelectorAll()` 사용 |
| `document.activeElement` | 항상 `undefined`입니다. | `onFocus` / `onBlur`로 포커스를 추적하세요. |
| `\<canvas>` | 아무것도 렌더링되지 않으며, 오류도 없습니다. | SVG를 사용하거나, 오프스크린에서 그린 뒤 `<img src={dataUrl}>`로 표시하세요. |
| `createPortal(node, document.body)` | `isConnected`는 성공을 보고하지만 실제로는 아무것도 렌더링되지 않습니다. | `position: absolute`를 사용해 인라인으로 오버레이를 배치하거나, 라이브러리에 직접 렌더링한 컨테이너 요소를 전달하세요. |
이 포털 간극 때문에 Radix, Headless UI, MUI, react-select의 팝오버는 기본적으로 아무것도 렌더링하지 않습니다. 대부분은 container prop을 받으므로, 여러분이 렌더링한 요소를 가리키도록 설정하면 됩니다.
### 이벤트
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/ko/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/ko/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/ko/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ Twenty 앱의 **레이아웃 레이어**는 사용자가 보는 모든 것을
| **명령 메뉴 (Cmd+K)** | 고정된 빠른 작업 또는 숨겨진 명령 | `defineCommandMenuItem` |
프런트 컴포넌트는 Remote DOM을 사용하는 격리된 Web Worker 내부에서 실행됩니다. 이들은 페이지 안에서 네이티브하게 렌더링되지만(iframe 내부가 아님), 호스트 페이지나 DOM에 직접 접근할 수는 없습니다. Twenty와의 통신은 메시지 전달 호스트 API를 통해 이루어집니다.
여전히 활발히 개발 중입니다. 샌드박스는 DOM을 부분적으로만 구현하고 있어 고급 사용 사례에서는 실패할 수 있습니다. [현재 제한 사항](/l/ko/developers/extend/apps/layout/front-components#current-limitations)을 참고하세요.
@@ -60,7 +60,7 @@ export default defineFrontComponent({
**로직 함수**는 Node.js 환경에서 실행됩니다. Node 기본 모듈(`fs`, `path`, `crypto`, `http` 등) 을(를) 사용할 수 있으며 설치할 필요가 없습니다.
**프런트 컴포넌트**는 Web Worker에서 실행됩니다. Node 기본 모듈은 사용할 수 없습니다 — 브라우저 환경에서 동작하는 브라우저 API와 npm 패키지만 사용할 수 있습니다.
**프런트 컴포넌트**는 Web Worker에서 실행됩니다. Node 기본 모듈은 **사용할 수 없습니다** — 브라우저 환경에서 동작하는 npm 패키지만 사용할 수 있습니다. 샌드박스는 *부분적인* DOM만 구현하므로, 패키지가 빌드에는 성공하더라도 런타임에 실패할 수 있습니다. 자세한 내용은 [현재 제한 사항](/l/ko/developers/extend/apps/layout/front-components#current-limitations)을 참고하세요.
두 환경 모두에서 `twenty-client-sdk/core`와 `twenty-client-sdk/metadata`가 사전 제공 모듈로 사용 가능합니다 — 이는 번들되지 않고 서버가 런타임에 해석합니다.
@@ -6,6 +6,10 @@ icon: window-maximize
Componentele front-end sunt componente React care se afișează direct în interfața Twenty. Acestea rulează într-un **Web Worker** izolat folosind Remote DOM — codul se execută într-un iframe cu origine opacă, într-un mediu izolat (sandboxed), însă interfața sa se redă în continuare nativ în pagină, în loc să fie limitată la acel iframe.
<Warning>
Componentele Front sunt încă în curs de dezvoltare activă. Codul tău se execută pe un DOM parțial, nu pe o pagină reală a browserului, astfel încât utilizările avansate pot eșua, adesea în tăcere. Vezi [Limitări actuale](#current-limitations).
</Warning>
## Unde pot fi utilizate componentele front-end
Componentele front-end pot fi afișate în trei locații în cadrul Twenty:
@@ -696,3 +700,72 @@ const Card = () => {
Deoarece `useTheme()` este un hook, citești tokenii în interiorul corpului componentei, astfel încât valorile reflectă întotdeauna tema activă în timp real. Aceeași hartă de tokeni este exportată și ca o constantă `themeCssVariables`, dar preferă `useTheme()` în componentele frontend — o constantă la nivel de modul care dereferențiază `themeCssVariables` poate fi nedefinită în timp ce manifestul aplicației este extras.
Pentru a ramifica explicit în funcție de schema activă, citește-o cu `useColorScheme()` din `twenty-sdk/front-component`, care returnează `'light'` sau `'dark'`.
## Limitări actuale
Componentele Front sunt în dezvoltare activă. Redarea, stilizarea și gestionarea evenimentelor funcționează bine. Orice ajunge *dincolo de* redare (măsurarea unui element, apelarea unei metode DOM pe un ref, portarea în afara arborelui tău, accesarea stocării browserului) lipsește sau este incompletă astăzi, iar majoritatea eșuează în mod silențios: nu există excepție și nici eroare TypeScript, deoarece scheletul este tastat pentru întregul DOM al browserului.
Dacă una dintre acestea te blochează, [deschide un tichet](https://github.com/twentyhq/twenty/issues/new/choose) pentru a fi prioritizată.
### Layout și măsurare
Nimic nu se poate măsura singur încă.
| API | Ce se întâmplă |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Aruncă o excepție |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Este în mod silențios `undefined`, astfel încât `width ?? 0` produce `0`, iar `width > 600` este întotdeauna fals |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (gardurile `typeof` funcționează) |
| `window.matchMedia()`, `window.getComputedStyle()` | Aruncă o excepție |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Este în mod silențios `undefined` |
| `new MutationObserver(fn)` | Se construiește, apoi `.observe()` aruncă o excepție |
Prin urmare, `ResponsiveContainer` din recharts, Floating UI / Popper, virtualizarea listelor și redimensionarea prin tragere nu funcționează încă. Fă layout-ul în CSS în schimb: foaia ta de stil ajunge la pagina reală, astfel încât flexbox, grid, `aspect-ratio`, `clamp()` și `@container` se comportă toate normal.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` și `queueMicrotask` funcționează fără prefixul `window.`. Numai `window.requestAnimationFrame(...)` și cele similare aruncă o excepție.
</Note>
### Acces DOM
Un `ref` îți oferă un element sandbox, nu un `HTMLElement`.
| Ce scrii | Ce se întâmplă | Folosește în schimb |
| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Aruncă o excepție | Componente controlate; citește valorile din `event.target` |
| `element.classList.add(...)` | Aruncă o excepție (`classList` este `undefined`) | Construiește manual șirul `className` |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Aruncă o excepție | `querySelector()` / `querySelectorAll()`, care funcționează |
| `document.activeElement` | Întotdeauna `undefined` | Urmărește focusul cu `onFocus` / `onBlur` |
| `\<canvas>` | Nu redă nimic, fără eroare | SVG sau desenează în offscreen și afișează un `<img src={dataUrl}>` |
| `createPortal(node, document.body)` | Nu redă nimic, în timp ce `isConnected` raportează succes | Suprapuneri inline cu `position: absolute` sau transmite bibliotecii propriul tău element container |
Golul portalului este motivul pentru care popover-urile Radix, Headless UI, MUI și react-select nu redau nimic în mod implicit. Majoritatea acceptă o proprietate de tip container; indică-i un element pe care l-ai redat.
### Evenimente
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/ro/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/ro/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/ro/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ icon: table-columns
| **Meniul de comenzi (Cmd+K)** | O acțiune rapidă fixată sau o comandă ascunsă | `defineCommandMenuItem` |
Componentele front rulează în interiorul unui Web Worker izolat folosind Remote DOM — acestea sunt redate *nativ* în pagină (nu într-un iframe), dar nu pot accesa direct pagina gazdă sau DOM-ul. Comunicarea cu Twenty se face printr-un API al gazdei bazat pe transmiterea de mesaje.
Sunt încă în curs de dezvoltare activă: sandbox-ul implementează un DOM parțial, astfel încât utilizările avansate pot eșua. Vezi [limitările actuale](/l/ro/developers/extend/apps/layout/front-components#current-limitations).
@@ -60,7 +60,7 @@ Pasul de build folosește esbuild pentru a produce un singur fișier autonom pen
**Funcțiile logice** rulează într-un mediu Node.js. Modulele built-in Node (`fs`, `path`, `crypto`, `http` etc.) sunt disponibile și nu trebuie instalate.
**Componentele frontend** rulează într-un Web Worker. Modulele built-in Node nu sunt disponibile — doar API-urile de browser și pachetele npm care funcționează într-un mediu de browser.
**Componentele frontend** rulează într-un Web Worker. Modulele built-in Node **nu** sunt disponibile — doar pachetele npm care funcționează într-un mediu de browser. Reține că sandbox-ul implementează un DOM *parțial*, astfel încât un pachet se poate construi fără erori, dar totuși poate eșua la execuție; vezi [Limitări curente](/l/ro/developers/extend/apps/layout/front-components#current-limitations).
Ambele medii au `twenty-client-sdk/core` și `twenty-client-sdk/metadata` disponibile ca module pre-furnizate — acestea nu sunt incluse în bundle, ci sunt rezolvate la rulare de către server.
@@ -6,6 +6,10 @@ icon: window-maximize
Ön uç bileşenler, Twenty'nin UI'si içinde doğrudan görüntülenen React bileşenleridir. Remote DOM kullanan **izole bir Web Worker** içinde çalışırlar — kodunuz, korumalı (sandbox) ve opak kökenli bir iframe içinde yürütülür; ancak UI, o iframe ile sınırlanmak yerine sayfada yerel olarak işlenir.
<Warning>
Front bileşenleri hâlâ aktif geliştirme aşamasındadır. Kodunuz gerçek bir tarayıcı sayfası yerine kısmi bir DOM üzerinde çalışır, bu nedenle ileri düzey kullanımlar çoğu zaman sessizce başarısız olabilir. [Mevcut sınırlamalara](#current-limitations) bakın.
</Warning>
## Ön uç bileşenlerinin kullanılabileceği yerler
Ön uç bileşenler, Twenty içinde üç konumda işlenebilir:
@@ -696,3 +700,72 @@ const Card = () => {
`useTheme()` bir kanca olduğundan, belirteçleri bileşen gövdesinin içinde okursunuz; böylece değerler her zaman etkin temayı yansıtır. Aynı belirteç haritası, `themeCssVariables` sabiti olarak da dışa aktarılır; ancak ön uç bileşenlerinde `useTheme()` kullanmayı tercih edin — `themeCssVariables` öğesini dolaylı olarak kullanan modül düzeyinde bir sabit, uygulama manifesti çıkarılırken tanımsız olabilir.
Etkin şemaya açıkça dallanmak için, `twenty-sdk/front-component` içindeki `useColorScheme()` ile okuyun; bu kanca `'light'` veya `'dark'` döndürür.
## Mevcut sınırlamalar
Front bileşenleri aktif olarak geliştirilmektedir. Render etme, stil verme ve olayları işleme iyi çalışıyor. Render etmenin *ötesine* geçen her şey (bir öğeyi ölçmek, bir ref üzerinde bir DOM metodunu çağırmak, ağacınızın dışına portal oluşturmak, tarayıcı depolamasına dokunmak) bugün eksik veya tamamlanmamış durumda ve çoğu sessizce başarısız oluyor: hiçbir exception yok ve TypeScript hatası da yok, çünkü iskelet tam tarayıcı DOMuna göre type edilmiştir.
Bunlardan biri sizi engelliyorsa, önceliklendirilmesi için [open an issue](https://github.com/twentyhq/twenty/issues/new/choose).
### Yerleşim ve ölçüm
Hiçbir şey henüz kendi kendini ölçemiyor.
| API | Ne olur |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `getBoundingClientRect()`, `getClientRects()` | Fırlatır |
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | Sessizce `undefined`, bu yüzden `width ?? 0` sonucu `0` verir ve `width > 600` her zaman false olur |
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` (`typeof` guardları çalışır) |
| `window.matchMedia()`, `window.getComputedStyle()` | Fırlatır |
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | Sessizce `undefined` |
| `new MutationObserver(fn)` | Oluşturur, ardından `.observe()` fırlatır |
Bu yüzden recharts `ResponsiveContainer`, Floating UI / Popper, liste sanallaştırma ve sürükleyerek boyutlandırma henüz çalışmıyor. Bunun yerine yerleşimi CSSte yapın: stil sayfanız gerçek sayfaya ulaştığı için flexbox, grid, `aspect-ratio`, `clamp()` ve `@container` normal şekilde davranır.
<Note>
`requestAnimationFrame`, `fetch`, `setTimeout` ve `queueMicrotask` `window.` öneki olmadan çalışır. Yalnızca `window.requestAnimationFrame(...)` ve benzerleri fırlatır.
</Note>
### DOM erişimi
Bir `ref` size bir `HTMLElement` değil, bir sandbox öğesi verir.
| Ne yazarsınız | Ne olur | Bunun yerine şunu kullanın |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | Fırlatır | Kontrollü bileşenler; değerleri `event.target` üzerinden okuyun |
| `element.classList.add(...)` | Fırlatır (`classList` `undefined`dır) | `className` stringini kendiniz oluşturun |
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | Fırlatır | Çalışan `querySelector()` / `querySelectorAll()` |
| `document.activeElement` | Her zaman `undefined` | Odağı `onFocus` / `onBlur` ile takip edin |
| `\<canvas>` | Hiçbir şey render etmez, hata yoktur | SVG kullanın veya ekranda olmayan bir yerde çizip bir `<img src={dataUrl}>` gösterin |
| `createPortal(node, document.body)` | `isConnected` başarı bildirmesine rağmen hiçbir şey render etmez | Yer paylaşımlarını `position: absolute` ile satır içinde yapın veya kütüphaneye kendi container öğenizi verin |
Portal boşluğu, Radix, Headless UI, MUI ve react-select popoverlarının varsayılan olarak hiçbir şey render etmemesinin nedenidir. Çoğu bir container prop kabul eder; onu render ettiğiniz bir öğeye yönlendirin.
### Etkinlikler
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
### Attributes and styling
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
### Storage and network
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/tr/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/tr/developers/extend/apps/logic/key-value-store).
`fetch` works, with caveats:
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
### Other gaps
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/tr/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
@@ -55,3 +55,5 @@ Bir Twenty uygulamasının **düzen katmanı**, kullanıcının gördüğü her
| **Komut menüsü (Cmd+K)** | Sabitlenmiş bir hızlı eylem veya gizli komut | `defineCommandMenuItem` |
Ön uç bileşenleri, Remote DOM kullanan yalıtılmış bir Web Worker içinde çalışır — sayfada *yerel* olarak oluşturulurlar (bir iframe içinde değil), ancak ana makine sayfasına veya DOM'a doğrudan erişemezler. Twenty ile iletişim, mesaj iletimi yapan bir ana makine API'si aracılığıyla gerçekleşir.
Hâlâ etkin geliştirme aşamasındalar: sandbox kısmi bir DOM uygular, bu nedenle gelişmiş kullanımlar başarısız olabilir. [Geçerli kısıtlamalar](/l/tr/developers/extend/apps/layout/front-components#current-limitations) bölümüne bakın.
@@ -60,7 +60,7 @@ Derleme adımı, her mantık işlevi ve her ön uç bileşeni için tek bir bağ
**Mantık işlevleri**, Node.js ortamında çalışır. Node yerleşik modülleri (`fs`, `path`, `crypto`, `http` vb.) kullanılabilir ve kurulmaları gerekmez.
**Ön uç bileşenleri**, bir Web Worker içinde çalışır. Node'un yerleşik modülleri **kullanılamaz** — yalnızca tarayıcı ortamında çalışan tarayıcı API'leri ve npm paketleri kullanılabilir.
**Ön uç bileşenleri**, bir Web Worker içinde çalışır. Node'un yerleşik modülleri **kullanılamaz** — yalnızca tarayıcı ortamında çalışan npm paketleri kullanılabilir. Korumalı alanın *kısmi* bir DOM uyguladığını unutmayın; bu nedenle bir paket hatasız derlenip çalışma zamanında yine de başarısız olabilir. Bkz. [Geçerli kısıtlamalar](/l/tr/developers/extend/apps/layout/front-components#current-limitations).
Her iki ortamda da `twenty-client-sdk/core` ve `twenty-client-sdk/metadata` önceden sağlanmış modüller olarak mevcuttur — bunlar paketlenmez, ancak çalışma zamanında sunucu tarafından çözülür.