페이지 프래그먼트

이 페이지

page:fragments 훅은 플러그인이 공개 페이지에 원시 HTML, 스크립트 또는 스타일시트를 기여할 수 있게 합니다. 이는 분석 태그, 타사 위젯, 사용자 정의 CSS 및 JavaScript 또는 마크업을 방문자의 브라우저에 직접 전달해야 하는 기타 항목에 적합한 도구입니다.

출력이 브라우저에서 퍼스트 파티 코드로 실행되어 샌드박스 경계 밖에서 작동하기 때문에 네이티브 플러그인으로 제한됩니다. 구조화된 메타데이터 — 메타 태그, OpenGraph, JSON-LD, 허용된 <link> rels — 만 기여해야 하는 경우, 샌드박스 및 네이티브 플러그인 모두에서 사용할 수 있는 page:metadata를 대신 사용하십시오. Hooks: page:metadata를 참조하십시오.

Capability

page:fragmentshooks.page-fragments:register capability가 필요합니다:

return definePlugin({
	id: "analytics-gtm",
	version: "1.0.0",
	capabilities: ["hooks.page-fragments:register"],
	// ...
});

이 capability는 디스크립터에도 나타나야 합니다.

프래그먼트가 렌더링되는 위치

템플릿은 emdash/ui에서 관련 컴포넌트를 포함하여 프래그먼트를 받도록 선택합니다:

  • <EmDashHead />placement: "head"가 있는 프래그먼트와 모든 page:metadata 기여를 렌더링합니다.
  • <EmDashBodyStart />placement: "body:start"가 있는 프래그먼트를 렌더링합니다.
  • <EmDashBodyEnd />placement: "body:end"가 있는 프래그먼트를 렌더링합니다.

이러한 컴포넌트 중 하나를 생략하는 템플릿은 해당 배치를 대상으로 하는 프래그먼트를 자동으로 무시합니다 — 플러그인이 깨지지 않고 프래그먼트만 나타나지 않습니다. 플러그인의 README에 배치 요구 사항을 문서화하십시오.

기여 유형

훅은 세 가지 기여 유형 중 하나를 반환할 수 있습니다:

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"head" | "body:start" | "body:end"입니다.

예제

외부 스크립트

다음 훅은 타사 태그 관리자를 <head>에 주입합니다:

"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,
	};
},

인라인 스크립트

다음 훅은 콘텐츠 페이지의 <body> 상단에서 작은 JavaScript 조각을 실행합니다:

"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 프래그먼트

다음 훅은 <body> 끝에 noscript 폴백을 추가합니다:

"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>`,
	};
},

여러 프래그먼트

훅은 배열을 반환하여 한 번에 여러 프래그먼트를 기여할 수 있습니다. 다음 훅은 스크립트와 noscript 폴백을 모두 추가합니다:

"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>`,
		},
	];
},

페이지 이벤트

page:fragments 훅은 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 };
	}
}

event.page.kindevent.page.pageType를 사용하여 주어진 페이지에서 기여할지 결정하십시오 — 예를 들어, 관리자 미리보기에서 분석을 건너뛰거나 블로그 게시물에만 JSON-LD를 주입합니다.

언제 대신 page:metadata를 사용할까

실제로 필요한 것이 다음과 같은 경우:

  • 메타 설명, robots 지시문 또는 Twitter 카드 → kind: "meta"가 있는 page:metadata.
  • OpenGraph 속성 → kind: "property"가 있는 page:metadata.
  • 정규 또는 대체 <link>kind: "link"가 있는 page:metadata.
  • JSON-LD 그래프 → kind: "jsonld"가 있는 page:metadata.

page:metadata는 샌드박스 플러그인에서 작동하고 무료로 유효성 검사 및 중복 제거를 받으며 방문자에게 원시 HTML을 전달하는 신뢰 부담을 피합니다. JavaScript 또는 HTML을 전달해야 할 때만 page:fragments에 의존하십시오.