--- title: App-Konfiguration description: Deklarieren Sie die Identität, die Standardrolle, Variablen und Marktplatz-Metadaten Ihrer App mit `defineApplication`. icon: rocket --- Jede App muss genau einen Aufruf von `defineApplication` haben. Dieser deklariert: * **Identität** — universeller Bezeichner, Anzeigename, Beschreibung. * **Berechtigungen** — unter welcher Rolle ihre Logikfunktionen und Frontend-Komponenten ausgeführt werden. * **Variablen** *(optional)* — Schlüssel–Wert-Paare, die Ihrem Code als Umgebungsvariablen zur Verfügung gestellt werden. * **Pre-install-/Post-install-/Uninstall-Hooks** *(optional)* — siehe [Logikfunktionen](/l/de/developers/extend/apps/logic/logic-functions). ```ts src/application-config.ts import { defineApplication } from 'twenty-sdk/define'; export default defineApplication({ universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d', displayName: 'My Twenty App', description: 'My first Twenty app', applicationVariables: { DEFAULT_RECIPIENT_NAME: { universalIdentifier: '19e94e59-d4fe-4251-8981-b96d0a9f74de', description: 'Default recipient name for postcards', value: 'Jane Doe', isSecret: false, }, }, }); ``` Notizen: * `universalIdentifier`-Felder sind deterministische IDs, die Ihnen gehören. Erzeugen Sie sie einmal und halten Sie sie über Synchronisierungen hinweg stabil. * `applicationVariables` werden zu Umgebungsvariablen für Ihre Funktionen und Frontend-Komponenten. In Logikfunktionen (serverseitig) sind sie als `process.env.VARIABLE_NAME` verfügbar. In Frontend-Komponenten verwenden Sie `getApplicationVariable('VARIABLE_NAME')` aus `twenty-sdk/front-component`. Variablen, die mit `isSecret: true` gekennzeichnet sind, werden nur in Logikfunktionen injiziert. Frontend-Komponenten erhalten nur nicht-geheime Variablen. * Die Standardrolle wird automatisch aus der Rollen-Datei erkannt, die mit [`defineApplicationRole()`](/l/de/developers/extend/apps/config/roles) markiert ist – Sie müssen sie nicht aus `defineApplication()` referenzieren. * Pre-Installations-, Post-Installations- und Deinstallationsfunktionen werden während des Manifest-Builds automatisch erkannt — Sie müssen sie in `defineApplication()` nicht referenzieren. * Die explizite Übergabe von `defaultRoleUniversalIdentifier` wird für die Abwärtskompatibilität weiterhin unterstützt, ist jedoch zugunsten von `defineApplicationRole()` veraltet. * `serverVariables` sind instanzbezogene Konfigurationen und Geheimnisse (z. B. API-Schlüssel). Im Gegensatz zu `applicationVariables` haben sie im Manifest keinen Wert definiert – die Workspace-Operatorin bzw. der Workspace-Operator trägt sie in den App-Einstellungen ein, und sie werden erst dann in Logikfunktionen eingespeist, wenn sie gesetzt sind. * Um eine benutzerdefinierte Konfigurationsoberfläche im Tab **Settings** der App anzuzeigen (anstelle des standardmäßigen Variablenkonfigurationsbereichs), deklarieren Sie eine Front-Komponente mit [`defineSettingsFrontComponent()`](/l/de/developers/extend/apps/layout/front-components#custom-settings-component) in einer eigenen Datei. Pro App ist nur eine zulässig. Systemverwaltete Bereiche (Auto-Upgrade, App-URL, Verbindungen) bleiben immer sichtbar. ## Variablentypen Sowohl `applicationVariables` als auch `serverVariables` akzeptieren einen optionalen `type` (und für `SELECT` / `MULTI_SELECT` eine `options`-Liste). Unterstützte Typen: `TEXT` (Standard), `BOOLEAN`, `NUMBER`, `NUMERIC`, `DATE`, `DATE_TIME`, `SELECT`, `MULTI_SELECT`, `ARRAY`, `RAW_JSON`, `RICH_TEXT`. ```ts src/application-config.ts import { defineApplication, FieldType } from 'twenty-sdk/define'; export default defineApplication({ // ...identity, role... applicationVariables: { MAX_POSTCARDS: { universalIdentifier: '5f4497e4-9030-4085-85eb-2c48b8d53713', description: 'Maximum postcards per batch', type: FieldType.NUMBER, value: 10, }, DEFAULT_REGION: { universalIdentifier: '76c5c321-b6b6-46eb-b4fc-f9f04bb04227', description: 'Default shipping region', type: FieldType.SELECT, options: [ { label: 'Europe', value: 'eu' }, { label: 'United States', value: 'us' }, ], value: 'eu', }, }, }); ``` Der `type` beeinflusst nur die **Darstellung und Validierung** – er wählt das passende Eingabefeld in der UI der Arbeitsbereichseinstellungen aus (Schalter, Zahlenfeld, Dropdown, Datumsauswahl, JSON-Editor, …) und ermöglicht es dem Build, deine Konfiguration zu validieren (zum Beispiel müssen `SELECT` / `MULTI_SELECT` nicht-leere `options` deklarieren). Er ändert **nicht**, wie der Wert deinen Code erreicht. Werte werden **immer als Strings bereitgestellt** – das ist inhärent bei Umgebungsvariablen (`process.env.*` enthält ausschließlich Strings). Wenn deine Logikfunktion ausgeführt wird, serialisiert der Executor jeden Wert anhand seines deklarierten `type` beim Aufbau von `process.env`, sodass das Stringformat konsistent ist, unabhängig davon, wie der Wert gesetzt wurde (Manifest-Standardwert, Einstellungs-UI oder eine vorherige Version): | Typ | `process.env`-String | | ------------------------------------- | ------------------------------------- | | `TEXT`, `SELECT`, `DATE`, `DATE_TIME` | der Rohwert (`"eu"`, `"2026-01-01"`) | | `BOOLEAN` | `"true"` / `"false"` | | `NUMBER`, `NUMERIC` | Dezimal-String (`"10"`, `"2.5"`) | | `MULTI_SELECT`, `ARRAY` | JSON-Array (`'["email","postcard"]'`) | | `RAW_JSON`, `RICH_TEXT` | JSON-Objekt (`'{"retries":3}'`) | Wandle den String zurück in den erwarteten Typ um: ```ts const maxCards = Number(process.env.MAX_POSTCARDS); // "10" -> 10 const enabled = process.env.ENABLE_TRACKING === 'true'; // "true" -> true const channels = JSON.parse(process.env.ENABLED_CHANNELS ?? '[]'); // '["email"]' -> ["email"] const config = JSON.parse(process.env.PROVIDER_CONFIG ?? '{}'); // '{"retries":3}' -> { retries: 3 } ``` Das Gleiche gilt für Frontend-Komponenten, die Werte über `getApplicationVariable('VARIABLE_NAME')` lesen – der zurückgegebene Wert ist ein String; wandle ihn bei Bedarf um. ## Standard-Funktionsrolle Die mit [`defineApplicationRole()`](/l/de/developers/extend/apps/config/roles) deklarierte Rolle steuert, worauf die Logikfunktionen und Frontend-Komponenten der App zugreifen können: * Das zur Laufzeit als `TWENTY_APP_ACCESS_TOKEN` injizierte Token wird aus dieser Rolle abgeleitet. * Der typisierte API-Client ist auf die dieser Rolle gewährten Berechtigungen beschränkt. * Befolgen Sie das Least-Privilege-Prinzip: Deklarieren Sie nur die Berechtigungen, die Ihre Funktionen benötigen. Wenn Sie eine neue App erzeugen, erstellt die CLI eine Starter-Rolldatei unter `src/roles/default-role.ts`. Die vollständige Referenz finden Sie unter [Rollen & Berechtigungen](/l/de/developers/extend/apps/config/roles). ## Marktplatz-Metadaten Wenn Sie planen, [Ihre App zu veröffentlichen](/l/de/developers/extend/apps/operations/publishing), steuern diese optionalen Felder, wie Ihre App im Marktplatz erscheint: | Feld | Beschreibung | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------- | | `author` | Name des Autors oder des Unternehmens | | `category` | App-Kategorie für die Filterung im Marktplatz | | `logo` | Pfad zu deinem App-Logo in `public/` gebündelt (z.B. `public/logo.png`) | | `galleryImages` | Array der Galerie-Bild-Pfade in `public/` gebündelt (z.B. `public/screenshot-1.png`) | | `aboutDescription` | Längere Markdown-Beschreibung für den Tab "Info". Wenn weggelassen, verwendet der Marktplatz die `README.md` des Pakets von npm | | `websiteUrl` | Link zu Ihrer Website | | `termsUrl` | Link zu den Nutzungsbedingungen | | `emailSupport` | Support-E-Mail-Adresse | | `issueReportUrl` | Link zum Issue-Tracker | `logoUrl` und `screenshots` sind veraltete Aliase von `logo` und `galleryImages`. Externe absolute URLs (`http://` oder `https://`) werden für diese Felder nicht unterstützt: Sie werden beim Build mit einer Warnung gelöscht. Bundle stattdessen die Bilder im `public/` Ordner deiner App.