Skip to content
Last updated Give Feedback

Plugin Settings

If your plugin needs configuration (API keys, toggles, URLs), define a settingsSchema in your manifest. ecommus will auto-generate a settings form in the admin panel — no custom React components needed.

Add settingsSchema to the "ecommus" section of your package.json:

{
"ecommus": {
"name": "my-plugin",
"settingsSchema": {
"apiKey": {
"label": "API Key",
"type": "password",
"required": true,
"description": "Your API key from the provider dashboard"
},
"mode": {
"label": "Mode",
"type": "select",
"options": [
{ "label": "Sandbox", "value": "sandbox" },
{ "label": "Production", "value": "production" }
],
"default": "sandbox"
},
"retries": {
"label": "Max Retries",
"type": "number",
"default": 3
},
"enabled": {
"label": "Enable Plugin",
"type": "boolean",
"default": true
}
}
}
}
TypeUI ControlDescription
stringText inputPlain text value
passwordPassword input (with show/hide toggle)Sensitive values, stored as-is
numberNumber inputInteger or float
booleanCheckboxTrue/false toggle
selectDropdownRequires options array
textareaMulti-line textFor longer text (HTML, JSON, etc.)
interface SettingsField {
label: string;
type: "string" | "password" | "number" | "boolean" | "select" | "textarea";
description?: string;
default?: unknown;
required?: boolean;
placeholder?: string;
options?: Array<{ label: string; value: string }>; // only for 'select'
}

Once your plugin is loaded, the settings page is available at:

/admin/integrations/<plugin-name>/settings

The form is built automatically from the settingsSchema. On save, values are stored in the settings table with the key plugin:<plugin-name>:settings, scoped per tenant.

const init: PluginInit = async (ctx) => {
ctx.registerHook("order.paid", async (event) => {
const row = await ctx.db.query.settings.findFirst({
where: (s, { and, eq }) =>
and(
eq(s.tenantId, event.tenantId),
eq(s.key, `plugin:${ctx.name}:settings`)
),
});
const settings = (row?.value as Record<string, unknown>) ?? {};
const apiKey = settings.apiKey as string | undefined;
if (!apiKey) {
ctx.logger.warn("Plugin not configured — skipping");
return;
}
// Use apiKey...
});
};

The settings are exposed via the admin API:

GET /api/admin/plugins → list all plugins with schemas
GET /api/admin/plugins/:name/settings → get current settings (tenant-scoped)
PUT /api/admin/plugins/:name/settings → save settings (JSON body)

Authentication: Authorization: Bearer <admin-jwt> + X-Tenant-Id: <tenantId>