Componentes de renderização Portable Text

Nesta página

Plugins podem adicionar tipos de blocos personalizados ao editor Portable Text — embeddings do YouTube, snippets de código, galerias de imagens, qualquer coisa que não seja coberta pelo conjunto de blocos padrão. Plugins sandboxed podem declarar a interface de edição para esses blocos (usando campos Block Kit), mas os componentes Astro que os renderizam no site público precisam ser carregados em tempo de compilação a partir do npm. Essa é a parte que requer um plugin nativo.

Se seu plugin precisa apenas de campos do lado da edição e outra pessoa está fornecendo os componentes de renderização (ou o site os está fornecendo localmente), você pode permanecer sandboxed. Se o plugin também deve fornecer os componentes de renderização, você precisa ser nativo.

Declarando tipos de blocos

Tanto plugins sandboxed quanto nativos podem declarar tipos de blocos. Plugins nativos fazem isso dentro de definePlugin() sob 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" },
			],
		},
	],
},

Cada tipo de bloco define:

  • type — nome do tipo de bloco (usado no Portable Text _type).
  • label — nome de exibição no menu de comandos slash do editor.
  • iconvideo, code, link ou link-external. Retorna para um cubo genérico por padrão.
  • placeholder — texto de placeholder de entrada.
  • fields — campos de formulário Block Kit para edição. Se omitido, uma entrada de URL simples é exibida.

Renderização no site público

Para renderizar tipos de blocos no site público, exporte componentes Astro de um componentsEntry. O nome de exportação deve ser blockComponents:

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

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

Defina componentsEntry no descriptor:

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

EmDash mescla componentes de blocos de plugins no <PortableText> automaticamente — autores de sites não precisam importar nada. Componentes fornecidos pelo usuário (declarados na prop components do site em <PortableText>) têm precedência sobre os padrões do plugin.

Exportações de pacote

Adicione a exportação ./astro ao package.json:

{
	"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" }
	}
}

A exportação ./astro é do lado do servidor (Astro SSR), a exportação ./admin é do lado do navegador (React), e a exportação "." é o descriptor + createPlugin. Mantenha-os em arquivos separados porque eles são empacotados para ambientes diferentes.

Variantes compatíveis com sandbox

Se você deseja que um plugin seja sandboxed mas ainda forneça uma experiência de renderização padrão, o padrão usual é:

  1. Distribua o plugin sandboxed (apenas campos de edição) no marketplace.
  2. Distribua um pacote nativo complementar separado no npm que fornece os componentes de renderização Astro.
  3. Documente ambos: os usuários finais instalam o plugin sandboxed do marketplace e executam npm install do pacote complementar para renderização.

Isso troca uma instalação de uma etapa por manter o lado do editor sandboxed. Ser totalmente nativo é mais simples quando a renderização de blocos está envolvida, mas essa divisão permanece uma opção.