Pular para o conteúdo principal
Pular para o conteúdo principal

Testei o Drupal Canvas em modo headless: o que funciona, o que quebra e onde ele se encaixa num portal B2B

Por que testar isso agora

Recentemente a Acquia anunciou uma aliança com a Vercel: o Drupal roda na Acquia Cloud Platform, o front-end JavaScript roda na Vercel e os dois conversam via Drupal Canvas Headless. A promessa é sedutora: o editor monta páginas visualmente no Canvas, edita props e vê o preview ao vivo; quem renderiza o site, porém, é um app Next.js com os seus próprios componentes.

Promessa bonita em anúncio é uma coisa. Eu queria entender o que é esse Canvas Headless na prática, o que vai para o app e o que fica no Drupal, e se a ideia aguenta um cenário mais pesado que um institucional: um portal B2B logado, com catálogo vindo de uma plataforma de commerce externa.

Então montei um laboratório local, descartável, fase por fase. Este é o resumo do que aprendi.

Imagem
Editor visual do Canvas renderizando um app headless

O laboratório

  • Drupal 11.4 em DDEV, com drupal/canvas 1.12 e o submódulo experimental canvas_headless.
  • Next.js 16 no host, criado pelo CLI oficial.
  • Uma plataforma de commerce simulada — catálogo, preço por cliente, estoque e carrinho — atrás de uma camada BFF mock.
  • Nenhum deploy e nenhuma conta externa: tudo ficou local.

O ponto principal do experimento era simples: nenhum dado de produto passa pelo Drupal. O CMS cuida da experiência editorial; o commerce continua dono do catálogo.

Dica: não confie em versão ou flag de tutorial. Esse ecossistema está mudando rápido, e várias notas de documentação e POCs da comunidade já estavam desatualizadas quando fui testar.

Imagem
Diagrama do laboratório local com CMS, app e commerce

O que é, afinal, o Canvas Headless

São três peças trabalhando juntas.

1. Lado Drupal

drupal/canvas fornece o editor e o armazenamento; canvas_headless adiciona a API de conteúdo, a tela de front-ends e os tokens de preview. O custom_elements serializa a árvore de componentes no JSON que a API devolve. simple_oauth e consumers assinam os tokens de preview.

Uma pegadinha importante: o Canvas lista alguns desses pacotes como dependências de desenvolvimento. Em um projeto real, custom_elements e simple_oauth precisam entrar explicitamente no Composer.

2. Lado npm

O SDK central é @drupal-canvas/headless. O adapter de Next fornece fetchPage(), CanvasComponentTree, as rotas de draft e o withCanvas(). O app continua sendo um Next normal, criado com uma rota catch-all que consulta o Drupal e renderiza a árvore recebida com componentes React do próprio projeto.

O app é um app normal

O scaffold traz uma rota catch-all, rotas de metadata de componentes, uma rota de draft e a configuração do Next. É isso que vai para a Vercel: app/, components/, lib/, configuração e lockfile.

Não vão node_modules, .next, .canvas nem variáveis de ambiente. Em runtime, a variável essencial é a URL do site Canvas; credenciais do CLI ficam apenas no CI, caso você use canvas push.

O template default do CLI, por outro lado, é outra proposta: envia componentes com código para renderização no próprio Drupal. No modo headless, o contrato do componente vai para o Drupal, mas o dono da renderização é o app.

Imagem
Estrutura conceitual do app headless

Como a mágica funciona

Para o visitante, o fluxo é direto: o app recebe uma URL, chama a content API do Drupal com aquele path e recebe uma árvore JSON. Cada element é mapeado para um componente React. Se o Canvas não gerencia a rota, a resposta vem sem conteúdo; falhas seguem o formato Problem Details.

O preview do editor é a parte mais elaborada. O Canvas pede ao Drupal uma assertion JWT ligada ao usuário. O iframe do app troca essa assertion por um token, grava uma sessão de preview e passa a chamar a API com Bearer token para enxergar auto-saves ainda não publicados. A sessão é renovada via postMessage antes de expirar.

Dois detalhes bons: o status Ready/Unreachable é testado no navegador do editor, então localhost funciona sem malabarismo de Docker; e há sincronização automática de componentes quando alguém com permissão abre o editor.

Imagem
Sequência de autenticação do preview do Canvas

O teste de verdade: um portal B2B logado

Site institucional é fácil. A pergunta interessante é como isso se comporta quando o usuário final faz login no portal — não no Drupal —, o Drupal é só backoffice, e catálogo, preço por cliente, estoque e pedidos vêm de outra plataforma.

Eu usei require_login para fechar o Drupal, mas a content API precisa continuar aberta para o app. A exceção por path não funcionava porque a API reescreve a requisição antes do roteamento. A saída limpa foi um módulo custom pequeno que detecta o atributo da content API no hook de avaliação do próprio require_login.

O login do portal fica no Next. O proxy bloqueia tudo sem sessão, exceto metadata de componentes, rotas de draft e preview. Isso evita que o iframe do Canvas dependa da sessão de cliente e mantém o preview separado do portal real.

Imagem
Portal B2B e preview visual do editor

Páginas de produto: quem é dono do quê

A plataforma de commerce é dona do dado. O Next é dono dos componentes. O Canvas é dono do layout.

Catálogo de dezenas de milhares de SKUs deveria viver na plataforma de commerce. Espelhar tudo no Drupal recria um pipeline de sync e a discussão eterna entre batch e real-time. Ainda assim, o editor pode rearranjar a caixa de preço, trocar uma foto ou montar a página visualmente.

O modelo que funcionou foi criar componentes externos de produto que leem os dados da rota no BFF, um template Canvas para um tipo de conteúdo Produto bem magro, nós de enriquecimento apenas quando uma página precisa de algo editorial e uma página Canvas de exceção quando um SKU precisa de layout próprio.

A busca segue a mesma lógica: produtos pela busca da plataforma de commerce, conteúdo editorial pelo Search API, ou uma busca única alimentada por ambos. Tentar fazer o Drupal indexar um catálogo que ele não possui só traz o sync de volta.

Imagem
Responsabilidades entre commerce, app e Canvas numa página de produto

Carrinho: o caso de borda que ninguém pode errar

“O preço mudou enquanto o cliente estava comprando.” No laboratório, a primeira versão do checkout atualizava a cotação e pedia confirmação quando detectava mudança. Parecia certa até a revisão adversarial: num duplo clique, o primeiro POST recusava e recotava, e o segundo podia passar por um preço que ninguém tinha visto.

A correção foi enviar uma impressão digital SHA-256 da cotação exibida — linhas, quantidades, preços e total. O checkout só fecha se ela bater exatamente com o recálculo naquele instante. Repetir uma operação aceita devolve o mesmo pedido: idempotência.

O Canvas pode posicionar botão e conteúdo editorial em torno do carrinho. A tabela de carrinho e o checkout não deveriam ser editáveis: isso é responsabilidade do app e da plataforma de commerce.

Imagem
Carrinho com proteção contra mudança de preço e reenvio

Escala, acoplamento e riscos

No experimento, cada page view fazia uma chamada ao Drupal. O SDK usa no-store e a catch-all é dinâmica; o cache interno respondeu rápido, mas com cabeçalho privado. Em produção, eu ligaria um CDN na API com purge por cache tag, ou colocaria cache com tags e webhook de revalidação no Next.

Quando o Drupal cai, rotas do app com fallback e dados de commerce ainda podem responder. Páginas 100% Canvas, não: podem virar um 404 silencioso ou 500 dependendo da falha. Isso pede 503 explícito, alerta e stale-if-error; “conteúdo aparentemente apagado” é uma experiência ruim para pessoa usuária e para monitoramento.

Pegadinhas que custaram tempo

  1. Versões de Node e pacotes do Canvas importam bastante; valide no runtime.
  2. O nome de prop precisa seguir o camelCase que o Canvas espera.
  3. canvas pull pode remover componentes locais externos: use Git limpo e backup.
  4. Template alterado pela UI e template versionado em código se desencontram. Escolha uma fonte da verdade.
  5. O módulo headless ainda é experimental; governança de quem edita templates é tão importante quanto o código.
Imagem
Diagrama de disponibilidade quando o CMS fica indisponível

Vale a pena?

Para quem quer dar autonomia visual real ao time de conteúdo sem abrir mão de um front-end moderno, sim: funciona melhor do que eu esperava. O preview dentro do editor é o próprio app, com os componentes do projeto, e isso muda a conversa com quem edita.

Mas entre com os olhos abertos. É um módulo experimental, o protocolo de preview tem várias peças e a parte difícil de um portal transacional — preço, carrinho, busca e disponibilidade — continua sendo sua.

Commerce é dono do dado. Next é dono dos componentes. Canvas é dono do layout.

O Canvas cuida muito bem do layout. O resto é engenharia de sempre.

Imagem
Três camadas: dados, componentes e layout