Extension quickstart¶
This example adds one API 2 page at /acme-inventory. Replace the sample
identity with the permanent ID assigned to your partner application.
1. Register a provider¶
In the partner app's hooks.py, declare Yukon and the manifest provider:
required_apps = ["yukon_crm"]
yukon_extensions = ["acme_inventory.extension.get_manifest"]
export_python_type_annotations = True
require_type_annotated_api_methods = True
2. Return a deterministic manifest¶
from __future__ import annotations
from typing import Any
def get_manifest() -> dict[str, Any]:
return {
"id": "acme_inventory",
"title": "Acme Inventory",
"version": "0.1.0",
"api_version": "2",
"description": "Show approved inventory context inside Yukon.",
"publisher": "Acme Systems",
"maturity": "beta",
"entrypoint": "/assets/acme_inventory/extension.mjs?v=0.1.0",
"required_roles": ["Acme Inventory User"],
"navigation": [
{
"key": "home",
"label": "Inventory",
"path": "/acme-inventory",
"icon": "package",
"order": 80,
}
],
}
The provider must be side-effect free. Do not call a remote service, write records, or depend on the current browser while returning the manifest.
The sample also assumes the application ships an app-owned Acme Inventory User role and assigns it to the intended users. Do not remove the role filter merely to make the navigation appear.
3. Activate the page¶
function createPage(context) {
const { h } = context.ui
return {
name: 'AcmeInventoryHome',
setup() {
return () => h('section', { class: 'page' }, [
h('header', { class: 'page-header' }, [
h('div', null, [
h('h1', null, 'Inventory'),
h('p', null, 'Approved inventory context for this workspace.'),
]),
]),
])
},
}
}
export function activate(context) {
context.registerRoute({
path: '/acme-inventory',
name: 'acme_inventory.home',
component: createPage(context),
})
}
Build the Frappe assets, migrate the test site, and enable the beta extension from Yukon's Extensions settings. Verify it with a user who holds the declared role and with one who does not.
Continue with the manifest and frontend contract.