Skip to main content

📦 Plugin Configuration & Deployment

This guide provides a comprehensive overview of how to configure, package, and deploy custom UI plugins. Plugins can either extend the sidebar with new pages or embed components into existing views.

📦 Plugin Packaging

Before uploading, a plugin must be packaged as a .zip archive containing the bundled application and a plugin.config.json manifest file at its root.

🏗️ Archive Structure

Your .zip file must be created from the contents of your dist directory, with plugin.config.json added to the root. The dist folder itself should not be included in the archive.

my-plugin.zip
├── assets/
│ ├── main.js
│ ├── styles.css
│ ├── image.png
│ └── ... (fonts, etc.)
├── index.html
└── plugin.config.json
  • Archive Root: The root must contain your index.html and plugin.config.json.
  • assets/: All other static assets, including JavaScript bundles, CSS files, images, and fonts, must be placed inside this directory.
  • plugin.config.json: This manifest file must be at the root of the archive.

The entryPoint in your configuration must point to an HTML file at the root (e.g., "entryPoint": "index.html").

📄 plugin.config.json Example

Here is a complete example of a plugin.config.json file. It defines a Single Page Application (SPA) with four different resources: two sidebar pages and two embedded components, along with top-level permissions.

{
"dependOn": [],
"resourceType": "SPA",
"version": "1.0.0",
"entryPoint": "index.html",
"permissions": [
{
"groupName": "Home Page",
"resource": "home",
"items": [
{
"name": "write",
"description": "Allow to create products"
}
]
},
{
"groupName": "Products Page",
"resource": "products",
"items": [
{
"name": "read",
"description": "Allow to view products",
"dependOn": [
{
"resource": "home",
"name": "write"
}
]
}
]
}
],
"resourceOutput": [
{
"name": "Home Page",
"resource": "home",
"tags": ["some tag"],
"componentRoute": "/",
"type": "page",
"label": "Home Page",
"styles": {
"height": "100%",
"width": "100%",
"initialBgColor": "white"
}
},
{
"name": "Products Page",
"resource": "products",
"tags": ["some tag"],
"componentRoute": "/products",
"type": "page",
"label": "Products Page",
"styles": {
"height": "100%",
"width": "100%",
"initialBgColor": "white"
}
},
{
"name": "Analytics Dashboard",
"resource": "analytics",
"componentRoute": "/analytics",
"type": "embedded",
"target": "ProjectUsers",
"styles": {
"height": "700px",
"width": "100%",
"initialBgColor": "white"
}
},
{
"name": "User Management",
"resource": "users",
"componentRoute": "/users",
"type": "embedded",
"target": "ProjectUsers",
"styles": {
"height": "1000px",
"width": "100%",
"initialBgColor": "white"
}
}
]
}

📖 Field Reference

This section breaks down the fields in plugin.config.json.

🔝 Top-Level Fields

FieldTypeRequiredDescription
dependOnstring[]NoOptional list of system modules or plugins that must be initialized before this one.
resourceTypestringYesType of the front-end application. Supported values: SPA, STATIC.
versionstringYesThe version of the plugin. Must be a valid semantic version (e.g., 1.0.0).
entryPointstringYesPath to the application's bootstrap HTML file at the archive root. Must match the pattern {name}.html (e.g., index.html, app.html).
permissionsPermissionGroup[]NoTop-level permission groups to register for this plugin. See Permissions.
resourceOutputResource[]YesAn array of resources to register. Must contain at least one item. See Resource Fields.

⚙️ Resource Fields

Each object in the resourceOutput array defines a single resource. The schema is strict — no extra fields are allowed beyond those listed here.

FieldTypeRequiredDescription
resourcestringYesA unique identifier/key for the resource (e.g., "home", "analytics"). Must be unique across all resourceOutput items.
namestringYesThe human-readable display name shown as the plugin title (max 126 characters). Must be unique among all page type resources.
tagsstring[]NoFree-form tags for search and categorization.
componentRoutestringYesThe route within the plugin SPA to mount (e.g., "/", "/products").
type'page' | 'embedded'Yespage adds a sidebar entry; embedded injects the component into a host view.
labelstringNo (only for page)The display name shown in the sidebar navigation (max 126 characters). Only valid on page type.
iconstringNoFilename of the icon asset inside the assets/ directory (e.g., "icon.png"). Valid for both page and embedded types.
target'ProjectUsers' | 'Dashboard'Yes (for embedded)The host surface where the embedded component should appear. Must be unique across all embedded type resources.
stylesobjectYesDefines container styling. Required for all resource types.
styles.heightstringYesContainer height (e.g., "100%", "700px"). Must be a valid CSS value.
styles.widthstringYesContainer width (e.g., "100%"). Must be a valid CSS value.
styles.initialBgColorstringNoBackground color shown during plugin load to prevent content flashing (e.g., "white", "#fff").

🔑 Permissions Object

Permissions are defined at the top level of plugin.config.json as an array of permission groups. Each group is linked to a resource by its resource identifier.

Permission Group (permissions[]):

FieldTypeRequiredDescription
groupNamestringYesA human-readable label for this permission group.
resourcestringYesThe resource identifier this group applies to (must match a resource in resourceOutput).
itemsPermissionItem[]YesAt least one permission item must be defined.

Permission Item (permissions[].items[]):

FieldTypeRequiredDescription
namestringYesThe permission name (e.g., "read", "write").
descriptionstringYesA user-friendly description of what the permission allows.
dependOnPermissionDependency[]NoAn optional list of permissions from other resources that this permission requires.

Permission Dependency (permissions[].items[].dependOn[]):

FieldTypeRequiredDescription
resourcestringYesThe resource identifier of the dependency.
namestringYesThe permission name on that resource that must be granted first.

✅ Validation Rules

The config is validated strictly — unknown fields cause validation failure. Key rules:

  • version must be a valid semver string (e.g., 1.0.0, 2.1.3-beta.1).
  • entryPoint must match {name}.html and the referenced file must exist in the archive.
  • resourceOutput must contain at least one item.
  • Each resource value across all resourceOutput items must be unique.
  • Each name value across all page type items must be unique.
  • Each target value across all embedded type items must be unique.
  • styles.height and styles.width must be valid CSS values.
  • No additional fields beyond those listed above are permitted in any object.

🚀 Deployment & Validation

After packaging your plugin into a .zip archive, you can deploy it through the UI.

  1. Upload & Validate: Begin by uploading your .zip archive. The system automatically validates the package structure and the plugin.config.json manifest.

    Plugin Start Validation

  2. Review & Process:

    • On Success: If validation passes, you will see a preview of the parsed plugin.config.json. Review the resources to be created or updated. Click Start Processing to proceed. All resources will be pushed to a processing queue. New resources will be created, while existing resources will be moved to an UPDATING stage.

      Successful Plugin Validation

    • On Error: If validation fails, an error message will detail the specific issues. You must correct the errors in your package and re-upload it.

      Plugin Validation Error


Happy coding! If you run into any issues, please check your ZIP structure (entry-point HTML at root) and ensure your front-end supports any hash routes you've configured.

💡 Business Case

Business case — Custom Analytics Dashboard

Imagine your organization needs a custom analytics dashboard inside the iXR platform to visualize VR training performance metrics.

  • Using the Plugin Configuration, your dev team builds a plugin that connects to your own analytics API.
  • By choosing Page as the plugin type, it appears in the iXR sidebar as a dedicated Analytics section.
  • Trainers can filter sessions, track completion rates, and export reports — all inside the iXR UI without switching tools.
  • If the dashboard layout changes, you can simply upload a new plugin bundle, and the update goes live without redeploying the core platform.

Benefits

  • Gives stakeholders real-time insights without leaving iXR.
  • Enables teams to roll out new visualization features quickly.
  • Reduces reliance on external dashboards and context switching.