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 します。

これは、ワンステップインストールをエディター側をサンドボックス化したまま保つこととトレードオフします。ブロックレンダリングが関係する場合、完全にネイティブになる方が簡単ですが、この分割も選択肢として残ります。