App Manifest Documentation
Overview
A plugin manifest is a JSON-formatted configuration that defines a plugin'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 plugin 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 plugin, whereas the short property describes an identifier.
Property | Type | Description |
---|---|---|
short | string | Brief name of the plugin (supports template keys like __TK_key1__ ) |
full | string | Complete name of the plugin |
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) |
A working example of this can be found in the Example plugin's SetupPage.tsx located at: '/examples/hello-world-plugin/frontend/src/setupPage/SetupPage.tsx' as well as the corresponding "/connect-tenant" route found in "/examples/hello-world-plugin/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 plugin'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 thelocales
section__ACTIVE_LOCALE__
: Replaced with the user's active locale
Complete Example
{
"manifestVersion": "1.0.0",
"version": "1.0.0",
"name": {
"short": "Demo __TK_key1__",
"full": "The official plugin for Demo"
},
"description": {
"short": "Lorem ipsum.",
"full": "Minions ipsum gelatooo uuuhhh para tú bappleees para tú tank yuuu! Gelatooo po kass. Bappleees poopayee tulaliloo pepete belloo! Wiiiii."
},
"defaultLocale": "de-DE",
"locales": {
"de-DE": {
"key1": "abc"
},
"en": {
"key1": "abc"
}
},
"icon": {
"light": "https://hub.dev.jtl-cloud.com/assets/image-placeholder.png",
"dark": "https://hub.dev.jtl-cloud.com/assets/image-placeholder.png"
},
"communication": {
"supportUrl": "https://demogmbh.com/support-for-plugin-xy/__ACTIVE_LOCALE__/",
"guideUrl": "https://demogmbh.com/guide-for-plugin-xy?lang=__ACTIVE_LOCALE__"
},
"legal": {
"gdprRequestUrl": "https://demogmbh.com/gdpr/request",
"gdprDeleteUrl": "https://demogmbh.com/gdpr/delete",
"privacyUrl": "https://demogmbh.com/privacy",
"termsOfUseUrl": "https://demogmbh.com/terms-of-use"
},
"lifecycle": {
"setupUrl": "http://localhost:50142/setup",
"connectUrl": "https://jtl.integrations.demogmbh.com/lifecycle/connect",
"disconnectUrl": "https://jtl.integrations.demogmbh.com/lifecycle/disconnect"
},
"requirements": {
"minCloudApiVersion": "version12"
},
"capabilities": {
"hub": {
"appLauncher": {
"redirectUrl": "http://localhost:50142/erp"
}
},
"pane": [
{
"context": "productDetail",
"title": "Demo GmbH Product Detail",
"url": "https://jtl.integrations.demogmbh.com/wawi/pane/product/detail",
"matchChildContext": true,
},
{
"context": "customerDetail",
"title": "Demo GmbH Customer Detail",
"url": "https://jtl.integrations.demogmbh.com/wawi/pane/customer/detail",
"matchChildContext": false,
},
],
"erp": {
"headless": {
"url": "http://localhost:50142/erp"
},
"menuItems": [
{
"id": "overview",
"name": "Demo GmbH Overview",
"url": "http://localhost:50142/erp?view=overview"
},
{
"id": "features",
"name": "Demo GmbH Features",
"url": "http://localhost:50142/erp?view=features",
"children": [
{
"id": "features_ai",
"name": "AI",
"children": [
{
"id": "features_ai_image",
"name": "Image generation",
"url": "https://jtl.integrations.demogmbh.com/wawi/pages/features/ai/image"
},
{
"id": "features_ai_text",
"name": "Text generation",
"url": "https://jtl.integrations.demogmbh.com/wawi/pages/features/ai/text"
}
]
}
]
}
],
"tabs": [
{
"context": "productDetail",
"name": "Demo data",
"url": "https://jtl.integrations.demogmbh.com/wawi/tabs/product/detail",
"features": ["details:full", "pricing:write"]
},
{
"context": "customerDetail",
"name": "Demo data",
"url": "https://jtl.integrations.demogmbh.com/wawi/tabs/customer/detail",
"features": ["details:write", "address:read"]
}
],
"api": {
"scopes": ["productRead", "productDelete"]
}
}
}
}