DocumentaçãoSDK no GitHub

Documentação Guias

Blocos personalizados

Defina blocos de e-mail com campos na sua aplicação e renderize pelo SDK de integração.

Nesta página

Definir um bloco

Informe customBlocks como array. As funções de renderização executam na sua aplicação, de forma síncrona ou por promise. O iframe recebe definições JSON e um fragmento HTML de corpo. O SDK não depende do runtime React.

html
<script src="https://weavour.com/editor/sdk/0.1.12/editor.js"></script>
<div id="email-editor" style="height: 800px"></div>
<script>
const escapeHTML = value => String(value).replace(/[&<>"']/g, char =>
  ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[char]));
const editor = Weavour.mount('#email-editor', {
  editorKey: 'YOUR_PUBLIC_EDITOR_KEY',
  userId: 'user-123', organizationId: 'org-456',
  customBlocks: [{
    id: 'product-card', version: 1, label: 'Product card',
    defaultProps: { title: 'New product', href: 'https://example.com/product' },
    controls: {
      title: { type: 'text', label: 'Product name', required: true },
      href: { type: 'url', label: 'Product link' },
    },
    render: props => '<table role="presentation" width="100%"><tbody><tr>' +
      '<td style="padding:24px"><h2>' + escapeHTML(props.title) + '</h2>' +
      '<a href="' + escapeHTML(props.href) + '">View product</a></td></tr></tbody></table>',
  }],
  onDocumentChange(document) { /* Save the complete envelope in your backend. */ },
});
</script>

Referência da definição

PropriedadeContrato
idID estável: começa com letra, depois letras, números, sublinhados ou hífens; até 64 caracteres.
versionInteiro positivo. Com id, identifica exatamente a função de renderização e os controles.
labelNome de exibição definido pelo cliente, até 200 caracteres. O editor não traduz nomes do cliente.
defaultPropsObjeto JSON copiado para novos blocos; propriedades salvas existentes não mudam.
controlsDefinições de campos por nome de propriedade, com rótulo e valor padrão compatível.
render(props)Retorna um fragmento HTML de corpo com estilos inline ou Promise<string>; executa na sua aplicação.
iconSvgString SVG estática opcional que substitui o esquema automático da paleta.

Usar React Email

Instale React, @react-email/components e @react-email/render na sua aplicação. Testado com components 1.0.12, render 2.2.0 e React 19.3.1: Section, Row, Column, Text, Button e Img. Retorne um fragmento de corpo independente; omita Html, Head, Body e estilos do head.

tsx
import { defineCustomBlock } from '@weavour/editor';
import { WeavourEditor } from '@weavour/react';
import { Section, Text, Button } from '@react-email/components';
import { render } from '@react-email/render';

export const productCard = defineCustomBlock({
  id: 'product-card', version: 1, label: 'Product card',
  defaultProps: { title: 'New product', href: 'https://example.com/product' },
  controls: {
    title: { type: 'text', label: 'Product name', required: true },
    href: { type: 'url', label: 'Product link' },
  },
  async render(props) {
    const html = await render(
      <Section><Text>{props.title}</Text>
        <Button href={props.href} style={{ padding: '12px 24px' }}>View product</Button>
      </Section>
    );
    // React Email adds a doctype even when rendering a body fragment.
    return html.replace(/^<!doctype[^>]*>/i, '');
  },
});
export function CampaignEditor() {
  return <WeavourEditor
    editorKey="YOUR_PUBLIC_EDITOR_KEY"
    userId="user-123" organizationId="org-456"
    customBlocks={[productCard]} style={{ height: 800 }}
  />;
}

Controles e propriedades de imagens

Todo controle precisa de rótulo e propriedade padrão compatível. Controles de imagem abrem a biblioteca do escopo e o recorte. O descritor é { src, assetId, width, height, alt }; renderize usando src e alt. IDs de arquivos nunca concedem acesso. Outras propriedades JSON limitadas podem guardar dados salvos do cliente.

TipoValorOpções
text / textareastringplaceholder, required, maxLength
urlstringrequired; merge tags
imagedescriptor | nullrequired; src, assetId, width, height, alt
numbernumbermin, max, step
selectstringoptions: [{ label, value }]
booleanboolean
colorstring#rrggbb

Inserir e editar

Blocos personalizados aparecem após os padrão na mesma grade, sem título nem separador. Os blocos da organização vêm depois. A busca acima da grade filtra os três tipos por nome; limpe o campo ou pressione Escape para restaurar a paleta. Clique, arraste ou foque um bloco e pressione Enter para inserir. O painel gera controles a partir da definição; campos de seleção usam o mesmo menu com tema dos controles padrão. Mover, duplicar, excluir e desfazer funcionam normalmente. Durante a renderização, novos blocos reservam uma área vazia; atualizações mantêm a última prévia e mostram um indicador na lateral. Erros e novas tentativas ficam na lateral, fora do conteúdo do e-mail.

Ícones da paleta

Sem iconSvg, a paleta desenha um esquema a partir do layout de render(defaultProps) no navegador. Reutiliza uma captura salva compatível; caso contrário, executa a função uma vez por definição e geração do registro, dentro dos limites compartilhados. Os ícones são mantidos entre abas e temas. A medição não carrega recursos externos; imagens sem dimensões usam espaços reservados. Uma falha mantém um ícone genérico para inserção. Defina iconSvg com uma string SVG estática e viewBox para substituir o esquema e evitar a renderização da paleta. Geometria aceita: g, path, rect, circle, ellipse, line, polyline e polygon. Cores seguem o tema e preservam none. Scripts, eventos, estilos, texto, referências e conteúdo incorporado são rejeitados. Limites: 16 KiB UTF-8, 128 elementos, 12 níveis. Ícones não alteram documentos, histórico nem exportações.

typescript
// Optional property on a custom-block definition. Omit for an automatic outline.
const iconSvg = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6">' +
  '<rect x="3" y="3" width="18" height="18" rx="2"/>' +
  '<path d="M7 8h10M7 12h6M7 16h8"/></svg>';

// Keep the renderer and controls; replace only the palette icon.
editor.updateConfig({ customBlocks: [{ ...productCard, iconSvg }] });

Versões e configuração em tempo real

Registre pares exatos (id, version); a paleta insere a maior versão registrada. Aumente version quando mudar comportamento, padrões ou semântica dos controles. Mantenha versões antigas para editar conteúdo antigo. Definições alteradas nunca reescrevem propriedades nem capturas existentes. customBlocks no nível superior prevalece sobre editorConfig.customBlocks; updateConfig({ customBlocks }) substitui o registro, [] limpa e omissão preserva. A propriedade React atualiza sem remontar.

typescript
// productCard is the definition from the React Email example above.
editor.updateConfig({ customBlocks: [productCard] });

// Include each custom ID when supplying an explicit insertion allowlist.
editor.updateConfig({
  allowedBlocks: ['text', 'heading', 'section', 'custom:product-card'],
});

// Remove registrations without deleting existing email content.
editor.updateConfig({ customBlocks: [] });

Salvamento, prévias e exportação

Salve o envelope completo do esquema 3 em onDocumentChange e reabra com emailDocument. Ele contém referência, propriedades e captura HTML validada de cada bloco; callbacks e metadados de ícones não são salvos. Rascunhos preservam edições não resolvidas. Exportação, teste, criação de modelo e salvamento de blocos da organização aguardam o resultado atual e falham se indisponível. Uma função de renderização ausente preserva capturas válidas para prévia e exportação e desativa a edição dos campos. Reabrir uma captura válida não renderiza novamente esse nó; a paleta pode renderizar os padrões para criar seu ícone. Prévias no painel usam capturas. Blocos da organização são layouts reutilizáveis com blocos nativos ou personalizados; salvar exige organizationId.

Política de HTML e personalização

Retorne tabelas, links, textos e imagens de e-mail com estilos inline. Comentários de botões compatíveis com Outlook são preservados. Scripts, eventos, formulários, frames, objetos, elementos de documento, CSS de head, classes que exigem estilos globais e URLs em CSS são rejeitados com erro. Escape valores escritos. Tokens conhecidos permanecem literais nos callbacks; use variáveis configuradas e layouts condicionais para personalização por destinatário. A Weavour não busca dados de destinatários.

Restrições de blocos

Uma lista explícita allowedBlocks deve incluir custom:product-card para permitir inserir este exemplo. Sem lista, IDs personalizados registrados ficam disponíveis. Restrições preservam nós existentes. O transporte de código personalizado está desativado na demonstração pública. Atualize SDK e leitores hospedados antes de habilitar escrita do esquema 3; versões antigas falham explicitamente.

Limites e solução de problemas

Por montagem: 50 versões de definições, 32 controles por versão, 100 nós personalizados, 32 KiB UTF-8 de propriedades por nó, 100 KiB de HTML de captura, quatro renderizações ativas e 100 solicitações pendentes. A digitação espera 150 ms; a renderização expira em cinco segundos. Documentos do esquema 3 têm limite conjunto de 1.000.000 bytes, incluindo capturas e metadados; limites de transporte e API também valem. Funções devem terminar rápido e evitar efeitos colaterais; JavaScript síncrono não pode ser interrompido à força. Salve dados resolvidos nas propriedades para reproduzir o conteúdo. Tente novamente, restaure o registro exato ou reduza o HTML. A substituição completa por IA não está disponível em documentos com blocos personalizados.

Precisa de ajuda? Fale com a gente