Skip to main content
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.
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.

Wo Front-Komponenten verwendet werden können

Front-Komponenten können an drei Stellen innerhalb von Twenty gerendert werden:
  • Seitenpanel — Nicht-Headless-Front-Komponenten werden im rechten Seitenpanel geöffnet. Dies ist das Standardverhalten, wenn eine Front-Komponente über das Befehlsmenü ausgelöst wird.
  • Widgets (Dashboards und Datensatzseiten) — Front-Komponenten können als Widgets in Seitenlayouts eingebettet werden. Beim Konfigurieren eines Dashboards oder eines Datensatzseiten-Layouts können Benutzer ein Front-Komponenten-Widget hinzufügen.
  • App settings — Definiert mit defineSettingsFrontComponent(), wird die Front-Komponente als Abschnitt im Settings-Tab der App gerendert und ersetzt dabei die standardmäßige Variablenkonfigurationsoberfläche.
Eine Front-Komponente allein ist über die Benutzeroberfläche nicht erreichbar – Sie müssen sie sichtbar machen. Die drei Möglichkeiten dafür sind:
  • Mit einem Befehlsmenüeintrag verknüpfen — registriert sie im Befehlsmenü (Cmd+K) und optional als angeheftete Schnellaktion.
  • Als Widget in ein Seitenlayout einbetten — platziert es auf der Detailseite eines Datensatzes oder in einem Dashboard.
  • Definiere sie mit defineSettingsFrontComponent() — rendert sie als Abschnitt im Settings-Tab der App und ersetzt dabei die standardmäßige Variablenkonfigurationsoberfläche.

Einfaches Beispiel

Die schnellste Möglichkeit, eine Front-Komponente in Aktion zu sehen, besteht darin, sie mit einem defineCommandMenuItem zu verknüpfen, sodass sie als Schnellaktionsschaltfläche in der oberen rechten Ecke der Seite erscheint:
src/front-components/hello-world.tsx
src/command-menu-items/hello-world.command-menu-item.ts
Nach dem Synchronisieren mit yarn twenty dev (oder durch einmaliges Ausführen von yarn twenty apply) erscheint die Schnellaktion oben rechts auf der Seite:
Klicken Sie darauf, um die Komponente inline zu rendern.

Konfigurationsfelder

Eine Front-Komponente auf einer Seite platzieren

Über Befehle hinaus können Sie eine Front-Komponente direkt in eine Datensatzseite einbetten, indem Sie sie als Widget in einem Seitenlayout hinzufügen. Details finden Sie unter Seitenlayouts.

Benutzerdefinierte Einstellungen-Komponente

Um die automatisch generierte Variablenkonfigurationsoberfläche im Settings-Tab deiner App durch deine eigene Komponente zu ersetzen, definiere sie mit defineSettingsFrontComponent statt mit defineFrontComponent. Es verwendet dieselben Konfigurationsfelder (mit Ausnahme von isHeadless, das nicht akzeptiert wird, da eine Einstellungskomponente immer eine sichtbare Benutzeroberfläche rendert) und kennzeichnet die Komponente zusätzlich als Einstellungen-UI der App. Die Komponente wird als Abschnitt innerhalb des Settings-Tabs gerendert, nicht als Ersatz für den gesamten Tab. Die von Twenty verwalteten Systembereiche – Auto-Upgrade, App-URL und Verbindungen – werden immer darüber gerendert und können von der App nicht überschrieben werden.
src/front-components/app-settings.tsx
Pro App ist nur eine Einstellungs-Frontkomponente zulässig; wenn mehr als eine deklariert wird, schlägt der Build fehl. Wenn vorhanden, rendert der Settings-Tab der App diese Komponente anstelle der standardmäßigen Konfigurationsoberfläche für Variablen.

Headless vs. Nicht-Headless

Front-Komponenten gibt es in zwei Rendering-Modi, die durch die Option isHeadless gesteuert werden: Nicht-Headless (Standard) — Die Komponente rendert eine sichtbare UI. Wird sie über das Befehlsmenü ausgelöst, öffnet sie sich im Seitenpanel. Dies ist das Standardverhalten, wenn isHeadless false ist oder weggelassen wird. Headless (isHeadless: true) — Die Komponente wird unsichtbar im Hintergrund gemountet. Sie öffnet das Seitenpanel nicht. Headless-Komponenten sind für Aktionen konzipiert, die Logik ausführen und sich anschließend selbst unmounten — zum Beispiel das Ausführen einer asynchronen Aufgabe, das Navigieren zu einer Seite oder das Anzeigen eines Bestätigungsdialogs. Sie lassen sich gut mit den unten beschriebenen SDK-Command-Komponenten kombinieren.
src/front-components/sync-tracker.tsx
Da die Komponente null zurückgibt, überspringt Twenty das Rendern eines Containers dafür — im Layout entsteht kein Leerraum. Die Komponente hat dennoch Zugriff auf alle Hooks und die Host-Kommunikations-API.

SDK-Command-Komponenten

Das Paket twenty-sdk stellt vier Command-Hilfskomponenten bereit, die für Headless-Front-Komponenten ausgelegt sind. Jede Komponente führt beim Mounten eine Aktion aus, behandelt Fehler durch Anzeige einer Snackbar-Benachrichtigung und unmountet die Front-Komponente nach Abschluss automatisch. Importieren Sie sie aus twenty-sdk/front-component:
  • Command — Führt einen asynchronen Callback über das Prop execute aus.
  • CommandLink — Navigiert zu einem App-Pfad. Props: to, params, queryParams, options.
  • CommandModal — Öffnet einen Bestätigungsdialog. Bestätigt der Benutzer, wird der Callback execute ausgeführt. Props: title, subtitle, execute, confirmButtonText, confirmButtonAccent.
  • CommandOpenSidePanelPage — Öffnet eine Seite im Seitenpanel. Props hängen von page ab — z. B. verwendet ViewRecord recordId + objectNameSingular (plus eine optionale tab-ID, um den Datensatz auf einem bestimmten Tab zu öffnen), andere Seiten verwenden pageTitle + pageIcon.
Hier ist ein vollständiges Beispiel einer Headless-Front-Komponente, die Command verwendet, um eine Aktion aus dem Befehlsmenü auszuführen:
src/front-components/run-action.tsx
src/command-menu-items/run-action.command-menu-item.ts
Und ein Beispiel, das CommandModal verwendet, um vor der Ausführung um Bestätigung zu bitten:
src/front-components/delete-draft.tsx
Und ein Beispiel mit CommandOpenSidePanelPage, um den aktuellen Datensatz im Seitenbereich auf einem bestimmten Tab zu öffnen. tab ist eine Seitenlayout-Tab-ID (Standardlayouts verwenden IDs wie company-tab-emails oder company-tab-timeline; benutzerdefinierte Layouts verwenden die eigene ID des Tabs). Wenn die ID im Layout des Datensatzes nicht vorhanden ist, wird stattdessen der Standard-Tab geöffnet:
src/front-components/open-company-emails.tsx

Aufrufen einer Logikfunktion

Front-Komponenten laufen browserseitig in einem Web-Worker, der in einem sandboxed iframe mit opaker Origin ausgeführt wird, während Logikfunktionen serverseitig laufen. Es gibt keinen direkten In-Process-Aufruf zwischen beiden – stattdessen ruft eine Front-Komponente eine Logikfunktion über HTTP auf. Eine mit httpRouteTriggerSettings deklarierte Logikfunktion ist über HTTP unter ihrem Routenpfad erreichbar. RestApiClient behandelt Pfade, die mit /s/ beginnen, als App-Routen, löst sie zur URL auf, unter der deine Funktionen bereitgestellt werden, und authentifiziert sie mit TWENTY_APP_ACCESS_TOKEN.
In Twenty Cloud werden HTTP-ausgelöste Logikfunktionen auf einer eigenen, arbeitsbereichsspezifischen Domain bereitgestellt unter https://\<your-workspace-subdomain>.withtwenty.com\<path>. Für externe Aufrufer kopiere die exakte URL aus den HTTP trigger-Einstellungen der Funktion oder aus dem Settings-Tab der Anwendung.
Eine headless Front-Komponente kann den Aufruf beim Mounten über die Command-Komponente ausführen und sich anschließend automatisch unmounten:
src/front-components/sync-prs.tsx
Der an RestApiClient übergebene Pfad ist der httpRouteTriggerSettings.path der Logikfunktion, der mit /s präfixiert ist. Belasse isAuthRequired: true; das TWENTY_APP_ACCESS_TOKEN, das Twenty für deine Komponente ausstellt, authentifiziert die Anfrage:
src/logic-functions/fetch-prs.logic-function.ts
TWENTY_APP_ACCESS_TOKEN wird automatisch injiziert – siehe Anwendungsvariablen. Da geheime Anwendungsvariablen niemals in Front-Komponenten offengelegt werden, sollten API-Schlüssel und andere sensible Logik in der Logikfunktion verbleiben und nicht in der Front-Komponente.

Aufrufen der Twenty-REST-API

Um App-HTTP-Routen aufzurufen oder Twenty-Datensätze aus einer Front-Komponente zu lesen und zu schreiben, verwende RestApiClient aus twenty-client-sdk/rest. Es sendet /s/...-Pfade an die Funktions-Basis-URL deines Arbeitsbereichs und alle anderen Pfade, einschließlich /rest/..., an TWENTY_API_URL. Es handelt immer als die Person, die die Seite betrachtet. runAs: 'application' ist nur eine Option für Logikfunktionen: Eine Komponente erhält niemals das eigene Token Ihrer Anwendung. Wenn Sie es hier anfordern, wird ein Fehler ausgelöst. Lagern Sie Arbeiten, die den eigenen Zugriff der Anwendung benötigen, hinter eine Logikfunktion aus und rufen Sie stattdessen diese auf. options akzeptiert headers, query (ein Record von Query-String-Parametern; null- bzw. undefined-Werte werden übersprungen) sowie ein AbortSignal über signal. Ein body-Objekt, das kein FormData ist, wird automatisch als JSON serialisiert. Bei einem 401 aktualisiert der Client das Access-Token einmal über den Host und versucht die Anfrage erneut. Die Basis-URL und das Token werden standardmäßig aus der Umgebung ermittelt. Gib bei Bedarf – zum Beispiel in Tests – Überschreibungen an den Konstruktor weiter:
Fehlgeschlagene Anfragen lösen einen RestApiClientError aus, der status, statusText, url und den geparsten body bereitstellt:

Zugriff auf den Laufzeitkontext

Verwenden Sie innerhalb Ihrer Komponente SDK-Hooks, um auf den aktuellen Benutzer, den Datensatz und die Komponenteninstanz zuzugreifen:
src/front-components/record-info.tsx
Verfügbare Hooks:

Anwendungsvariablen

In defineApplication() mit isSecret: false definierte Anwendungsvariablen sind in Front-Komponenten über das Hilfsprogramm getApplicationVariable verfügbar:
src/front-components/greeting.tsx
Geheime Variablen (isSecret: true) werden nicht in Front-Komponenten offengelegt. Sie sind nur in Logikfunktionen verfügbar, die serverseitig ausgeführt werden. Dadurch wird verhindert, dass sensible Werte wie API-Schlüssel an den Browser gesendet werden.
getApplicationVariable gibt immer einen String (oder undefined) zurück, unabhängig vom deklarierten type der Variable. Der String wird je nach Typ konsistent serialisiert (boolesche Werte als "true" / "false", Zahlen als Dezimalstrings, Arrays / Objekte als JSON), im selben Format, das für die Logikfunktion process.env verwendet wird — parsen Sie ihn selbst (Number(...), JSON.parse(...), === 'true'). Siehe Variablentypen. Die folgenden Systemvariablen sind immer über process.env verfügbar:

TWENTY_FUNCTIONS_URL

Twenty injiziert außerdem TWENTY_FUNCTIONS_URL in Front-Komponenten und Logikfunktionen: die Basis-URL, unter der die HTTP-ausgelösten Logikfunktionen deiner App bereitgestellt werden. Sie existiert, weil diese URL nicht immer der Twenty-Server selbst ist. In Twenty Cloud werden App-Routen auf einer eigenen, arbeitsbereichsspezifischen Domain bereitgestellt (https://\<your-workspace-subdomain>.withtwenty.com oder die primäre öffentliche Domain der Anwendung, falls eine konfiguriert ist), damit von der App erzeugte Antworten in einem isolierten Origin und nicht im Origin der Twenty-App ausgeführt werden. Self-Hosted- und lokale Instanzen stellen App-Routen unter dem Präfix /s auf dem Server selbst bereit und setzen die Variable eventuell gar nicht. Da die Basis-URL je nach Arbeitsbereich und Instanz variiert, kann dein Code sie nicht hardcoden – der Server injiziert zur Laufzeit den richtigen Wert. Du musst sie nur selten direkt lesen. Rufe deine Routen über RestApiClient mit einem mit /s/ präfixierten Pfad auf, und der Client löst die URL für dich auf: Er entfernt das Präfix /s und verwendet TWENTY_FUNCTIONS_URL als Ziel, mit Fallback auf \<TWENTY_API_URL>/s, wenn die Variable nicht gesetzt ist. Verwende resolveUrl('/s/\<path>'), um die absolute URL ohne das Senden einer Anfrage zu erhalten, z. B. für einen Link. Lies die Variable nur direkt aus, wenn du eine URL manuell zusammenbaust:

Host-Kommunikations-API

Front-Komponenten können Navigation, Modals und Benachrichtigungen mittels Funktionen aus twenty-sdk auslösen: Hier ist ein Beispiel, das die Host-API verwendet, um nach Abschluss einer Aktion eine Snackbar anzuzeigen und das Seitenpanel zu schließen:
src/front-components/archive-record.tsx

Speicher

localStorage und sessionStorage funktionieren wie auf einer normalen Seite mit der standardmäßigen synchronen API. Deine Schlüssel sind auf die Installation deiner App und die angemeldete Benutzerin bzw. den angemeldeten Benutzer beschränkt: Keine andere App kann sie lesen, und wenn sich eine andere Benutzerin oder ein anderer Benutzer im selben Browser anmeldet, beginnt diese Person mit einem leeren Speicher. In localStorage geschriebene Werte bleiben geräteweit über Neuladungen hinweg erhalten; sessionStorage besteht für die Dauer der Browsersitzung.
src/front-components/note-draft.tsx
Twenty speichert die Werte im Namen deiner App, sodass ein Schreibvorgang lokal sofort angewendet und im Hintergrund gespeichert wird. Lesevorgänge warten niemals auf den Host. Es wird nichts synchronisiert: Die Werte folgen der Benutzerin oder dem Benutzer nicht in einen anderen Browser oder auf eine andere Maschine. Verwende daher den Key-Value Store einer Logic Function für alles, was einen Gerätewechsel überstehen muss. Schreibvorgänge sind begrenzt, und alle Limits zählen Zeichen statt Bytes: Schlüssel sind höchstens 512 Zeichen lang, ein einzelner Wert höchstens 262.144 Zeichen, und jeder Speicher höchstens 1.048.576 Zeichen pro App und Benutzerin oder Benutzer. Ein Schreibvorgang, der ein Limit überschreitet, löst einen QuotaExceededError aus, wie bei der Browser-API.

Mit mehreren Datensätzen arbeiten

Verwenden Sie useSelectedRecordIds(), um mehrere ausgewählte Datensätze zu verwalten. Dies ist nützlich für Stapelvorgänge:
src/front-components/bulk-export.tsx
Machen Sie es über einen Befehlsmenüeintrag sichtbar, der auf die Auswahl von Datensätzen beschränkt ist:
src/command-menu-items/bulk-export.command-menu-item.ts

Öffentliche Assets

Front-Komponenten können mit getPublicAssetUrl auf Dateien aus dem public/-Verzeichnis der App zugreifen:
Details finden Sie im Abschnitt Öffentliche Assets.

Freigabe von Abhängigkeiten über die Front-Komponenten

Standardmäßig bündelt jede Front-Komponente ihre eigene Kopie der von ihr importierten Bibliotheken, so dass eine App mit fünf Komponenten fünf Mal React verschickt. Erklären Sie geteilte Abhängigkeiten im Paket Ihrer App. son`, um diese Bibliotheken einmal zu erstellen und jede Komponente der App aus einer einzigen zwischengespeicherten Datei laden zu lassen:
package.json
Jede Komponente importiert dann ihre Abhängigkeiten genau wie zuvor — nichts ändert sich im Komponentencode:
src/front-components/counter.tsx
Ein paar Dinge, die Sie wissen sollten:
  • Ein freigegebenes Abhängigkeitsbündel pro App. Das Paket wird aus den eigenen Abhängigkeiten deiner App aufgebaut, so dass du die volle Kontrolle über die von dir ausgelieferten Versionen behalten kannst.
  • Listet die exakten Angaben, die du importierst, auf. twenty-ui/input und twenty-ui/display sind zwei Einträge; ein Paketname allein deckt seine Unterpfade nicht ab. Das Auflisten von react deckt automatisch react/jsx-runtime ab.
  • Teile react-dom/client neben react. Jede Komponente wird durch createRoot erzeugt, so dass es herauskommt, dass jede Komponente noch React DOM-Pakete enthält.
  • **Das Bundle wird zwischengespeichert. * Es wird unter einer Content-Hash-URL mit einem langlebigen unveränderlichen Cache versorgt so dass es einmal heruntergeladen und über alle Komponenten der App wiederverwendet wird, bis sich eine seiner Abhängigkeiten ändert.
  • Komponenten, die keines der gemeinsam genutzten Pakete importieren, laden sie nie herunter.

Styling

Front-Komponenten unterstützen mehrere Styling-Ansätze. Sie können verwenden:
  • Inline-Stylesstyle={{ color: 'red' }}
  • Twenty UI-Komponenten — Twentys eigene Komponentenbibliothek; siehe Verwenden von Twenty UI-Komponenten unten
  • Emotion — CSS-in-JS mit @emotion/react
  • Styled-componentsstyled.div-Muster
  • Tailwind CSS — Utility-Klassen
  • Beliebige CSS-in-JS-Bibliothek, die mit React kompatibel ist

Verwenden von Twenty UI-Komponenten

Twenty liefert seine Komponentenbibliothek als twenty-ui-Paket aus. Frontend-Komponenten können sie für Schaltflächen, Tags, Status-Pills, Chips, Avatare, Icons, Typografie und Theme-Tokens verwenden, die automatisch zum hellen und dunklen Theme des Arbeitsbereichs passen.

Installation

Fügen Sie das Paket zu Ihrer App hinzu und fixieren Sie es auf die Version, mit der Ihre Twenty-Instanz ausgeliefert wird:
twenty-ui wird zur Build-Zeit in Ihre Frontend-Komponente gebündelt, sodass es nur eine Abhängigkeit Ihrer App sein muss – zur Laufzeit muss nichts konfiguriert werden.

Komponenten importieren

Importieren Sie aus dem passenden Subpfad statt aus dem Paket-Root, damit nur die Komponenten, die Sie verwenden, in Ihrem Bundle landen:

Icons

Importieren Sie einzelne Icons aus twenty-ui/icon:
Jedes benannte Icon wird per Tree Shaking berücksichtigt, sodass der Import einiger weniger Ihr Bundle nur gering vergrößert. Vermeiden Sie IconsProvider, useIcons und iconsState – sie ziehen das vollständige Tabler-Icon-Set (mehrere MB) mit hinein.

Theming und Theme-Tokens

Twenty UI-Komponenten passen sich automatisch dem hellen und dunklen Theme des Arbeitsbereichs an – der Renderer wendet das aktive Farbschema auf dem Host an und die Komponenten leiten ihre Farben daraus ab. Um dieselben Design-Tokens in Ihren eigenen Inline-Styles zu verwenden, rufen Sie den Hook useTheme() auf. Er gibt die Theme-Tokens von Twenty (Abstände, Farben, Radien, Schriftarten) zurück, die mit dem aktiven Theme verknüpft sind – ohne dass ein ThemeProvider in Ihrer Komponente eingerichtet werden muss:
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-Komponenten befinden sich in aktiver Entwicklung. Rendern, Styling, Ereignisbehandlung, Messen von Elementen und Browser-Speicher funktionieren gut. Alles, was über diese Aspekte hinausgeht (Aufrufen einer DOM-Methode auf einem Ref, Beobachten von Größenänderungen eines Elements, Portaling außerhalb deines Baums), fehlt heute noch oder ist unvollständig, und das meiste davon schlägt stillschweigend fehl: keine Exception und auch kein TypeScript-Fehler, da das Gerüst gegen das vollständige Browser-DOM typisiert ist. Wenn dich eines dieser Probleme blockiert, eröffne ein Issue, damit es priorisiert wird.

Layout und Messung

Elemente können sich selbst messen: Der Host spiegelt die Geometrie in die Sandbox, sodass Lesezugriffe lokal beantwortet werden, aber bis zu einem Frame veraltet sein können, und der erste Lesezugriff auf ein noch nie gemessenes Element gibt Nullen zurück. Nach dem Schreiben erneut in einem requestAnimationFrame-Callback oder in einem Effekt lesen. Positionierung über getBoundingClientRect funktioniert jetzt, aber alles, was Größenänderungen über ResizeObserver beobachtet (Recharts ResponsiveContainer, Floating UIs autoUpdate), funktioniert weiterhin nicht. Verwende ohnehin CSS für das Layout: dein Stylesheet erreicht die echte Seite, daher verhalten sich Flexbox, Grid, aspect-ratio, clamp() und @container normal, ohne Frame-Lag.
requestAnimationFrame, fetch, setTimeout und queueMicrotask funktionieren ohne das Präfix window.. Nur window.requestAnimationFrame(...) und ähnliche Aufrufe lösen eine Exception aus.

DOM-Zugriff

Ein ref gibt dir ein Sandbox-Element, kein HTMLElement. Diese Portal-Lücke ist der Grund, warum Radix-, Headless-UI-, MUI- und react-select-Popover standardmäßig nichts rendern. Die meisten akzeptieren eine Container-Prop; verweise sie auf ein Element, das du gerendert hast.

Ereignisse

Maus, Zeiger, Touch, Drag, Tastatur, Fokus, input/change/submit, scroll/wheel/contextmenu und animationend/transitionend werden an den Host durchgereicht, plus ein paar pro Element: load/error auf img, Zwischenablage und Komposition auf input/textarea, Medien auf video/audio, toggle auf details/dialog. Alles andere (onAuxClick, onSelect, onInvalid, onReset, onAnimationStart, Pointer-Capture, onLoad von img) wird ohne Warnung verworfen. document.addEventListener() und window.addEventListener() werden ohne Fehler registriert und feuern nie, weshalb ein Drag aufhört, sobald der Zeiger das Element verlässt, auf dem er begonnen hat. event.preventDefault() wird ebenfalls nicht durchgereicht; Formularübermittlung, dragover/drop und Link-Klicks sind bereits für dich abgesichert.

Attribute und Styling

Jedes Element leitet seine eigenen Eigenschaften an den Host-DOM weiter (href auf a, src/alt auf img, value/placeholder/disabled auf input usw.), plus einen gemeinsamen Satz auf jedem Element: id, className, style, title, tabIndex, role, draggable und jedes aria-*-/data-*-Attribut (mit Bindestrich, daher wird ariaLabel verworfen). Alles außerhalb davon wird stillschweigend verworfen, daher solltest du benutzerdefinierte Zustände als data-* ausdrücken. Component-CSS, egal ob aus import './styles.css', CSS-in-JS oder einem style-Element, wird unscoped in den head der Host-Seite injiziert. Dadurch kollidieren Klassennamen mit denen von Twenty (präfixe sie und schreibe niemals nacktes div { ... }-Selektoren), und @media bezieht sich auf das Browserfenster statt auf dein Widget (verwende @container mit deinem eigenen container-type). Inline-style-Props sind nicht betroffen.

Speicher und Netzwerk

localStorage und sessionStorage werden von Twenty statt vom Browser bereitgestellt: Die Komponente läuft in einem Worker mit einem intransparenten Ursprung, daher speichert der Host die Werte im Namen deiner App. Siehe Speicher für ihren Geltungsbereich und ihre Limits. IndexedDB, Cookies, die Cache API und BroadcastChannel sind weiterhin nicht verfügbar. Um Zustand geräteübergreifend zu persistieren, rufe eine Logic Function auf und verwende deren Key-Value Store. fetch funktioniert, mit Einschränkungen:
  • Aufrufe an die Twenty-API und die Routen deiner App werden vom Host als Proxy weitergeleitet, daher solltest du RestApiClient bevorzugen. Bei proxied Aufrufen werden AbortSignal und die anderen RequestInit-Optionen verworfen, und es werden nur string- und URLSearchParams-Bodies unterstützt.
  • Andere Origins verlassen die Sandbox mit Origin: null, sodass eine Drittanbieter-API nur antwortet, wenn sie Access-Control-Allow-Origin: * sendet. Rufe sie stattdessen aus einer Logic Function auf.
  • fetch('/rest/people') wird niemals der Twenty-API zugeordnet, weil die Sandbox keine Seiten-URL hat, gegen die ein relativer Pfad aufgelöst werden könnte.

Medienerfassung

navigator.mediaDevices.getUserMedia() und MediaRecorder funktionieren innerhalb von Front-Komponenten über Sandbox-Polyfills, sodass Standard-Aufnahmecode unverändert ausgeführt wird und MediaRecorder.isTypeSupported Auskunft darüber gibt, ob gängige Container-/Codec-Kombinationen unterstützt werden. Detaillierte getUserMedia-Constraint-Objekte werden akzeptiert, aber nicht weitergereicht – der Host erfasst mit seinen Standardwerten für die angeforderten Typen – und es kann immer nur eine Aufnahme gleichzeitig über Anwendungen hinweg aktiv sein. Speichere ein aufgezeichnetes Blob mit der Host-Funktion uploadFile.

Weitere Lücken

  • Dateiinhalt. Ein input des Typs file gibt deinem Handler nur Dateimetadaten, nicht die Bytes, daher ist FileReader nicht verfügbar. Um ein Blob hochzuladen, das dein Code bereits besitzt – z. B. eines, das von MediaRecorder erzeugt wurde – verwende die Host-Funktion uploadFile.
  • Drag-and-drop-Nutzlasten. Drag-Events werden ausgelöst, aber event.dataTransfer ist undefined.
  • Node-Built-ins. fs, path und node:crypto führen zu einem Build-Fehler, daher solltest du diese Arbeit in eine Logic Function auslagern. Web Crypto, fetch, TextEncoder und URL sind verfügbar.
  • iframe wird immer erneut ohne allow-same-origin in einer Sandbox ausgeführt, sodass eine Einbettung, die auf ihre eigene Sitzung angewiesen ist, als abgemeldet gerendert wird. Es hat auch kein onLoad.