EmDash-Plugins werden in einem von zwei Formaten ausgeliefert: sandboxed oder native. Die Wahl beeinflusst, wie das Plugin installiert wird, welche Durchsetzung es zur Laufzeit erhält und welche Funktionen verfügbar sind.
Standard ist sandboxed. Sandboxed-Plugins können im Marketplace veröffentlicht und mit einem Klick über die Admin-Oberfläche installiert werden. Native Plugins erfordern eine Codeänderung, ein npm install und ein erneutes Deployment auf jeder Website, die sie verwenden möchte. Sandboxed ist das, was Endbenutzer wollen.
Wählen Sie native nur, wenn Sie eine Funktion benötigen, die die Sandbox nicht bereitstellen kann.
Auf einen Blick
| Sandboxed | Native | |
|---|---|---|
| Authoring-Form | emdash-plugin.jsonc + src/plugin.ts | definePlugin()-Deskriptor |
| Installationsmethode | Ein Klick aus dem Admin-Marketplace | npm install + astro.config bearbeiten |
| Läuft in | Einer isolierten Laufzeitumgebung durch einen Sandbox-Runner | Gleichem Prozess wie Ihre Astro-Site |
| Fähigkeiten | Durchgesetzt durch die Sandbox-Bridge | Prozessintern durch dieselbe Bridge durchgesetzt |
| Ressourcenlimits | Durchgesetzt durch den Runner — typischerweise CPU, Subrequests, Wall-Time, Speicher | Keine |
| Netzwerkzugriff | Nur ctx.http, beschränkt auf allowedHosts | Nur ctx.http, beschränkt auf allowedHosts |
Direkter fetch() / process.env | Vom Runner blockiert | Möglich (Plugin-Code teilt die Laufzeit) |
| Verteilung | .tar.gz-Bundle im Marketplace | npm-Paket |
| Admin-UI | Block Kit (JSON-beschrieben) Routen | React-Komponenten oder Block Kit |
| Einstellungs-UI | Block Kit-Seite + KV-Lesevorgänge | admin.settingsSchema (Auto-Formular) oder Block Kit |
| Portable Text Rendering-Komponenten | Nicht verfügbar | componentsEntry stellt Astro-Komponenten bereit |
| Seitenmetadaten-Beiträge | page:metadata-Hook — Meta/Property-Tags, allowlisted <link>-rels, JSON-LD | page:metadata-Hook (gleiche Oberfläche) |
| Seitenfragment-Injektion | Nicht verfügbar — nur Meta/JSON-LD über page:metadata | page:fragments-Hook — Inline-Skripte, externe Skripte, rohes HTML |
| Constructor-Optionen | Keine — Einstellungen zur Laufzeit aus KV lesen | options im Deskriptor |
Was Sie bei Native aufgeben
Native Plugins sehen aus wie eine mächtigere Version derselben Sache, und das sind sie auch — aber die Kosten sind hoch:
- Kein Marketplace. Jede Website muss Ihr npm-Paket installieren,
astro.config.mjsbearbeiten und erneut deployen. - Keine Isolation. Ein Fehler in Ihrem Plugin kann den Host-Prozess zum Absturz bringen oder sein CPU-Budget aufbrauchen. Eine unbehandelte Ablehnung in einem Hook kann die umgebende Anfrage mit sich reißen.
- Vertrauenslast beim Benutzer. Native Plugins haben denselben Zugriff wie die Host-Website. Endbenutzer können sie nicht allein durch Fähigkeitsdeklarationen überprüfen.
Wenn Ihr Plugin seine Arbeit in der Sandbox erledigen kann, sollte es das tun.
Wann native wählen
Es gibt drei Gründe, native zu wählen, und sie alle betreffen Funktionen, die Build-Time-Integration mit der Host-Website benötigen:
-
Benutzerdefinierte React-Admin-Seiten oder -Widgets. Sandboxed-Plugins beschreiben ihre Admin-UI mit Block Kit — einem JSON-Schema, das der Admin im Namen des Plugins rendert. Wenn Sie volles React benötigen (benutzerdefinierte Hooks, Drittanbieter-Komponenten, komplexer State), benötigen Sie native.
-
Astro-Komponenten zum Rendern von Portable Text-Blöcken auf der öffentlichen Website. Ein sandboxed Plugin kann einen benutzerdefinierten Blocktyp deklarieren, aber die Astro-Komponenten, die ihn auf der öffentlichen Website rendern, müssen zur Build-Time von npm geladen werden. Nur native Plugins können einen
componentsEntrybereitstellen. -
Rohes HTML, Skripte oder Stylesheets in öffentliche Seiten injizieren. Der
page:fragments-Hook liefert First-Party-Code an die Browser der Besucher — außerhalb jeder Sandbox-Grenze. Er ist auf native Plugins beschränkt. Sandboxed-Plugins können immer noch über denpage:metadata-Hook zu öffentlichen Seiten beitragen, der viele echte Anwendungsfälle abdeckt:meta-Tags (name+content) — SEO-Beschreibungen, Robots-Direktiven, Twitter-Cardsproperty-Tags — OpenGraph und andere property-basierte Metalink-Tags mit einer sicherheitsgesperrten rel-Allowlist (canonical,alternate,author,license,nlweb,site.standard.document) —stylesheet,prefetchund ähnliche ressourcenladende rels sind absichtlich nicht erlaubt- JSON-LD-Graphen
Wenn Ihr “Seiteninjektions”-Bedarf strukturierte Daten oder SEO-Metadaten ist, bleiben Sie sandboxed und verwenden Sie
page:metadata. Wenn Sie tatsächlich JavaScript oder HTML in den Browser des Besuchers liefern müssen, ist das der Fall für native.
Wenn Sie sich nicht sicher sind, wählen Sie sandboxed. Sie können später immer zu native migrieren — aber umgekehrt ist es schwieriger, weil native-exklusive Funktionen keine Sandbox-Äquivalente haben.
Sandbox-Runner und Plattformunterstützung
Die Sandbox selbst ist erweiterbar. EmDash exponiert eine sandboxRunner-Konfigurationsoption und der Runner entscheidet, wie Plugin-Code isoliert wird — es gibt nichts Cloudflare-Spezifisches im Plugin-Format selbst.
Der Runner, den die meisten Websites heute verwenden, ist sandbox() von @emdash-cms/cloudflare, der Cloudflare Workers’ Dynamic Worker Loader verwendet. Worker Loader cached das V8-Isolat pro Plugin-ID, sodass die Isolat-Kaltstartkosten nur einmal bezahlt werden; der Runner konstruiert bei jedem Aufruf einen frischen Worker-Stub und Bridge-Bindings, da Stubs und Bindings an den I/O-Kontext der aufrufenden Anfrage gebunden sind. Runner für andere Plattformen (Node.js via workerd und potenziell Deno) sind in Entwicklung.
Wenn kein Runner konfiguriert ist oder wenn der konfigurierte Runner auf der aktuellen Plattform als nicht verfügbar meldet, werden Plugins, die unter sandboxed: [] aufgeführt sind, beim Start mit einem Debug-Level-Log übersprungen.
Wenn Sie ein sandboxed Plugin auf einer Plattform ohne Sandbox-Runner ausführen möchten, verschieben Sie es von sandboxed: [] in das plugins: []-Array — es wird dann prozessintern ausgeführt. Fähigkeitsdeklarationen werden weiterhin berücksichtigt (dieselbe PluginContext-Factory steuert ctx.content, ctx.http und Friends), aber es gibt keine Isolationsgrenze, keine Ressourcenlimits, und ein fehlerhaftes oder böswilliges Plugin kann fetch() direkt aufrufen, Umgebungsvariablen lesen oder die Event-Loop blockieren. Ohne aktiven Sandbox-Runner behandeln Sie jedes Plugin aus Vertrauensgründen als natives Plugin.