Der page:fragments-Hook ermöglicht es einem Plugin, rohes HTML, Skripte oder Stylesheets zu öffentlichen Seiten beizutragen. Es ist das richtige Werkzeug für Analytics-Tags, Widgets von Drittanbietern, benutzerdefiniertes CSS und alles andere, was JavaScript oder Markup direkt in den Browser des Besuchers liefern muss.
Er ist auf native Plugins beschränkt, da seine Ausgabe als First-Party-Code im Browser ausgeführt wird, außerhalb jeglicher Sandbox-Grenzen. Wenn Sie nur strukturierte Metadaten beitragen müssen — Meta-Tags, OpenGraph, JSON-LD, zugelassene <link>-Rels — verwenden Sie stattdessen page:metadata, das sowohl für Sandbox- als auch für native Plugins verfügbar ist. Siehe Hooks: page:metadata.
Fähigkeit
page:fragments erfordert die Fähigkeit hooks.page-fragments:register:
return definePlugin({
id: "analytics-gtm",
version: "1.0.0",
capabilities: ["hooks.page-fragments:register"],
// ...
});
Die Fähigkeit muss auch im Deskriptor erscheinen.
Wo Fragmente gerendert werden
Vorlagen entscheiden sich für den Empfang von Fragmenten, indem sie die relevanten Komponenten aus emdash/ui einbinden:
<EmDashHead />— rendert Fragmente mitplacement: "head"plus allepage:metadata-Beiträge.<EmDashBodyStart />— rendert Fragmente mitplacement: "body:start".<EmDashBodyEnd />— rendert Fragmente mitplacement: "body:end".
Vorlagen, die eine dieser Komponenten weglassen, ignorieren stillschweigend Fragmente, die auf diese Platzierung abzielen — Ihr Plugin bricht nicht, die Fragmente erscheinen einfach nicht. Dokumentieren Sie Ihre Platzierungsanforderungen in der README des Plugins.
Beitragsarten
Drei Arten von Beiträgen:
type PageFragmentContribution =
| {
kind: "external-script";
placement: PagePlacement;
src: string;
async?: boolean;
defer?: boolean;
attributes?: Record<string, string>;
key?: string;
}
| {
kind: "inline-script";
placement: PagePlacement;
code: string;
attributes?: Record<string, string>;
key?: string;
}
| {
kind: "html";
placement: PagePlacement;
html: string;
key?: string;
};
PagePlacement ist "head" | "body:start" | "body:end".
Beispiele
Externes Skript
Einen Drittanbieter-Tag-Manager einfügen:
"page:fragments": async (event, ctx) => {
const containerId = await ctx.kv.get<string>("settings:gtmContainerId");
if (!containerId) return null;
return {
kind: "external-script",
placement: "head",
src: `https://www.googletagmanager.com/gtm.js?id=${containerId}`,
async: true,
};
},
Inline-Skript
Ein kleines Stück JavaScript oben in <body> ausführen:
"page:fragments": async (event, ctx) => {
if (event.page.kind !== "content") return null;
return {
kind: "inline-script",
placement: "body:start",
code: `window.contentId = ${JSON.stringify(event.page.content?.id)};`,
};
},
HTML-Fragment
Ein Noscript-Fallback am Ende von <body> anhängen:
"page:fragments": async (event, ctx) => {
const containerId = await ctx.kv.get<string>("settings:gtmContainerId");
if (!containerId) return null;
return {
kind: "html",
placement: "body:end",
html: `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=${containerId}" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>`,
};
},
Mehrere Fragmente
Ein Array zurückgeben, um mehrere Fragmente von einem einzigen Hook beizutragen:
"page:fragments": async (event, ctx) => {
const id = await ctx.kv.get<string>("settings:gtmContainerId");
if (!id) return null;
return [
{
kind: "external-script",
placement: "head",
src: `https://www.googletagmanager.com/gtm.js?id=${id}`,
async: true,
},
{
kind: "html",
placement: "body:end",
html: `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=${id}" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>`,
},
];
},
Seitenereignis
Der page:fragments-Hook empfängt die gleiche Ereignisform wie page:metadata:
{
page: {
url: string;
path: string;
locale: string | null;
kind: "content" | "custom";
pageType: string;
title: string | null;
pageTitle?: string | null;
description: string | null;
canonical: string | null;
image: string | null;
content?: { collection: string; id: string; slug: string | null };
}
}
Verwenden Sie event.page.kind und event.page.pageType, um zu entscheiden, ob Sie auf einer bestimmten Seite beitragen möchten — zum Beispiel Analytics bei Admin-Vorschauen überspringen oder JSON-LD nur bei Blogbeiträgen einfügen.
Wann stattdessen page:metadata verwenden
Wenn das, was Sie tatsächlich benötigen, Folgendes ist:
- Eine Meta-Beschreibung, Robots-Direktive oder Twitter-Karte →
page:metadatamitkind: "meta". - Eine OpenGraph-Eigenschaft →
page:metadatamitkind: "property". - Ein kanonischer oder alternativer
<link>→page:metadatamitkind: "link". - Ein JSON-LD-Graph →
page:metadatamitkind: "jsonld".
page:metadata funktioniert in Sandbox-Plugins, erhält kostenlos Validierung und Deduplizierung und vermeidet die Vertrauenslast, rohes HTML an Besucher zu liefern. Greifen Sie nur dann auf page:fragments zurück, wenn Sie wirklich JavaScript oder HTML liefern müssen.