메인 콘텐츠로 건너뛰기
모든 앱에는 defineApplication 호출이 정확히 하나 있어야 합니다. 다음 항목을 선언합니다:
  • 식별 정보 — 범용 식별자, 표시 이름, 설명.
  • 권한 — 로직 함수와 프런트 컴포넌트가 어떤 역할로 실행되는지.
  • 변수 (선택 사항) — 코드에 환경 변수로 노출되는 키–값 쌍.
  • 설치 전/후 훅 (선택 사항)Logic Functions를 참조하세요.
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,
    },
  },
});
노트:
  • universalIdentifier 필드는 여러분이 소유하는 변하지 않는 고유 ID입니다. 한 번만 생성하고 이후 동기화 동안에도 변하지 않도록 유지하세요.
  • applicationVariables는 함수와 프런트 컴포넌트의 환경 변수가 됩니다. 로직 함수(서버 사이드)에서는 process.env.VARIABLE_NAME으로 사용할 수 있습니다. 프런트 컴포넌트에서는 twenty-sdk/front-componentgetApplicationVariable('VARIABLE_NAME')을 사용하세요. isSecret: true로 표시된 변수는 로직 함수에만 주입됩니다. 프런트 컴포넌트는 비밀이 아닌 변수만 받습니다.
  • 기본 역할은 defineApplicationRole()로 표시된 역할 파일에서 자동으로 감지되므로, defineApplication()에서 이를 참조할 필요가 없습니다.
  • 설치 전/후 함수는 매니페스트 빌드 중 자동으로 감지됩니다 — defineApplication()에서 별도로 참조할 필요가 없습니다.
  • 하위 호환성을 위해 defaultRoleUniversalIdentifier를 명시적으로 전달하는 방식도 계속 지원되지만, 이제는 defineApplicationRole() 사용을 권장하며 이전 방식은 더 이상 권장되지 않습니다.
  • serverVariables는 인스턴스 범위의 구성 및 비밀(예: API 키)입니다. applicationVariables와 달리, 매니페스트에는 값을 선언하지 않으며, 워크스페이스 운영자가 앱 설정에서 값을 채워 넣으면 설정된 이후에만 로직 함수에 주입됩니다.

변수 유형

applicationVariablesserverVariables는 모두 선택적인 type을 허용하며, SELECT / MULTI_SELECT의 경우 options 목록을 허용합니다. 지원되는 타입: TEXT(기본값), 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',
    },
  },
});
type표현과 검증에만 영향을 줍니다. 즉, 워크스페이스 설정 UI에서 해당하는 입력 요소(토글, 숫자 필드, 드롭다운, 날짜 선택기, JSON 편집기 등)를 선택합니다. 또한 빌드가 구성(config)을 검증하도록 합니다(예를 들어 SELECT / MULTI_SELECT는 비어 있지 않은 options를 선언해야 합니다). 값이 코드로 전달되는 방식은 변경되지 않습니다. 값은 항상 문자열로 주입됩니다. 이는 환경 변수의 특성 때문입니다(process.env.*는 문자열만 허용). 로직 함수가 실행될 때, 실행기는 선언된 type에 따라 각 값을 직렬화하여 process.env를 구성하므로, 값이 어떻게 설정되었는지(매니페스트 기본값, 설정 UI, 또는 이전 버전)와 관계없이 문자열 형식이 일관되게 유지됩니다:
유형process.env 문자열
TEXT, SELECT, DATE, DATE_TIME원시 값("eu", "2026-01-01")
BOOLEAN"true" / "false"
NUMBER, NUMERIC10진수 문자열("10", "2.5")
MULTI_SELECT, ARRAYJSON 배열('["email","postcard"]')
RAW_JSON, RICH_TEXTJSON 객체('{"retries":3}')
문자열을 다시 기대하는 타입으로 파싱하세요:
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 }
getApplicationVariable('VARIABLE_NAME')을 통해 값을 읽는 프런트 컴포넌트에도 동일하게 적용됩니다. 반환되는 값은 문자열이므로, 필요에 따라 파싱해야 합니다.

기본 함수 역할

defineApplicationRole()로 선언된 역할은 앱의 로직 함수와 프런트엔드 컴포넌트가 무엇에 접근할 수 있는지를 제어합니다:
  • TWENTY_APP_ACCESS_TOKEN로 주입되는 런타임 토큰은 이 역할에서 파생됩니다.
  • 타입드 API 클라이언트는 해당 역할에 부여된 권한으로 제한됩니다.
  • 최소 권한 원칙을 따르세요: 함수에 필요한 권한만 선언하세요.
새 앱을 스캐폴딩하면 CLI가 src/roles/default-role.ts에 시작용 역할 파일을 생성합니다. 전체 내용은 Roles & Permissions를 참조하세요.

마켓플레이스 메타데이터

앱을 게시할 계획이라면, 다음 선택적 필드로 마켓플레이스에서 표시되는 방식을 제어합니다:
필드설명
author작성자 또는 회사 이름
category마켓플레이스 필터링을 위한 앱 카테고리
logopublic/에 번들된 앱 로고의 경로(예: public/logo.png)
galleryImagespublic/에 번들된 갤러리 이미지 경로의 배열(예: public/screenshot-1.png)
aboutDescription”About” 탭에 대한 더 긴 마크다운 설명. 생략하면 마켓플레이스는 npm의 패키지 README.md를 사용합니다
websiteUrl웹사이트 링크
termsUrl서비스 약관 링크
emailSupport지원 이메일 주소
issueReportUrl이슈 트래커 링크
logoUrlscreenshotslogogalleryImages의 더 이상 사용되지 않는 별칭입니다. 다음 필드에는 외부 절대 URL(http:// 또는 https://)이 지원되지 않습니다. 빌드 시 경고와 함께 제거됩니다. 대신 앱의 public/ 폴더에 이미지를 번들하세요.