Skip to content

API ​

This page organizes the extension API by UI contributions, injected objects, host data, and host actions.

Registration Entry ​

After the entry script loads, it must call:

js
window.registerExtension(factory, token);

token comes from:

js
const token = document.currentScript?.dataset?.extensionToken || "";

Minimal template:

js
(function registerMyExtension(factory) {
  const token = document.currentScript?.dataset?.extensionToken || "";

  if (!token) {
    throw new Error("Missing extension activation token");
  }

  window.registerExtension(factory, token);
})(function (api) {
  return {};
});

UI Contributions ​

The object returned by factory(api) may declare the following UI contributions.

homeWidget ​

Single home card.

FieldTypeRequiredDescription
titlestringyescard title
ComponentReact.ComponentTypeyescard component
descriptionstringnocard description
iconstringnoicon field
keystringnokey for multi-card extensions
defaultWidthnumbernodefault width
minWidthnumbernominimum width
maxWidthnumbernomaximum width

homeWidgets ​

Multiple home cards, typed as homeWidget[].

settingsPage ​

Extension settings page.

FieldTypeRequiredDescription
ComponentReact.ComponentTypeyessettings page component

Route:

text
/settings/extension/<identifier>

page ​

Single extension page.

FieldTypeRequiredDescription
routePathstringyesextension-internal route
ComponentReact.ComponentTypeyespage component
isStandAlonebooleannowhether the page is standalone

General route:

text
/extension/<identifier>/<routePath>

Standalone route:

text
/standalone/extension/<identifier>/<routePath>

pages ​

Multiple extension pages, typed as page[].

customModal ​

Single extension-defined modal. The host renders it inside a Chakra UI Modal, with the component mounted in ModalBody.

FieldTypeRequiredDescription
keystringyesunique modal key within the current extension; must be non-empty and must not contain :
titlestringyesmodal title
ComponentReact.ComponentType<{ params?: any; close: () => void; }>yesmodal content component
paramsanynodefault params; can be overridden by openCustomModal
other fieldsOmit<ModalProps, "children" | "isOpen">noprops forwarded to Chakra UI Modal, such as size, closeOnOverlayClick, and motionPreset

The component receives:

ts
{
  params?: any;
  close: () => void;
}

customModals ​

Multiple extension-defined modals, typed as customModal[].

slots ​

Registers action items into host-provided UI slots. All current slots extend item menus on instance detail pages.

Base shape:

ts
slots: {
  [slotKey]: {
    getItems: (context) => Array<{
      icon: string | IconType;
      label?: string;
      onClick?: MouseEventHandler<HTMLButtonElement>;
      danger?: boolean;
    }>;
  };
}

Notes:

  • Only known slot keys are accepted by the host; unknown keys are ignored.
  • getItems(context) returns the extra button items for the current context.
  • icon may be an icon asset string or a react-icons IconType.
  • When danger is true, the host renders the item with danger styling.

Currently supported slot keys and contexts:

Slot KeyExtra context Fields
ui.instance.world.item_menu_operationssave: WorldInfo
ui.instance.server.item_menu_operationsserver: GameServerInfo
ui.instance.mod.item_menu_operationsmod: LocalModInfo
ui.instance.resourcepack.item_menu_operationspack: ResourcePackInfo
ui.instance.server_resourcepack.item_menu_operationspack: ResourcePackInfo
ui.instance.schematic.item_menu_operationsschematic: SchematicInfo
ui.instance.shaderpack.item_menu_operationspack: ShaderPackInfo

Every slot context also includes this base payload:

ts
{
  instanceId: string | undefined;
  summary: InstanceSummary | undefined;
}

dispose ​

Cleanup function called during deactivation.

Injected Objects ​

The factory argument is api. It includes the following injected objects.

api.React ​

The host React runtime.

js
const React = api.React;

api.ChakraUI ​

The host Chakra UI bundle.

js
const { Box, Button, Text, VStack } = api.ChakraUI;

api.Components ​

Host business components.

FieldDescription
OptionItemoption card component
OptionItemGroupoption group component
Sectionpage section container
WrapCardcard component
WrapCardGroupcard group component

api.identifier ​

Extension identifier.

api.resolveAssetUrl(path) ​

Resolves an extension-relative path to an asset URL.

path is relative to the extension root, not to the current script file. For example, if the extension contains assets/video.mp4, the argument is "assets/video.mp4".

js
const videoUrl = api.resolveAssetUrl("assets/video.mp4");

Host ​

This section describes the host entry points injected into the extension runtime. The host context provides state abilities, action abilities, and reactive host-owned data.

api.getHostContext() ​

Returns the host context object:

ts
{
  actions: ExtensionAbilityActions;
  state: {
    useExtensionState: <T>(key: string, initialValue: T) => [T, SetState<T>];
  };
}

Common usage:

js
const host = api.getHostContext();

api.useHostData() ​

A React Hook for reading host data. The returned value is maintained by the host, and the component receives updated snapshots when players, instances, config, or route parameters change.

js
const hostData = api.useHostData();

The detailed fields are listed below.

Host Data ​

api.useHostData() returns a read-only snapshot exposed by the launcher. It is used to render UI, branch on launcher state, and react to changes in host-owned data.

api.useHostData() returns:

FieldTypeDescription
configLauncherConfiglauncher configuration
selectedPlayerPlayer | undefinedselected player
selectedInstanceInstanceSummary | undefinedselected instance
playerListPlayer[]player list
instanceListInstanceSummary[]instance list
routeQueryRecord<string, string | string[] | undefined>current route query

Host State ​

host.state.useExtensionState(key, initialValue) ​

Extension-scoped state hook, similar to useState in React development.

js
const host = api.getHostContext();
const [count, setCount] = host.state.useExtensionState("count", 0);

The state is stored by the launcher host under the extension scope.

Host Actions ​

host.actions exposes host-implemented abilities to the extension. These methods are used for config updates, navigation, file access, network requests, and extension reload.

getPlayerList ​

Gets the player list.

ts
const players = host.actions.getPlayerList(sync?: boolean);

getInstanceList ​

Gets the instance list.

ts
const instances = host.actions.getInstanceList(sync?: boolean);

updateConfig ​

Updates the value at a config path.

ts
host.actions.updateConfig(path: string, value: any);

Navigates within the route scope allowed for the extension.

ts
await host.actions.navigate(route: string);

Requests a single history back navigation from the host.

ts
host.actions.navBack();

openWindow ​

Opens a standalone window for the given route.

ts
host.actions.openWindow(route: string, title: string);

Requests the host to open an external link.

ts
await host.actions.openExternalLink(url: string);

openSharedModal ​

Opens a shared host modal.

ts
host.actions.openSharedModal(key: string, params?: any);

openCustomModal ​

Opens a custom modal registered by the current extension.

ts
host.actions.openCustomModal(key: string, params?: any);

key must match a modal declared in customModal or customModals, and can only target the current extension.

setHomeWidgetTitle 1.1.0 ​

Updates a home widget title.

ts
host.actions.setHomeWidgetTitle(title: string, key?: string);

If the extension declares multiple home widgets, pass key to target a specific one; omit key for the single home widget case.

readFile ​

Reads a file from the extension data/ directory.

ts
const content = await host.actions.readFile(
  path: string,
  mode?: "string" | "base64"
);

The default mode is "string". Use "base64" for binary content.

writeFile ​

Writes content into a file under the extension data/ directory.

ts
await host.actions.writeFile(
  path: string,
  content: string,
  mode?: "string" | "base64"
);

The default mode is "string". Use "base64" when writing binary content.

deleteFile ​

Deletes a file under the extension data/ directory.

ts
await host.actions.deleteFile(path: string);

deleteDirectory ​

Deletes a directory under the extension data/ directory.

ts
await host.actions.deleteDirectory(path: string);

request ​

Performs an HTTP request and returns a response object.

ts
const response = await host.actions.request(
  input: URL | Request | string,
  init?: RequestInit
);

requestText ​

Requests text content and decodes it with the given encoding.

ts
const text = await host.actions.requestText(
  url: string,
  init?: RequestInit,
  encoding?: string
);

invoke ​

Calls a host command and returns its result.

ts
const result = await host.actions.invoke<T = unknown>(
  command: string,
  payload?: Record<string, unknown>
);

Example ​

Get the currently selected instance ID and read options.txt from that instance root directory:

js
const host = api.getHostContext();
const hostData = api.useHostData();

async function readSelectedInstanceOptions() {
  const instanceId = hostData.selectedInstance?.id;
  if (!instanceId) {
    throw new Error("No selected instance");
  }

  const optionsText = await host.actions.invoke("read_instance_file", {
    instanceId,
    dirType: "Root",
    path: "options.txt",
    mode: "string",
  });

  return optionsText;
}

dirType: "Root" targets the instance root directory. To read from mods, resourcepacks, and other subdirectories, pass the corresponding InstanceSubdirType value.

logger ​

Accesses the host logger.

ts
host.actions.logger.info("extension log");

reloadSelf ​

Reloads the extension.

ts
host.actions.reloadSelf();

updateSelf ​

Requests the host to download an updated extension package and prompt for installation.

ts
await host.actions.updateSelf(src: string, newVersion: string);