Portable Text レンダリングコンポーネント

このページ

プラグインは Portable Text エディターにカスタムブロックタイプを追加できます — YouTube の埋め込み、コードスニペット、画像ギャラリーなど、デフォルトのブロックセットでカバーされていないものすべてです。サンドボックス化されたプラグインは、これらのブロックの編集 UI を宣言できます(Block Kit フィールドを使用)が、公開サイトでそれらをレンダリングする Astro コンポーネントは、ビルド時に npm からロードする必要があります。これがネイティブプラグインを必要とする部分です。

プラグインが編集側のフィールドのみを必要とし、他の誰かがレンダリングコンポーネントを提供している場合(またはサイトがローカルで提供している場合)は、サンドボックス化されたままでいることができます。プラグインがレンダリングコンポーネントも提供する必要がある場合は、ネイティブである必要があります。

ブロックタイプの宣言

サンドボックス化されたプラグインとネイティブプラグインの両方がブロックタイプを宣言できます。ネイティブプラグインは definePlugin() 内の admin.portableTextBlocks の下でこれを行います:

admin: {
	portableTextBlocks: [
		{
			type: "youtube",
			label: "YouTube Video",
			icon: "video",                       // video, code, link, link-external
			placeholder: "Paste YouTube URL...",
			fields: [                            // Block Kit fields for the editing UI
				{ type: "text_input", action_id: "id", label: "YouTube URL" },
				{ type: "text_input", action_id: "title", label: "Title" },
				{ type: "text_input", action_id: "poster", label: "Poster Image URL" },
			],
		},
	],
},

各ブロックタイプは以下を定義します:

  • type — ブロックタイプ名(Portable Text の _type で使用)。
  • label — エディターのスラッシュコマンドメニューに表示される名前。
  • iconvideocodelink、または link-external。デフォルトで汎用的なキューブにフォールバックします。
  • placeholder — 入力プレースホルダーテキスト。
  • fields — 編集用の Block Kit フォームフィールド。省略された場合、シンプルな URL 入力が表示されます。

公開サイトでのレンダリング

公開サイトでブロックタイプをレンダリングするには、componentsEntry から Astro コンポーネントをエクスポートします。エクスポート名は blockComponents である必要があります:

import YouTube from "./YouTube.astro";
import CodePen from "./CodePen.astro";

export const blockComponents = {
	youtube: YouTube,
	codepen: CodePen,
};

ディスクリプターに componentsEntry を設定します:

export function myPlugin(): PluginDescriptor {
	return {
		id: "embeds",
		version: "1.0.0",
		format: "native",
		entrypoint: "@my-org/embeds",
		componentsEntry: "@my-org/embeds/astro",
	};
}

EmDash は自動的にプラグインのブロックコンポーネントを <PortableText> にマージします — サイト作成者は何もインポートする必要がありません。ユーザーが提供するコンポーネント(サイトの <PortableText>components プロップで宣言)は、プラグインのデフォルトよりも優先されます。

パッケージのエクスポート

package.json./astro エクスポートを追加します:

{
	"exports": {
		".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
		"./admin": { "types": "./dist/admin.d.ts", "import": "./dist/admin.js" },
		"./astro": { "types": "./dist/astro/index.d.ts", "import": "./dist/astro/index.js" }
	}
}

./astro エクスポートはサーバーサイド(Astro SSR)、./admin エクスポートはブラウザサイド(React)、"." エクスポートはディスクリプター + createPlugin です。異なる環境用にバンドルされるため、これらを別々のファイルに保管してください。

サンドボックス対応の変種

プラグインをサンドボックス化しながらもデフォルトのレンダリング体験を提供したい場合、通常のパターンは:

  1. サンドボックス化されたプラグイン(編集フィールドのみ)をマーケットプレイスに出荷する。
  2. Astro レンダリングコンポーネントを提供する別のネイティブコンパニオンパッケージを npm に出荷する。
  3. 両方を文書化する: エンドユーザーはマーケットプレイスからサンドボックス化されたプラグインをインストールし、レンダリング用のコンパニオンパッケージには npm install を使用します。

これは、ワンステップインストールをエディター側をサンドボックス化したままにするためにトレードオフします。ブロックレンダリングが関係する場合、ほとんどのプラグイン作成者は単にネイティブにすることを好みますが、オプションは存在します。