---
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.

## 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                                                                                                          |

<Note>
`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.
</Note>
