# App Manifest Documentation ## Overview A app manifest is a JSON-formatted configuration that defines a app's properties, behavior, and capabilities within the system. This document outlines the structure and elements of the manifest. ## Manifest Structure ### Basic Properties | Property | Type | Description | | --- | --- | --- | | `manifestVersion` | string | Specifies the version of the manifest schema (format: "major.minor.patch") | | `version` | string | The version of the app itself (format: "major.minor.patch") | ### Name Information Accepts a short and full property, both are simple strings. The full property serves as the Display-name of a given app, whereas the short property describes an identifier. | Property | Type | Description | | --- | --- | --- | | `short` | string | Brief name of the app (supports template keys like `__TK_key1__`) | | `full` | string | Complete name of the app | ### Description The `description` object provides information about the purpose and functionality of the app: | Property | Type | Description | | --- | --- | --- | | `short` | string | Brief summary of the app (50-150 characters recommended) | | `full` | string | Detailed description explaining the app's features and benefits (150-1000 characters recommended) | Both properties support template keys using the `__TK_key1__` syntax for localization. ### Localization The `defaultLocale` takes the descriptor of the app's default language setting as a string that has to match one of the descriptors in the `locales` object. the `locales` describes the languages the App supports by providing a descriptor and an object of key-value pairs. Keys being the variables used in the code and values being their respective displayed texts in the app. As in the name.short example above, a specified variable can be used using the following syntax: | Property | Type | Description | | --- | --- | --- | | `defaultLocale` | string | Default locale code (ISO format, e.g., "de-DE") | | `locales` | object | Maps locale codes to translation key-value pairs | ### Visual Elements Accepts a dark and light property as links to where the App Icon is stored. The chosen image will be displayed in the app card in the hub. depending on the theme either the dark or light variants will automatically be chosen. Should the image not be available, it will be displayed as a placeholder. | Property | Type | Description | | --- | --- | --- | | `light` | string | Icon URL for light themes (HTTPS URL, PNG/SVG recommended) | | `dark` | string | Icon URL for dark themes (HTTPS URL, PNG/SVG recommended) | ### Support and Documentation The `communication` object contains resources for users to get help and learn about the app: | Property | Type | Description | | --- | --- | --- | | `supportUrl` | string | URL where users can get technical help or report issues with the app. Supports the `__ACTIVE_LOCALE__` template variable for localization. | | `guideUrl` | string | URL to comprehensive documentation that explains how to use the app's features. Supports the `__ACTIVE_LOCALE__` template variable for localization. | ### Legal Information The `legal` object contains URLs for compliance and legal documentation: | Property | Type | Description | | --- | --- | --- | | `gdprRequestUrl` | string | URL for users to submit GDPR data access requests, allowing them to view what personal data is stored | | `gdprDeleteUrl` | string | URL for users to submit GDPR data deletion requests when they want their personal data removed | | `privacyUrl` | string | URL to the app's privacy policy, which outlines how user data is collected, used, and protected | | `termsOfUseUrl` | string | URL to the terms of service document that defines the conditions under which users may access and use the app | ### App Lifecycle The `lifecycle` object defines integration points for the app's installation process: | Property | Type | Description | | --- | --- | --- | | `setupUrl` | string | URL called during app installation that can display a login screen to match the app's user/tenant with the installing cloud tenant | | `connectUrl` | string | Webhook URL that will be triggered when the app is installed (functionality not yet implemented) | | `disconnectUrl` | string | Webhook URL that will be triggered when the app is uninstalled (functionality not yet implemented) | Using the token A working example of this can be found in the Example app's SetupPage.tsx located at: '/examples/hello-world-app/frontend/src/setupPage/SetupPage.tsx' as well as the corresponding "/connect-tenant" route found in "/examples/hello-world-app/backend/src/index.ts" ### Requirements The `requirements` object contains: | Property | Type | Description | | --- | --- | --- | | `minCloudApiVersion` | string | Minimum compatible API version | ### Capabilities #### Hub Capabilities The `capabilities.hub` object defines how the app integrates with the JTL-Hub: | Property | Type | Description | | --- | --- | --- | | `appLauncher.redirectUrl` | string | URL that the system redirects to when the app's card is clicked in the hub | #### Pane Capabilities The `capabilities.pane` object defines how the app integrates with the pane sidebar of the JTL-ERP: | Property | Type | Description | | --- | --- | --- | | `url` | string | Desired URL to show in the pane view | | `title` | string | Title of your app shown in the pane view | | `context` | string | Dot notation of the url path you want your app to be available in | | `matchChildContext` | boolean | Flag that determines whether or not the whole context needs to match for the App to be displayed | #### ERP Capabilities The `capabilities.erp` object defines how the app integrates with the JTL-ERP: ##### Headless Mode | Property | Type | Description | | --- | --- | --- | | `headless.url` | string | URL for headless mode (TBD) | ##### Menu Items The `menuItems` array defines custom navigation elements in the ERP interface: | Property | Type | Description | | --- | --- | --- | | `id` | string | Internal identifier for the menu item | | `name` | string | Display name shown in the navigation | | `url` | string | *(optional)* Link to the content when the item is clicked | | `children` | array | *(optional)* Nested sub-menu items with the same structure | Menu items can be nested using the `children` property, creating hierarchical navigation. Currently, only root items are supported in the implementation, so nested children won't affect the app's behavior. ##### Tabs Each item in the `tabs` array defines a custom tab that appears in specific contexts: | Property | Type | Description | | --- | --- | --- | | `context` | string | Where the tab appears (e.g., "productDetail", "customerDetail") | | `name` | string | Display name shown on the tab | | `url` | string | Content URL loaded when the tab is selected | | `features` | array | Permission features needed for the tab to function | ##### API The `api` object contains: | Property | Type | Description | | --- | --- | --- | | `scopes` | array | API permission scopes required | ## Template Variables The manifest supports these template variables: - `__TK_key1__`: Replaced with translation values from the `locales` section - `__ACTIVE_LOCALE__`: Replaced with the user's active locale ## Complete Example ```json { "manifestVersion": "1.0.0", "version": "1.0.0", "name": { "short": "Hello World example", "full": "Hello World example" }, "description": { "short": "Official Hello World example.", "full": "This is the official Hello World example." }, "defaultLocale": "de-DE", "locales": { "de-DE": { "key1": "abc" }, "en": { "key1": "abc" } }, "icon": { "light": "https://hub.jtl-cloud.com/assets/image-placeholder.png", "dark": "https://hub.jtl-cloud.com/assets/image-placeholder.png" }, "communication": { "supportUrl": "https://example.com/support-for-plugin-xy/__ACTIVE_LOCALE__/", "guideUrl": "https://example.com/guide-for-plugin-xy?lang=__ACTIVE_LOCALE__" }, "legal": { "gdprRequestUrl": "https://example.com/gdpr/request", "gdprDeleteUrl": "https://example.com/gdpr/delete", "privacyUrl": "https://example.com/privacy", "termsOfUseUrl": "https://example.com/terms-of-use" }, "lifecycle": { "setupUrl": "http://localhost:50142/setup", "connectUrl": "https://jtl.integrations.example.com/lifecycle/connect", "disconnectUrl": "https://jtl.integrations.example.com/lifecycle/disconnect" }, "capabilities": { "hub": { "appLauncher": { "redirectUrl": "http://localhost:50142/erp" } }, "erp": { "headless": { "url": "https://jtl.integrations.example.com/erp" }, "menuItems": [ { "id": "