Skip to main content
Subnav links allow you to embed external pages or applications directly into the Kibo Admin UI navigation. They are registered as entities in the subnavlinks@mozu entity list. Make a POST request to the entity list endpoint:
POST /api/platform/entitylists/subnavlinks@mozu/entities

Request Payload

{
    "path": [
        "Parent",
        "Child"
    ],
    "href": "{{your URL here}}",
    "windowTitle": "Custom Interface",
    "modalWindowTitle": "Subnav Link Title",
    "location": "ordermenu",
    "displayMode": "modal",
    "appId": "{{application ID}}",
    "badgeInitials": "CT",
    "requiredContext": "products"
}

Field Descriptions

FieldDescription
pathArray of strings defining the menu label. Use multiple elements for nested menus (e.g. ["Parent", "Child"]).
hrefThe URL of your external application that will be rendered in the modal.
windowTitleStatic title shown in the modal window itself.
modalWindowTitleStatic title shown in the Kibo Admin sidebar menu.
locationWhere in the Kibo Admin UI the link appears. See full list below.
displayModeSet to "modal" (static value).
appIdThe ID of an application installed on the tenant. Find it in Admin at System > Customizations > Applications — the app ID is visible in the page URL.
badgeInitialsShort label/initials badge shown in the menu. Must be unique.
requiredContext(Optional) Context scope (e.g. "products"). Used for edit-page subnav links.

Available location Values

These control where in the Admin UI the subnav link will appear:
ValueUI Section
productsmenuProducts menu
marketingmenuMarketing menu
searchmenuSearch menu
contentmenuContent menu
publishingmenuPublishing menu
ordermenuOrders menu
fulfillerFulfiller
orderRoutingOrder Routing
customermenuCustomers menu
b2baccountmenuB2B Accounts menu
reportmenuReports menu
settingsmenuSettings menu
schemamenuSchema menu
customizationmenuCustomizations menu
structuremenuStructure menu
permissionsmenuPermissions menu
localizationmenuLocalization menu
productseditProduct edit page (requires requiredContext: "products")
Note: Additions to productsmenu require a hard refresh to display. Other locations such as categoriesedit or productsedit appear after a single refresh.

How Requests Are Delivered to Your Application

When a user clicks a subnav link in Admin, Kibo makes a POST request to your configured href URL. The request includes:

Query Parameters

ParamDescription
dtThe date/time of the request (e.g. Fri, 29 Nov 2024 19:49:10 GMT)
messageHashHMAC-SHA256 hash used to verify request authenticity

POST Body (form-encoded)

FieldDescription
x-vol-return-urlThe Admin URL to return to
x-vol-tenantTenant ID
x-vol-master-catalogMaster Catalog ID
x-vol-catalogCatalog ID
x-vol-siteSite ID
userIdID of the Admin user who clicked the link

Verifying Request Authenticity

Use the dt and messageHash query parameters to confirm the request genuinely came from Kibo Admin. The following Node.js example shows the verification algorithm:
const crypto = require("crypto");

var appKey       = "YOUR.APP.KEY";
var appSecret    = "{{appSecret}}";      // From your app credentials
var receivedHash = "{{messageHash}}";    // From query param
var receivedDate = "{{dt}}";             // From query param
var rawContent   = "{{postBody}}";       // Raw POST body string

// Step 1: Concatenate the app secret with itself
var concatenated1 = appSecret + appSecret;

// Step 2: SHA-256 hash the concatenated secret, then Base64-encode it
var hash1 = crypto.createHash("sha256").update(concatenated1).digest("base64");

// Step 3: Concatenate hash1 + receivedDate + rawPostBody
var concatenated2 = hash1 + receivedDate + rawContent;

// Step 4: SHA-256 hash the second concatenation, then Base64-encode it
var generatedHash = crypto.createHash("sha256").update(concatenated2).digest("base64");

// Step 5: Compare — matching means the request is authentic
if (generatedHash === receivedHash) {
    console.log("Match! Request is authentic.");
}
Your appSecret comes from the application registered in Kibo. The appId in the subnav link payload must match that same application. Via API:
GET /api/platform/entitylists/subnavlinks@mozu/entities
Via Admin UI:
  1. Go to System > Schema > Custom Schema.
  2. Open Dev Tools and run: Ext.util.Cookies.set('debugext', true)
  3. Press Enter and refresh the page.
  4. Under Entity Lists, find subnavlinks to view or delete entries.

Example Demos

A reference implementation (Express server + Next.js) is available at github.com/KiboPartners/subnavlink-demos.