Componentes de renderização Portable Text

Nesta página

Plugins podem adicionar tipos de bloco personalizados ao editor Portable Text — incorporações do YouTube, trechos 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 no momento da compilação a partir do npm. Essa é a parte que requer um plugin nativo.

Se o 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 bloco

Tanto plugins sandboxed quanto nativos podem declarar tipos de bloco. 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 em Portable Text _type).
  • label — nome de exibição no menu de comandos slash do editor.
  • iconvideo, code, link ou link-external. Volta 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 é mostrada.

Renderização no site público

Para renderizar tipos de bloco no site público, exporte componentes Astro de um componentsEntry. O nome da 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 descritor:

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 bloco de plugin em <PortableText> automaticamente — autores de sites não precisam importar nada. Componentes fornecidos pelo usuário (declarados na prop components de <PortableText> do site) têm precedência sobre os padrões do plugin.

Exportações do 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 descritor + createPlugin. Mantenha-os em arquivos separados porque são empacotados para ambientes diferentes.

Variantes compatíveis com sandbox

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

  1. Envie o plugin sandboxed (apenas campos de edição) no marketplace.
  2. Envie 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 usam npm install para o pacote complementar de renderização.

Isso troca uma instalação de uma etapa por manter o lado do editor sandboxed. A maioria dos autores de plugin prefere simplesmente se tornar nativa quando a renderização de bloco está envolvida — mas a opção existe.