Componenti di rendering Portable Text

In questa pagina

I plugin possono aggiungere tipi di blocco personalizzati all’editor Portable Text — incorporamenti YouTube, frammenti di codice, gallerie di immagini, qualsiasi cosa non coperta dal set di blocchi predefinito. I plugin sandboxed possono dichiarare l’interfaccia di modifica per questi blocchi (utilizzando campi Block Kit), ma i componenti Astro che li renderizzano sul sito pubblico devono essere caricati al momento della build da npm. Questa è la parte che richiede un plugin nativo.

Se il tuo plugin necessita solo di campi lato editing e qualcun altro sta fornendo i componenti di rendering (o il sito li fornisce localmente), puoi rimanere sandboxed. Se il plugin deve anche fornire i componenti di rendering, devi essere nativo.

Dichiarare i tipi di blocco

Sia i plugin sandboxed che quelli nativi possono dichiarare tipi di blocco. I plugin nativi lo fanno all’interno di definePlugin() sotto 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" },
			],
		},
	],
},

Ogni tipo di blocco definisce:

  • type — nome del tipo di blocco (utilizzato in Portable Text _type).
  • label — nome visualizzato nel menu dei comandi slash dell’editor.
  • iconvideo, code, link o link-external. Torna a un cubo generico per impostazione predefinita.
  • placeholder — testo segnaposto di input.
  • fields — campi di modulo Block Kit per la modifica. Se omessi, viene mostrato un semplice input URL.

Rendering sul sito pubblico

Per renderizzare tipi di blocco sul sito pubblico, esporta componenti Astro da un componentsEntry. Il nome dell’esportazione deve essere blockComponents:

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

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

Imposta componentsEntry sul descrittore:

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

EmDash unisce automaticamente i componenti di blocco dei plugin in <PortableText> — gli autori del sito non devono importare nulla. I componenti forniti dall’utente (dichiarati nella prop components di <PortableText> del sito) hanno la precedenza sui valori predefiniti dei plugin.

Esportazioni del package

Aggiungi l’esportazione ./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" }
	}
}

L’esportazione ./astro è lato server (Astro SSR), l’esportazione ./admin è lato browser (React), e l’esportazione "." è il descrittore + createPlugin. Tienili in file separati perché vengono impacchettati per ambienti diversi.

Varianti compatibili con sandbox

Se vuoi che un plugin sia sandboxed ma fornisca comunque un’esperienza di rendering predefinita, il pattern abituale è:

  1. Distribuisci il plugin sandboxed (solo campi di modifica) sul marketplace.
  2. Distribuisci un package nativo complementare separato su npm che fornisce i componenti di rendering Astro.
  3. Documenta entrambi: gli utenti finali installano il plugin sandboxed dal marketplace e usano npm install per il package complementare di rendering.

Questo scambia un’installazione in un solo passaggio con il mantenimento del lato editor sandboxed. La maggior parte degli autori di plugin preferisce semplicemente diventare nativa quando è coinvolto il rendering di blocchi — ma l’opzione esiste.