Skip to content

Installing plugins

Administrators can install sandboxed plugins from the plugin registry or register npm packages in astro.config.mjs. Config-based plugins can run in the sandbox or in the site process.

Registry installs require:

  • An administrator account with the plugins:manage permission.
  • Configured storage for downloaded plugin bundles.
  • An available sandbox runner.

On Cloudflare Workers, use sandbox() from @emdash-cms/cloudflare:

astro.config.mjs
import { sandbox } from "@emdash-cms/cloudflare";
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
sandboxRunner: sandbox(),
}),
],
});

The Cloudflare runner uses Worker Loader to create a separate Worker for each plugin. It requires the Workers Paid plan and a worker_loaders binding named LOADER. Sandboxed plugins reach content, media, storage, network, and email APIs through PluginBridge, so the site’s Worker entry point must export that class.

The *-cloudflare templates export PluginBridge but leave the Worker Loader binding commented out, so new projects can deploy on the Workers free plan. Enable sandboxed plugins during scaffolding or follow the Cloudflare sandbox setup to add the binding later. The sandbox() helper reads the effective Wrangler config at build time. Without LOADER, registry browsing remains available, but config-managed sandboxed plugins do not load and install or update requests return SANDBOX_NOT_AVAILABLE.

On Node.js, install the runner and its workerd peer dependency:

Terminal window
npm install @emdash-cms/sandbox-workerd workerd

The workerd process runs the plugin code separately from the Node.js server. Select the runner in the EmDash integration:

astro.config.mjs
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
sandboxRunner: "@emdash-cms/sandbox-workerd/sandbox",
}),
],
});

See Plugin sandbox for development setup, runtime requirements, resource limits, and unavailable-runner errors on both platforms.

  1. Open Registry in the admin panel.
  2. Search for a plugin and open its detail page.
  3. Select a release and review its publisher, metadata, requested permissions, and verification status.
  4. Select Install.
  5. Review the verified release identifiers and permissions in the consent dialog, then confirm.

EmDash verifies the publisher’s current signed records and checks the downloaded bundle before loading it through the sandbox runner. The plugin appears under Plugins, where you can disable or configure it. See The plugin registry for the complete verification and trust model.

The consent dialog shows every permission declared by the plugin. Common permissions include:

Permission Access granted
content:read Read site content
content:write Create, update, and delete content
content:revisions:read Read retained content revision history
schema:read Read collection and field definitions
bylines:read Read public byline profiles and content credits
redirects:read Read redirect rules
redirects:write Change where visitors are sent
media:read Read safe metadata for ready media
media:bytes:read Read the file contents and content hash of ready media
media:metadata:write Change media alt text, captions, and focal points
media:write Upload, replace, and delete media
network:request Send requests to the plugin’s allowed host list

The dialog also identifies plugin routes exposed as Model Context Protocol (MCP) tools when a plugin declares them. See Capabilities and security for the complete permission model.

  1. Open Plugins in the admin panel.
  2. Select Check for updates.
  3. Select Update on a registry plugin with an available release.
  4. Review the consent dialog, then confirm the update.

Registry updates require another confirmation when they add permissions or MCP tools, or when a route changes from authenticated to public. EmDash leaves the installed version in place until you approve the change.

Explicit updates move forward only. Updates that follow the registry’s latest release can roll back if the publisher withdraws the newest release. To return to an older release any other time, uninstall the plugin and install that version from its registry page. Uninstalling keeps the plugin’s stored data unless you choose to delete it.

  1. Open Plugins in the admin panel and expand the installed plugin.
  2. Select Uninstall.
  3. Select Also delete plugin storage data only if you do not need the plugin’s stored data for a later reinstall.
  4. Confirm the uninstall.

EmDash removes the installed bundle and stops loading the plugin. Plugin storage data remains by default.

Native plugins and config-managed sandboxed plugins install as npm dependencies. Follow the package’s instructions to choose plugins: [] or sandboxed: [].

The following example registers the native Field Kit plugin:

astro.config.mjs
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { fieldKitPlugin } from "@emdash-cms/plugin-field-kit";
export default defineConfig({
integrations: [
emdash({
plugins: [fieldKitPlugin()],
}),
],
});

Config-managed plugins change when you update the npm dependency and deploy the site. They cannot be installed or removed from the admin panel.

Registry npm with sandboxed: [] npm with plugins: []
Install and update Admin panel Dependency change and deploy Dependency change and deploy
Execution Configured sandbox runner Configured sandbox runner Site process
Access to EmDash Only declared plugin APIs Only declared plugin APIs Declared plugin APIs plus direct process access
Node.js APIs and direct fetch() Unavailable Unavailable Available
React admin components Unavailable Unavailable Available
Portable Text renderers Unavailable Unavailable Available

Use a native plugin when it needs React admin components, Portable Text renderers, page fragments, or direct access to the site process. Use a sandboxed plugin when it can work through the declared plugin APIs.