Les plugins EmDash sont livrés dans l’un des deux formats : sandboxed ou native. Le choix affecte la manière dont le plugin est installé, l’application qu’il obtient au moment de l’exécution et les fonctionnalités disponibles.
Par défaut, sandboxed. Les plugins sandboxés peuvent être publiés sur le marketplace et installés depuis l’interface d’administration en un clic. Les plugins natifs nécessitent une modification du code, un npm install et un redéploiement sur chaque site qui les souhaite. Sandboxed est ce que les utilisateurs finaux veulent.
Choisissez natif uniquement lorsque vous avez besoin d’une fonctionnalité que le sandbox ne peut pas fournir.
En un coup d’œil
| Sandboxed | Native | |
|---|---|---|
| Forme d’authoring | emdash-plugin.jsonc + src/plugin.ts | Descripteur definePlugin() |
| Méthode d’installation | Un clic depuis le marketplace d’administration | npm install + éditer astro.config |
| S’exécute dans | Un runtime isolé fourni par un sandbox runner | Le même processus que votre site Astro |
| Capacités | Appliquées par le pont du sandbox | Appliquées en processus par le même pont |
| Limites de ressources | Appliquées par le runner — typiquement CPU, subrequests, wall-time, mémoire | Aucune |
| Accès réseau | ctx.http uniquement, restreint à allowedHosts | ctx.http uniquement, restreint à allowedHosts |
fetch() / process.env directs | Bloqués par le runner | Possible (le code du plugin partage le runtime) |
| Distribution | Bundle .tar.gz sur le marketplace | Paquet npm |
| Interface d’administration | Routes Block Kit (décrites en JSON) | Composants React, ou Block Kit |
| Interface de paramètres | Page Block Kit + lectures KV | admin.settingsSchema (formulaire automatique) ou Block Kit |
| Composants de rendu Portable Text | Non disponible | componentsEntry fournit des composants Astro |
| Contributions de métadonnées de page | Hook page:metadata — balises meta/property, rels <link> autorisés, JSON-LD | Hook page:metadata (même surface) |
| Injection de fragments de page | Non disponible — uniquement meta/JSON-LD via page:metadata | Hook page:fragments — scripts inline, scripts externes, HTML brut |
| Options du constructeur | Aucune — lire les paramètres depuis KV au runtime | options sur le descripteur |
Ce que vous abandonnez en choisissant natif
Les plugins natifs ressemblent à une version plus puissante de la même chose, et ils le sont — mais le coût est élevé :
- Pas de marketplace. Chaque site doit installer votre paquet npm, éditer
astro.config.mjset redéployer. - Pas d’isolation. Un bug dans votre plugin peut planter le processus hôte ou brûler son budget CPU. Un rejet non géré dans un hook peut faire tomber la requête environnante avec lui.
- Charge de confiance sur l’utilisateur. Les plugins natifs ont le même accès que le site hôte. Les utilisateurs finaux ne peuvent pas les auditer uniquement par des déclarations de capacités.
Si votre plugin peut faire son travail dans le sandbox, il devrait le faire.
Quand choisir natif
Il y a trois raisons de choisir natif, et elles concernent toutes des fonctionnalités qui nécessitent une intégration au moment de la compilation avec le site hôte :
-
Pages ou widgets d’administration React personnalisés. Les plugins sandboxés décrivent leur interface d’administration avec Block Kit — un schéma JSON que l’administrateur rend au nom du plugin. Si vous avez besoin de React complet (hooks personnalisés, composants tiers, état complexe), vous avez besoin de natif.
-
Composants Astro pour le rendu de blocs Portable Text sur le site public. Un plugin sandboxé peut déclarer un type de bloc personnalisé, mais les composants Astro qui le rendent sur le site public doivent être chargés au moment de la compilation depuis npm. Seuls les plugins natifs peuvent fournir un
componentsEntry. -
Injecter du HTML brut, des scripts ou des feuilles de style dans des pages publiques. Le hook
page:fragmentsenvoie du code first-party aux navigateurs des visiteurs — en dehors de toute limite de sandbox. Il est restreint aux plugins natifs. Les plugins sandboxés peuvent toujours contribuer aux pages publiques via le hookpage:metadata, qui couvre de nombreux cas d’utilisation réels :- Balises
meta(name+content) — descriptions SEO, directives robots, cartes Twitter - Balises
property— OpenGraph et autres méta basés sur les propriétés - Balises
linkavec une liste blanche rel verrouillée par sécurité (canonical,alternate,author,license,nlweb,site.standard.document) —stylesheet,prefetchet des rels similaires de chargement de ressources ne sont délibérément pas autorisés - Graphes JSON-LD
Si votre besoin “d’injection de page” concerne des données structurées ou des métadonnées SEO, restez sandboxé et utilisez
page:metadata. Si vous devez réellement envoyer du JavaScript ou du HTML au navigateur du visiteur, c’est le cas pour choisir natif. - Balises
Si vous n’êtes pas sûr, choisissez sandboxed. Vous pouvez toujours migrer vers natif plus tard — mais l’inverse est plus difficile, car les fonctionnalités natives uniquement n’ont pas d’équivalent sandbox.
Sandbox runners et support de plateforme
Le sandbox lui-même est extensible. 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.
Le runner que la plupart des sites utilisent aujourd’hui est sandbox() de @emdash-cms/cloudflare, qui utilise Dynamic Worker Loader de Cloudflare Workers. Worker Loader met en cache l’isolat V8 par id de plugin, de sorte que le coût de démarrage à froid de l’isolat n’est payé qu’une seule fois ; le runner construit un stub de worker frais et des bindings de pont à chaque invocation, car les stubs et les bindings sont liés au contexte I/O de la requête appelante. Des runners pour d’autres plateformes (Node.js via workerd, et potentiellement Deno) sont en développement.
Si aucun runner n’est configuré, ou si le runner configuré signale comme non disponible sur la plateforme actuelle, les plugins listés sous sandboxed: [] sont ignorés au démarrage avec un log de niveau de débogage.
Si vous souhaitez qu’un plugin sandboxé s’exécute sur une plateforme sans sandbox runner, déplacez-le de sandboxed: [] dans le tableau plugins: [] — il s’exécutera en processus. Les déclarations de capacités sont toujours respectées (la même factory PluginContext contrôle ctx.content, ctx.http et amis), mais il n’y a pas de limite 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 un sandbox runner actif, traitez chaque plugin comme un plugin natif à des fins de confiance.