Skip to main content
Both styles work; the default export is the namespace.

Ids

Ids you choose are local to your expansion. pages.register('home', …) registers my_expansion.home, so two expansions can both have a home page. The qualified id is what the call returns, and what appears in routes. Local ids are letters, digits, _ and -.

About

pages

Registers a page. Open it with a sidebar button or useNavigate().page(id). It renders at /project/<projectId>/custom/<expansionId>.<pageId>.
Adds a button to the project sidebar that opens one of your pages.
  • page is a page id you passed to pages.register.
  • icon is a Lucide icon name such as 'Star', or an imported image. Defaults to a puzzle piece.
  • label defaults to your expansion’s name.
Users can reorder or hide it like any built-in button.

injections

Renders a component inside an existing app screen. Returns a function that removes it. Slots today, all in the item editor:
The component receives injectionContext (for the item editor: { data, projectId }), injectionMetadata, slotId and expansionId. Lower order renders first; the default is 100.

editors

A full editor for a kind of item, and the mapping that makes items of elementType open in it. The component receives itemId, itemData, content, setContent and readItems.

creators

Adds an entry to the Create menu. metadata may carry label, icon, description and compatibility.

items

Registers a new item type for the browser. Type ids are written into project files, so they are not prefixed with your expansion id, and registering one that already exists is refused. config.editor names one of your editors; displayName, svgIcon and tabIcon control how items appear.

modules

Adds a module to the item editor. With component, your component renders it; without, type selects a built-in input.

settings

Adds a tab to app or project settings. A section is { id, title, description?, icon?, elements }, where elements are the app’s settings elements (text, checkbox, dropdown, slider, static-text, …). Element ids are namespaced with your expansion id automatically.

theme

setVariables sets CSS variables on the app. addStyle adds a stylesheet that is not scoped to your expansion, for when you deliberately want to restyle the app; both are undone when your expansion unloads. For styling your own UI, import a CSS file instead: it is scoped for you.

i18n

Registers a UI language, e.g. { local: 'es', label: 'Español', translations: { … } }.

events

Listen to what the user does, or send your own event. Any number of listeners per event, including several from one expansion; each on returns its own unsubscribe, and all of them are removed when your expansion unloads. Events the app fires:
emit reaches every expansion, including legacy ones, so it is also how two of your own expansions talk to each other. Namespace your own events, e.g. my_expansion:thing-happened.

project

  • current() is the open project’s id, or null outside a project.
  • items() returns the project’s items as an array.
  • readFile returns { success, data, parsed, error }: data is the text, parsed is the value for .json/.yml files.
  • writeFile returns { success, error }. fileName is a path inside the project folder; subfolders are created as needed and paths cannot escape the project.
  • updateItem applies changes to the item’s YAML at path.
Without the permission, these throw SdkPermissionError and the refusal is logged.

clipboard

notify and log

notify shows a toast. log writes to your expansion’s log, visible on the Expansions page, and to devtools. Plain console.* inside your expansion goes to the same place.

Expansion

The optional base class for a class-based expansion.

Errors

Thrown when a call needs a permission your meta.json does not declare.

Not available yet