Criando plug-ins para o ONLYOFFICE: dicas, truques e armadilhas ocultas

22 janeiro 2026Por Klaibson

Criar plug-ins para os editores ONLYOFFICE pode ser simples, mas o desenvolvimento no mundo real muitas vezes revela desafios inesperados, desde gargalos de desempenho e peculiaridades de rede até diferenças sutis entre ambientes web e desktop. Este artigo aborda dicas práticas, técnicas comprovadas e armadilhas comuns que você provavelmente encontrará ao criar plug-ins confiáveis que funcionam perfeitamente em editores e cenários de implantação.

Criando plug-ins para o ONLYOFFICE: dicas, truques e armadilhas ocultas

Ponte e fluxo de trabalho

A interface do usuário do seu plug-in é executada em sua própria janela e se comunica com o editor por meio de uma ponte de mensagens. Essa ponte funciona melhor com pequenas quantidades de dados e edições rápidas e específicas. Manter o trabalho da interface do usuário (como buscar dados ou filtrar listas) separado das alterações no documento (como inserir texto) torna tudo mais rápido, fácil de depurar e mais previsível quando vários usuários editam ao mesmo tempo.

Mantenha as edições dos documentos curtas e focadas

Por que: Os comandos do editor são executados de uma só vez; agrupar alterações relacionadas evita oscilações e mantém o estado do documento consistente.

Exemplo (Document Editor, inserir uma citação):

// UI side: prepare compact data
const citation = `${title} - ${source}${date ?  ', ' + date : ''}`;
Asc.scope.citation = citation;

// Editor side: run atomically
window.Asc.plugin.callCommand(function () {
  var doc = Api.GetDocument();
  var p = Api.CreateParagraph();
  p.AddText(Asc.scope.citation);
  doc.InsertContent([p]);
}, true);

Dica: Teste as chamadas da API do editor no playground para verificar a sintaxe e o comportamento antes de integrar ao plugin.

Não busque dados dentro dos comandos do editor

Por que: aguardar solicitações de rede dentro de um comando congela o editor.

Exemplo (anti-padrão vs. correto):

    // Anti-pattern: async in callCommand (don't do this)
window.Asc.plugin.callCommand(async function () {
  const res = await fetch(url);
  const text = await res.text();
  Api.GetDocument().InsertContent([Api.CreateParagraph().AddText(text)]);
}, true);

// Correct: fetch in the plugin window, then pass small data
const res = await fetch(url);
const text = await res.text().then(t => t.slice(0, 200)); // trim
Asc.scope.snippet = text;
window.Asc.plugin.callCommand(function () {
  var p = Api.CreateParagraph();
  p.AddText(Asc.scope.snippet);
  Api.GetDocument().InsertContent([p]);
}, true);

Envie apenas pequenas quantidades de dados pela ponte

Por que: A ponte é otimizada para cargas JSON; strings grandes ou objetos aninhados aumentam a latência.

Mantenha o trabalho da interface do usuário e o trabalho do documento separados

Por que: Buscar, analisar e filtrar pertencem à janela do seu plugin; apenas a inserção final ocorre no comando do editor.

Segurança e redes

Os plug-ins frequentemente obtêm conteúdo de fontes externas, como feeds RSS ou APIs. Sem as verificações adequadas, você pode acidentalmente permitir a entrada de códigos maliciosos na interface do usuário do seu plug-in, encontrar erros de origem cruzada que bloqueiam solicitações ou falhar silenciosamente ao misturar HTTP e HTTPS. Um plano simples de segurança e rede evita esses problemas.

Práticas-chave, com exemplos

Limpe o HTML não confiável antes de exibi-lo

Por que: resumos ou trechos de feeds podem conter HTML que danifica sua interface do usuário ou apresenta riscos à segurança.

Exemplo:

// Quick plain-text extraction
function toPlainText(html) {
  const tmp = document.createElement("div");
  tmp.innerHTML = html;
  return tmp. textContent || "";
}
const safeText = toPlainText(untrustedHtml);

// If rendering controlled HTML, use a sanitizer (e. g., DOMPurify)
// const safeHtml = DOMPurify.sanitize(untrustedHtml);
// container.innerHTML = safeHtml;

Prefira inserir texto simples nos documentos

Justificativa: o texto simples evita a transferência inesperada de formatação e mantém as cargas úteis da ponte pequenas; reserve a formatação rica para o uso deliberado da API pelo editor.

Use HTTPS e evite conteúdo misto

Justificativa: Os navegadores bloqueiam recursos HTTP em contextos seguros; falhas silenciosas são comuns quando os terminais não são HTTPS.

Use um proxy simples para solicitações entre origens

Justificativa: muitos pontos finais não permitem acesso direto entre origens; um pequeno proxy adiciona cabeçalhos CORS e normaliza a saída.

Exemplo (esboço Node/Express):

 // Minimal CORS/normalize proxy (server-side)
import express from "express";
import fetch from "node-fetch";

const app = express();
app.get("/feed", async (req, res) => {
  try {
    const url = new URL(req.query.src);
    const r = await fetch(url.toString(), { timeout: 8000 });
    const text = await r.text();
    // Convert to normalized JSON shape server-side as needed
    res.set("Access-Control-Allow-Origin", "*");
    res.json({ items: normalizeToCommonShape(text) });
  } catch (e) {
    res.set("Access-Control-Allow-Origin", "*");
    res.status(502).json({ error: "Upstream fetch failed" });
  }
});

app.listen(3000);

Desempenho, embalagem e pré-envio

Os plug-ins são executados enquanto os usuários estão editando documentos ativamente, portanto, a capacidade de resposta é importante. Bons hábitos de desempenho, empacotamento limpo e testes completos antes do lançamento mantêm seu plug-in rápido, previsível e fácil de atualizar.

O desempenho depende de hábitos consistentes: elimine pesquisas e filtros, virtualize listas longas, pré-calcule as sequências exatas que serão inseridas para reduzir o custo por ação. Ao fechar, limpe os temporizadores, aborte as solicitações em andamento e remova os ouvintes para evitar vazamentos lentos que se acumulam ao longo das sessões.

const controller = new AbortController();
const timer = setInterval(refresh, 300000);

window.Asc.plugin.button = function () {
  controller.abort();
  clearInterval(timer);
  window.Asc.plugin.executeCommand("close", "");
};

Práticas fundamentais

  1. Agrupe seu JavaScript e CSS localmente, em vez de depender de CDNs externos.
  2. Defina seus próprios esquemas de cores claras e escuras, em vez de presumir que o editor os fornecerá.
  3. Mantenha o identificador do seu plugin (GUID) estável entre as versões para que as atualizações funcionem sem problemas.
  4. Use números de versão claros (1.0.0, 1.1.0, 2.0.0) que indiquem o que mudou.
  5. Inclua todos os ícones e metadados necessários para o Gerenciador de Plug-ins e o Marketplace.
  6. Teste com URLs semelhantes aos de produção para detectar imagens ou caminhos de script corrompidos.

Antes do envio, execute uma verificação compacta, mas rigorosa, em todos os editores compatíveis (documento, planilha, apresentação), ambientes (web e desktop), temas (claro e escuro), colaboração (inserções simultâneas), condições de rede (offline, lenta, proxy inoperante), tamanhos de conjuntos de dados (pequenos e muito grandes) e um CSP mais rigoroso, sem scripts ou estilos embutidos, para que o comportamento permaneça consistente quando usuários reais e redes reais testarem o plug-in.

Conclusão

Plugins sólidos resultam de hábitos simples: prepare os dados primeiro, faça alterações nos documentos em uma única etapa focada, higienize o conteúdo externo, encaminhe as chamadas de rede por meio de um pequeno proxy e empacote tudo localmente para que funcione da mesma forma em todos os lugares. Teste em diferentes editores, ambientes, temas e condições de rede antes de enviar, para que seu plugin se comporte de maneira previsível quando usuários reais e redes reais o colocarem em funcionamento.

Crie sua conta gratuita no ONLYOFFICE

Visualize, edite e colabore em documentos, planilhas, slides, formulários e arquivos PDF online.