Skip to content

App Manifest

The App Manifest is a JSON configuration file that describes how an app should be integrated into a host application. It contains metadata like the app’s ID, title, icon, route, and other settings that define the app’s behavior within the host application context.

The App Manifest describes the configuration for when the app is to be integrated into another host application. It serves as the integration specification that the yuuvis client CLI uses to correctly configure the app during the integration process.

The manifest file should always be kept consistent with the app’s current configuration to ensure proper integration when the app is published and later integrated into host applications.


The App Manifest is located at the root of your app package with a fixed filename:

your-app/
├── yuv-manifest.json # App Manifest file
├── src/
├── package.json
└── ...

The manifest file is automatically generated by the client CLI when creating a new app.


The manifest file contains the following root-level properties:

PropertyTypeRequiredDescription
idstringYesUnique identifier for the app or extension. Must be unique across all packages in the host application.
titlestringYesDisplay name of the app or extension shown to users.
requiresstring[]NoList of backend application names required for this app to load. Enables conditional activation based on available backend capabilities.
extensionstringConditionalName of the class implementing ClientShellExtension. Required when extension functionality is implemented.
uiobjectConditionalUI configuration for apps with a user interface. Required for apps with UI, must not be present for extensions without UI.

The ui object configures how the app appears and behaves in the host application’s user interface. This section is required for apps with UI and must not be present for extensions without UI.

PropertyTypeRequiredDescription
pathstringYesThe Angular route path where the app will be accessible in the host application.
routesstringYesName of the exported constant containing the app’s Angular route configuration array.
svgIconstringConditionalThe SVG content for the app icon displayed in the sidebar navigation. Either svgIcon or iconName must be provided.
iconNamestringConditionalName of a Material icon to use for the app icon. Either svgIcon or iconName must be provided.
optionsobjectNoAdditional UI behavior options.

The options object within ui provides fine-grained control over the app’s UI behavior:

PropertyTypeRequiredDescription
appClaimstringNoDescriptive text displayed below the app title in the app header. Shows a claim or subtitle for the app.
appClaimKeystringNoTranslation key for the app claim text. If provided, the translated value is used as appClaim.
appHeaderbooleanNoWhether to show the standard app header. Set to true to enable. Default: false.
hideFromNavbooleanNoWhether to hide the app from the sidebar navigation. Set to true to hide the app. Default: false (apps are visible in navigation).

The id uniquely identifies your app or extension. It is used for routing, service registration, and internal references. The ID should be chosen to avoid collisions with any other app, ideally being globally unique.

Guidelines:

  • Use reverse domain notation (e.g., io.yuuvis.app.drive) to ensure global uniqueness
  • Use only lowercase letters, numbers, dots, and hyphens
  • Choose IDs that minimize the risk of collision with apps from other vendors or developers

Example:

"id": "io.yuuvis.app.document-manager"

The title defines the display name shown to users in the sidebar navigation and other UI elements. It can be either a human-readable string or a translation key for internationalization.

Guidelines:

  • Use clear, descriptive names
  • Keep it concise (1-3 words)
  • May be a translation key for internationalization

Example:

"title": "Document Manager"

For internationalization:

"title": "app.document-manager.title"

The requires property specifies backend applications that must be present for this app to load. This enables conditional app activation for client apps that need specific backend capabilities. See the Conditional App Activation guide for more details.

Example:

"requires": ["osdrive", "collaboration"]

This app will only load if both the osdrive and collaboration backend applications are available.

The extension property specifies the name of the class that implements ClientShellExtension. This class is responsible for registering the package’s capabilities with the shell during application initialization.

Requirements:

  • Required for extensions without UI (which always implement extension functionality)
  • Required for apps that implement extension functionality

Example:

"extension": "PdfToolsExtension"

The extension class must implement the ClientShellExtension interface and will be registered in the host application configuration.

The path defines the Angular route under which the app is registered in the host application’s router. This route makes the app accessible in the host application.

Example:

"path": "document-manager"

Users will access this app at https://host-app.example.com/document-manager.

The routes property specifies the name of the exported constant that contains the app’s Angular route configuration. The host application uses this name to import and integrate the app’s routes.

Example:

"routes": "MyappRoutes"

This refers to an exported constant in the app’s library:

// In lib.routes.ts
export const MyappRoutes: Route[] = [
{
path: 'myapp',
component: MyappComponent,
},
];

The host application imports this constant by name to register the app’s routes.

The svgIcon contains the SVG content (not a file path) for the icon displayed in the sidebar navigation. Either svgIcon or iconName must be provided for apps with UI.

Requirements:

  • Provide either svgIcon or iconName (at least one is required)
  • Use inline SVG markup, not a file path

Example:

"svgIcon": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"currentColor\" d=\"M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2Z\"/></svg>"

As an alternative to svgIcon, you can use iconName to specify a Material Symbols icon by name. Either svgIcon or iconName must be provided for apps with UI.

Requirements:

  • Provide either iconName or svgIcon (at least one is required)
  • Use valid Material Symbols icon names

Example:

"iconName": "folder"

The appClaim specifies a descriptive text (claim or subtitle) that is displayed below the app title in the app header. This helps users understand the purpose or context of the app.

Example:

"appClaim": "Document Management System"

For internationalization, use appClaimKey instead (see next section).

The appClaimKey property provides an internationalization-friendly alternative to appClaim. Instead of hardcoding the claim text, you specify a translation key that the shell will resolve based on the user’s language.

Guidelines:

  • Use this for multi-language applications
  • The translation key will be resolved at runtime
  • If the translation key is not found and appClaim is also provided, falls back to appClaim
  • When both appClaimKey and appClaim are provided, the translated value of appClaimKey takes precedence

Example:

"appClaimKey": "app.myapp.claim"

Translation files:

en.json
{
"app.myapp.claim": "Manage your documents efficiently"
}
de.json
{
"app.myapp.claim": "Verwalten Sie Ihre Dokumente effizient"
}

The appHeader option controls whether the standard app header is displayed. By default, the app header is not shown. Set to true to enable it.

Example to enable app header:

"appHeader": true

Note: If not specified, the app header will not be displayed by default.

Controls whether the app appears in the sidebar navigation. By default, apps are visible in the navigation (false). Set to true to hide the app from the sidebar.

Hiding apps from navigation is useful for:

  • Apps that are only accessible through deep links or other apps
  • Utility apps that do not need direct user access

Example to hide the app from navigation:

"hideFromNav": true

Note: If not specified, the app will be visible in the navigation by default.


Here is a complete manifest for an app that provides both a user interface and extension functionality:

{
"id": "io.yuuvis.app.document-manager",
"title": "Document Manager",
"extension": "DocumentManagerExtension",
"ui": {
"path": "document-manager",
"svgIcon": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"currentColor\" d=\"M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2Z\"/></svg>",
"routes": "DocumentManagerRoutes",
"options": {
"appClaim": "Manage and organize documents",
"appHeader": true,
"hideFromNav": false
}
}
}

Here is a manifest for an app that requires specific backend applications to be available:

{
"id": "io.yuuvis.app.drive",
"title": "yuuvis explorer",
"requires": ["osdrive"],
"extension": "AppDriveExtension",
"ui": {
"path": "drive",
"iconName": "cloud_circle",
"routes": "YuuvisDriveRoutes"
}
}

This app will only load if the osdrive backend application is available in the host application. See the Conditional App Activation guide for more details.

Here is a manifest for an extension that provides services but has no user interface:

{
"id": "io.yuuvis.extension.pdf-tools",
"title": "PDF Tools Extension",
"extension": "PdfToolsExtension"
}

Extensions without UI do not have a ui section since they provide no user interface.

Here is a minimal manifest with only required properties:

{
"id": "io.yuuvis.app.simple-viewer",
"title": "Simple Viewer",
"ui": {
"path": "simple-viewer",
"routes": "SimpleViewerRoutes",
"iconName": "visibility"
}
}

When creating or maintaining your App Manifest, follow these best practices:

Keep It Synchronized:

  • Update the manifest whenever you change routes, permissions, or UI configuration
  • Review the manifest before publishing a new version
  • Test integration with a host application to verify the manifest is correct

Validation:

  • Validate your yuv-manifest.json with a JSON schema validator
  • Verify the app appears correctly in the host application after integration