Vai al contenuto principale
Ogni app deve avere esattamente una chiamata a defineApplication. Dichiara:
  • Identità — identificatore universale, nome visualizzato, descrizione.
  • Autorizzazioni — il ruolo sotto il quale vengono eseguite le sue funzioni logiche e i componenti front-end.
  • Variabili (opzionali) — coppie chiave–valore esposte al tuo codice come variabili d’ambiente.
  • Hook di pre-installazione / post-installazione (opzionali) — vedi Funzioni logiche.
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,
    },
  },
});
Note:
  • I campi universalIdentifier sono ID deterministici che possiedi. Generali una volta e mantienili stabili tra una sincronizzazione e l’altra.
  • applicationVariables diventano variabili d’ambiente per le tue funzioni e i componenti front-end. Nelle funzioni di logica (lato server), sono disponibili come process.env.VARIABLE_NAME. Nei componenti front-end, usa getApplicationVariable('VARIABLE_NAME') da twenty-sdk/front-component. Le variabili contrassegnate con isSecret: true vengono iniettate solo nelle funzioni di logica. I componenti front-end ricevono solo variabili non segrete.
  • Il ruolo predefinito viene rilevato automaticamente dal file di ruolo contrassegnato con defineApplicationRole(): non è necessario farvi riferimento da defineApplication().
  • Le funzioni di pre-installazione e post-installazione vengono rilevate automaticamente durante il build del manifest — non è necessario farne riferimento in defineApplication().
  • Il passaggio esplicito di defaultRoleUniversalIdentifier è ancora supportato per garantire la compatibilità con le versioni precedenti, ma è deprecato a favore di defineApplicationRole().
  • serverVariables sono configurazioni e segreti con ambito di istanza (ad esempio chiavi API). A differenza di applicationVariables, non dichiarano alcun valore nel manifest — l’operatore dello spazio di lavoro li compila dalle impostazioni dell’app e vengono iniettati nelle funzioni di logica solo una volta impostati.

Tipi di variabili

Sia applicationVariables che serverVariables accettano un type opzionale (e, per SELECT / MULTI_SELECT, un elenco di options). Tipi supportati: TEXT (predefinito), BOOLEAN, NUMBER, NUMERIC, DATE, DATE_TIME, SELECT, MULTI_SELECT, ARRAY, RAW_JSON, RICH_TEXT.
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',
    },
  },
});
Il type influisce solo su presentazione e convalida: seleziona l’input corrispondente nell’interfaccia delle impostazioni dell’area di lavoro (un interruttore, campo numerico, menu a discesa, selettore di data, editor JSON, …) e consente alla build di convalidare la tua configurazione (ad esempio, SELECT / MULTI_SELECT devono dichiarare options non vuote). Non cambia il modo in cui il valore arriva al tuo codice. I valori sono sempre inseriti come stringhe: ciò è intrinseco alle variabili di ambiente (process.env.* accetta solo stringhe). Quando la tua funzione di logica viene eseguita, l’executor serializza ogni valore in base al type dichiarato mentre costruisce process.env, quindi il formato della stringa è coerente indipendentemente da come è stato impostato il valore (valore predefinito del manifest, interfaccia delle impostazioni o una versione precedente):
Tipostringa di process.env
TEXT, SELECT, DATE, DATE_TIMEil valore grezzo ("eu", "2026-01-01")
BOOLEAN"true" / "false"
NUMBER, NUMERICstringa decimale ("10", "2.5")
MULTI_SELECT, ARRAYarray JSON ('["email","postcard"]')
RAW_JSON, RICH_TEXToggetto JSON ('{"retries":3}')
Analizza nuovamente la stringa nel tipo che ti aspetti:
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 }
Lo stesso vale per i componenti front-end che leggono i valori tramite getApplicationVariable('VARIABLE_NAME'): il valore restituito è una stringa; analizzalo secondo le necessità.

Ruolo funzione predefinito

Il ruolo dichiarato con defineApplicationRole() controlla a cosa possono accedere le funzioni di logica e i componenti di interfaccia dell’app:
  • Il token di runtime iniettato come TWENTY_APP_ACCESS_TOKEN è derivato da questo ruolo.
  • Il client API tipizzato è limitato alle autorizzazioni concesse a quel ruolo.
  • Segui il principio del privilegio minimo: dichiara solo le autorizzazioni necessarie alle tue funzioni.
Quando esegui lo scaffolding di una nuova app, la CLI crea un file di ruolo iniziale in src/roles/default-role.ts. Per la documentazione completa, vedi Ruoli e autorizzazioni.

Metadati del marketplace

Se prevedi di pubblicare la tua app, questi campi opzionali controllano come appare nel marketplace:
CampoDescrizione
authorNome dell’autore o dell’azienda
categoryCategoria dell’app per il filtraggio nel marketplace
logoPercorso del logo dell’app in bundle in public/ (ad esempio, public/logo.png)
galleryImagesArray dei percorsi delle immagini della galleria raggruppati in public/ (ad esempio, public/screenshot-1.png)
aboutDescriptionDescrizione markdown più lunga per la scheda “Informazioni”. Se omesso, il marketplace utilizza il README.md del pacchetto da npm
websiteUrlLink al tuo sito web
termsUrlLink ai Termini di servizio
emailSupportIndirizzo email di supporto
issueReportUrlLink al sistema di tracciamento dei problemi
logoUrl e screenshots sono alias deprecati di logo e galleryImages. Gli URL assoluti esterni (http:// o https://) non sono supportati per questi campi: vengono eliminati con un avviso al momento della generazione. Raccogli invece le immagini nella cartella public/ della tua app.