Use this file to discover all available pages before exploring further.
This guide covers the two systems that control how your Cloud App renders and communicates inside the JTL platform:
Manifest: Configuration document with two sections. The manifest section defines lifecycle hooks, capabilities, and API scopes. The listing section defines name, description, icons, legal URLs, and support links shown in the JTL Hub and App Store.
AppBridge: Runtime SDK that enables bidirectional communication between your app (in an iframe) and the host environment (JTL Hub or ERP Cloud).
Platform UI: React component library for building interfaces that match JTL’s design system.
The manifest is a JSON document that defines your app. It has two sections that work together: manifest for technical runtime configuration, and listing for the marketing content shown in the App Store and JTL Hub. You need both to deploy an app through the Partner Portal.
The lifecycle object defines URLs JTL calls during installation, connection, and removal of your app.
Property
Type
Required
Description
lifecycle.configurationUrl
string
No
URL rendered in an iframe during initial setup or onboarding. Use this to present UI, confirm the connection, or collect any required configuration from the merchant.
lifecycle.connectUrl
string
No
URL called when JTL establishes a connection. Handle your OAuth callback or credential exchange here, and persist any tokens or identifiers required for future API calls.
lifecycle.disconnectUrl
string
No
URL called when the app is uninstalled. Use this to revoke access, delete stored credentials, and clean up any tenant-specific data.
All three URLs must be standard http:// or https:// URLs and are validated against the pattern ^https?:\/\/(?:[^{}\s]|\{\s*metadata\.[a-zA-Z0-9_-]+\s*})+$ when you register your manifest.Typical Flow
Merchant installs your app → configurationUrl (optional onboarding UI)
JTL establishes a connection → connectUrl
Merchant uninstalls your app → disconnectUrl
Identifying the AppThe lifecycle URLs are often the only reliable signal your handlers have about which app a request belongs to.If you publish multiple apps and they share the same configurationUrl, connectUrl, or disconnectUrl, your handlers cannot determine which manifest a request belongs to.
For configurationUrl, the wrong setup UI may be rendered.
For connectUrl, credentials may be registered against the wrong app.
For disconnectUrl, tokens and tenant data may be revoked for the wrong app.
Each app should have a unique, identifiable URL for every lifecycle endpoint.Give each app a distinct URL, either by using separate routes:
Both approaches are valid. Use separate routes if you control routing and want cleaner URLs. Use query parameters if you prefer a single handler that switches behavior dynamically.What matters is that the URL itself carries enough context for your backend to know which app it’s serving.
A working configuration flow is provided when you use the CLI npm create @jtl-software/cloud-app@latest to create a new app.
Capabilities define where and how your app integrates with JTL. Each key under capabilities maps to a specific surface. See Architecture Overview for a full description of each integration type.HubControls how the app appears in the JTL Hub dashboard. When a merchant clicks the app’s card, the platform redirects to this URL.
Property
Type
Required
Description
capabilities.hub.appLauncher.redirectUrl
string
Required if hub is present
URL the system redirects to when the app card is clicked in the Hub
Without a redirectUrl, the app card has no destination.ERP: Menu ItemsAdd entries to the ERP Cloud sidebar under the App section. Each menu item links to a page in your app loaded inside the ERP iframe.
Property
Type
Required
Description
id
string
Yes
Stable internal identifier for the menu item
name
string
Yes
Display name shown in the navigation
url
string
Yes
URL loaded when the item is clicked
ERP: API ScopesDeclare which JTL-Wawi API resources your app needs. Scopes are displayed and granted at install time.
Property
Type
Required
Description
capabilities.erp.api.scopes
array of string
No
API permission scopes required by the app
The platform accepts only 41 specific scope values. Any value outside this list is rejected at registration.A subset for reference:
The listing section holds the marketing content shown to merchants in the App Store and JTL Hub: localized names and descriptions, icons, support URLs, and legal links.
The example below shows both sections together: a manifest declaring Hub redirect, one ERP menu item, three API scopes, and one pane scoped to the orders view, alongside a listing covering the German locale.
The AppBridge is provided by the @jtl-software/cloud-apps-core package. It establishes a secure communication channel between your app’s frontend (running in an iframe) and the host JTL environment (JTL Hub or ERP Cloud).The bridge allows your app to request data (like session tokens) and call host methods. Publish/subscribe event handling is in development (see below).
Initialize the AppBridge before rendering your React app, then pass the instance as a prop or store it in context:
import { createAppBridge } from '@jtl-software/cloud-apps-core';import { createRoot } from 'react-dom/client';createAppBridge().then((appBridge) => { createRoot(document.getElementById('root')!).render( <StrictMode> <App appBridge={appBridge} /> </StrictMode>, );});
What this does: Calls createAppBridge() to establish the iframe-to-host connection, waits for the bridge to be ready, then passes it to your app as a prop. This guarantees the communication channel is open before any component tries to use it.
Do not initialize the AppBridge inside a component (e.g., in useEffect).
This can cause race conditions where components render before the bridge is
ready. Always initialize it at the application entry point.
For Next.js apps that need SSR compatibility, use a dynamic import inside a
client-side provider instead. See the From Scratch
Quickstart for the
full pattern.
You can use AppBridge in any JavaScript frontend framework, including React,
Vue, and Angular.
The AppBridge creates a two-way channel: your app’s appBridge instance communicates with a corresponding hostAppBridge instance inside the JTL Cloud service.All communication is asynchronous and non-blocking. Your app continues executing while messages are delivered between the iframe and the host. There are no HTTP requests or polling involved.
The AppBridge provides two main interfaces: methods (expose/call) and events (publish/subscribe).
Methods
Events
AppBridge methods provide a request/response channel between your app and the host. There are two directions:
Call host methods (available today): your app invokes functions the host exposes, like getSessionToken. See Environment-specific Methods for the full list.
Expose methods to the host (in development): your app registers functions that the host can invoke by name, used for things like custom calculations or data lookups.
In development:method.expose and method.isExposed are in active development and not yet available. This section will be updated when the API ships.
Once available, exposing methods will let the host invoke logic that lives in your app. For example, a calculateShippingCost function the ERP calls before showing a quote, or a validateOrder hook called before checkout. The shape will follow a name + handler registration pattern with a disposer for cleanup, mirroring the event subscription model.
The table marks which APIs are available today and which are planned.
Method
Status
Description
method.call(name, ...args)
Available
Call a host method. Returns Promise<T>.
method.expose(name, fn)
In development
Register a function the host can call by name.
method.isExposed(name)
In development
Check whether a method is already registered.
In development: AppBridge publish/subscribe events are in development and not yet available. This section will be updated when the API ships.
AppBridge events will provide two capabilities:
event.subscribe: listen for events emitted by the host (for example, inventory:updated when a merchant changes stock elsewhere in the ERP).
event.publish: send events to the host so it can react to actions your app completes (for example, order:verification:complete).
Topics will follow a resource:action naming convention so intent is clear from the name alone. Payloads will be small by design (IDs and changed values), not full objects.
JTL exposes different built-in methods depending on which environment your app is running in.
Setup Environment (JTL Hub)
ERP Environment (ERP Cloud)
These methods are available when your app loads via the lifecycle.configurationUrl during installation:
Method
Parameters
Returns
Description
getSessionToken
None
Promise<string>
Returns the current session token (contains user and tenant info)
setupCompleted
None
Promise<void>
Signals that setup is done and activates the app in the Hub
These methods are available when your app runs inside the ERP (via menu items, tabs, or panes):
Method
Parameters
Returns
Description
getSessionToken
None
Promise<string>
Returns the current session token
getCurrentTime
None
Promise<Date>
Returns the current time as a Date object
getSessionToken is available in both environments. It’s the primary way your frontend identifies the current user and tenant. For details on verifying session tokens on your backend, see Authentication & Login.
JTL provides a React component library that matches the platform’s design system. Using these components ensures your app looks and feels consistent with the rest of the JTL interface.