Componentes de renderizado de Portable Text

En esta página

Los plugins pueden agregar tipos de bloque personalizados al editor de Portable Text: incrustaciones de YouTube, fragmentos de código, galerías de imágenes, cualquier cosa que no esté cubierta por el conjunto de bloques predeterminado. Los plugins sandboxed pueden declarar la interfaz de edición para estos bloques (usando campos de Block Kit), pero los componentes de Astro que los renderizan en el sitio público deben cargarse en tiempo de compilación desde npm. Esa es la parte que requiere un plugin nativo.

Si tu plugin solo necesita campos del lado de edición y alguien más está proporcionando los componentes de renderizado (o el sitio los proporciona localmente), puedes permanecer sandboxed. Si el plugin también debe incluir los componentes de renderizado, necesitas ser nativo.

Declarar tipos de bloque

Tanto los plugins sandboxed como los nativos pueden declarar tipos de bloque. Los plugins nativos lo hacen dentro de definePlugin() bajo 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 bloque define:

  • type — nombre del tipo de bloque (usado en Portable Text _type).
  • label — nombre para mostrar en el menú de comandos slash del editor.
  • iconvideo, code, link o link-external. Vuelve a un cubo genérico por defecto.
  • placeholder — texto de marcador de posición de entrada.
  • fields — campos de formulario de Block Kit para edición. Si se omite, se muestra una entrada de URL simple.

Renderizado en el sitio público

Para renderizar tipos de bloque en el sitio público, exporta componentes de Astro desde un componentsEntry. El nombre de exportación debe ser blockComponents:

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

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

Establece componentsEntry en el descriptor:

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

EmDash fusiona los componentes de bloque del plugin en <PortableText> automáticamente: los autores del sitio no necesitan importar nada. Los componentes proporcionados por el usuario (declarados en la prop components de <PortableText> del sitio) tienen precedencia sobre los valores predeterminados del plugin.

Exportaciones del paquete

Agrega la exportación ./astro a 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" }
	}
}

La exportación ./astro es del lado del servidor (Astro SSR), la exportación ./admin es del lado del navegador (React), y la exportación "." es el descriptor + createPlugin. Manténlos en archivos separados porque se empaquetan para diferentes entornos.

Variantes compatibles con sandbox

Si deseas que un plugin esté sandboxed pero aún así proporcione una experiencia de renderizado predeterminada, el patrón habitual es:

  1. Distribuir el plugin sandboxed (solo campos de edición) en el marketplace.
  2. Distribuir un paquete nativo complementario separado en npm que proporcione los componentes de renderizado de Astro.
  3. Documentar ambos: los usuarios finales instalan el plugin sandboxed desde el marketplace y usan npm install para el paquete complementario de renderizado.

Esto intercambia una instalación de un solo paso por mantener el lado del editor sandboxed. La mayoría de los autores de plugins prefieren simplemente volverse nativos cuando se involucra el renderizado de bloques, pero la opción existe.