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.icon—video,code,linkoulink-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 é:
- Envie o plugin sandboxed (apenas campos de edição) no marketplace.
- Envie um pacote nativo complementar separado no npm que fornece os componentes de renderização Astro.
- Documente ambos: os usuários finais instalam o plugin sandboxed do marketplace e usam
npm installpara 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.