Choisir un format de plugin

Sur cette page

Les plugins EmDash utilisent l’un des deux formats : sandboxed ou native. Choisissez le format avant d’écrire le plugin car la forme d’écriture, le chemin d’installation et la frontière de confiance diffèrent.

Choisissez un plugin sandboxed sauf si le plugin a besoin d’une intégration uniquement native. Les plugins sandboxed peuvent être publiés dans le registre et installés depuis l’UI d’administration. Un plugin natif est un paquet npm qu’un opérateur de site installe dans le projet et ajoute à astro.config.mjs avant de redéployer.

En un coup d’œil

SandboxedNative
Authoring shapeemdash-plugin.jsonc + src/plugin.tsdefinePlugin() descriptor
Install methodOne-click from the admin registrynpm install + edit astro.config
Runs inAn isolated runtime provided by a sandbox runnerSame process as your Astro site
Capability-gated ctx APIsEnforced by the sandbox bridgeGated by PluginContext, but not a security boundary
Resource limitsRunner limits for CPU, subrequests, and wall time; platform memory ceilingNo per-plugin limits
Network accessctx.http, restricted to declared accessctx.http follows declarations; native code can also call fetch()
Direct fetch() / process.envBlocked by the runnerPossible (plugin code shares the runtime)
DistributionSigned release in the plugin registrynpm package
Admin UIBlock Kit (JSON-described) routesReact components, or Block Kit
Settings UIBlock Kit page + ctx.settingsadmin.settingsSchema (auto-form) or Block Kit
Portable Text rendering componentsNot availablecomponentsEntry provides Astro components
Page metadata contributionspage:metadata hook — meta/property tags, allowlisted <link> rels, JSON-LDpage:metadata hook (same surface)
Page fragment injectionNot available — meta/JSON-LD only via page:metadatapage:fragments hook — inline scripts, external scripts, raw HTML
Constructor optionsNone — read settings from KV at runtimeoptions on the descriptor

Coûts d’un plugin natif

Les plugins natifs ont un modèle d’installation et de confiance différent :

  • Installation au niveau du projet. Chaque site doit installer votre paquet npm, modifier astro.config.mjs et redéployer.
  • Pas d’isolation. Un bug dans votre plugin peut faire planter le processus hôte ou consommer son budget CPU. Un rejet non géré dans un hook peut emporter la requête environnante.
  • Charge de confiance sur l’utilisateur. Les plugins natifs ont le même accès que le site hôte. Les déclarations de capability seules ne peuvent pas montrer tout ce que leur code peut faire.

Si votre plugin peut faire son travail dans le sandbox, il devrait le faire.

Quand passer au natif

Choisissez natif pour les fonctionnalités qui nécessitent une intégration au moment du build avec le site hôte :

  1. Pages ou widgets d’administration React personnalisés. Les plugins sandboxed décrivent leur UI d’administration avec Block Kit — un schéma JSON que l’admin rend pour le compte du plugin. Si vous avez besoin de React complet (hooks personnalisés, composants tiers, état complexe), vous avez besoin du natif.

  2. Types de blocs Portable Text personnalisés. Leur configuration d’édition et leurs composants de rendu Astro sont chargés depuis le paquet npm installé. Seuls les plugins natifs peuvent fournir cette surface au moment du build.

  3. Injecter du HTML brut, des scripts ou des feuilles de style dans les pages publiques. Le hook page:fragments envoie du code de première partie aux navigateurs des visiteurs — hors de toute frontière de sandbox. Il est réservé aux plugins natifs. Les plugins sandboxed peuvent toujours contribuer aux pages publiques via le hook page:metadata, qui couvre de nombreux cas d’usage réels :

    • balises meta (name + content) — descriptions SEO, directives robots, Twitter cards
    • balises property — OpenGraph et autre meta basé sur property
    • balises link avec une allowlist de rel verrouillée pour la sécurité (canonical, alternate, author, license, nlweb, site.standard.document) — stylesheet, prefetch et rels similaires de chargement de ressources sont volontairement exclus
    • graphes JSON-LD

    Si votre besoin d’« injection de page » est des données structurées ou des métadonnées SEO, restez sandboxed et utilisez page:metadata. Si vous devez réellement envoyer du JavaScript ou du HTML dans le navigateur du visiteur, c’est le cas pour passer au natif.

Si aucune de ces fonctionnalités ne s’applique, utilisez le format sandboxed.

Runners de sandbox et prise en charge des plateformes

Le sandbox lui-même est enfichable. EmDash expose une option de configuration sandboxRunner et le runner décide comment le code du plugin est isolé — il n’y a rien de spécifique à Cloudflare dans le format du plugin lui-même.

Deux runners sont livrés avec EmDash : sandbox() de @emdash-cms/cloudflare, qui exécute chaque plugin comme Dynamic Worker via le Worker Loader de Cloudflare, et @emdash-cms/sandbox-workerd/sandbox, qui exécute les plugins dans un processus enfant workerd sous Node.js. Plugin Sandbox couvre la configuration de chaque runner, les limites de ressources qu’il applique et les différences entre les deux.

Si aucun runner n’est configuré, les plugins listés sous sandboxed: [] ne sont pas chargés. Si le runner configuré est indisponible sur la plateforme actuelle, ils ne sont pas chargés non plus, et EmDash journalise un avertissement au démarrage.

Si vous voulez qu’un plugin sandboxed s’exécute sur une plateforme sans runner de sandbox, déplacez-le de sandboxed: [] vers le tableau plugins: [] — il s’exécutera in-process. Les déclarations de capability sont toujours honorées (la même factory PluginContext contrôle ctx.content, ctx.http et consorts), mais il n’y a pas de frontière d’isolation, pas de limites de ressources, et un plugin bogué ou malveillant peut appeler fetch() directement, lire des variables d’environnement ou bloquer la boucle d’événements. Sans runner de sandbox actif, traitez chaque plugin comme un plugin natif à des fins de confiance.

Suite