Building apps (app.yml)
MintJams CMS is a platform. Using the same mechanism as the standard apps, you can add your team's own apps to the virtual desktop (Webtop). All you need is HTML / JavaScript (or TypeScript) and an app definition, app.yml.
Where apps live & how they're discovered
Apps live under the Webtop's apps/<app-name>/. Each app folder contains:
apps/my-app/
├── app.yml # app definition (metadata)
├── index.html # entry point
├── app.ts # app logic (ichigojs) → built to app.js
└── assets/ # icons, CSS, etc.
├── css/style.css
└── icons/icon.svg
The server discovers app.yml and lists the app (the GraphQL apps query). The list appears in the desktop menu; isAdminOnly apps show only to admins.
app.yml
identifier: 12345678-1234-5678-1234-567812345678 # unique UUID
title: My App # display name
icon: assets/icons/icon.svg # icon (relative path)
actions:
open:
icon: open
label: Open
minimumWidth: 480 # minimum window width (px)
minimumHeight: 480 # minimum window height (px)
customWindowControls: true # render minimize/maximize/close yourself
Main fields:
| Field | Meaning |
|---|---|
identifier |
unique app ID (UUID) |
title |
name shown on the desktop, Dock and window |
icon |
icon (SVG recommended, relative to the app folder) |
editor |
true registers the app as an "editor" for its contentTypes (appears in Content Browser's "Open with") |
contentTypes |
MIME types it can edit (when editor: true), e.g. ['text/*', 'application/json'] |
isAdminOnly |
true shows it only to admins |
singleton |
true allows only one instance (relaunch focuses the existing window) |
minimumWidth / minimumHeight |
minimum window size (px) |
customWindowControls |
true renders window controls yourself |
actions.<id>.{icon,label} |
actions exposed in menus (the standard one is open) |
App boot sequence
index.html loads the design-system CSS and mounts the root element. In app.ts you create an ichigojs app and receive the ApplicationInstance the shell passes in.
import { VDOM } from '@mintjamsinc/ichigojs';
const App = {
data() { return { instance: null, greeting: 'Hello, World!' }; },
methods: {
onMounted() {
const vm = this;
window.appLaunch = async (instance) => {
vm.instance = vm.\$markRaw(instance);
instance.windowTitle = 'My App';
instance.notifyLaunched(); // tell the shell we're ready
};
}
}
};
VDOM.createApp(App).mount('#app');
The shell calls window.appLaunch when the window opens. instance.notifyLaunched() clears the loading state.
Platform integration
Through instance you can use the platform's capabilities:
- Content / JCR — get, create, update and delete nodes via GraphQL
- Identity / Preferences / i18n — the current user, locale and messages
- Theme —
document.documentElement.dataset.themefollows light/dark - Events — subscribe to content changes and job progress
- Window — title, display info, minimize/maximize, before-close callback
Theme & design system
Apps load the shared design-system CSS (webtop-app.css) and match the standard look via CSS custom properties (--primary-color, --body-bg, --text-color, …). The shell switches the theme (light/dark) and it flows through the CSS variables automatically. Bootstrap Icons are available (<i class="bi bi-...">).
Steps to a minimal app
- Create
apps/my-app/withapp.yml,index.html,app.ts,assets/ - Set a unique
identifierand atitleinapp.yml - Load the design-system CSS in
index.htmland mount#app - Implement
appLaunchinapp.tsand callnotifyLaunched() - Build, then reload the desktop — your app appears in the menu
Localization
Put UI strings in i18n bundles (app.<appId>.*) and reference them in templates as t('app.my-app.greeting', undefined, 'Hello'). See "Localization & i18n".
For deeper server-side extensions, OSGi bundles are available too. See "OSGi extensions & BPM/EIP".