Skip to main content

@corvex/runtime

Bundle host que a plataforma injeta ao compilar temas. Não é um pacote npm — importe @corvex/runtime nos arquivos do tema. Contrato de dados da loja: @corvex/theme-sdk. Esta página cobre vitrine, integração com o Editor e boas práticas para quem implementa sections com blocks.

Runtime como proxy do builder

O editor usa um motor interno de árvore de blocos (implementação da plataforma). Temas não importam esse motor. @corvex/runtime é o proxy Corvex: hooks e componentes que leem o estado da section no builder, espelham blocks / block_order nos props e permitem preview ao vivo na vitrine do canvas. Quem cria o tema escolhe como compor a section — Padrão A ({children}), B (marquee / settings), C (grade com RepeatedBlockCard), ou layout customizado montado com os mesmos exports desta página. Não há lista fechada de “permitido”: há ferramentas documentadas e contratos (blocks, block_order, schema.json). Limite de fronteira (código do tema): não importe o motor do editor, não declare propriedade estática no componente e não importe caminhos internos da plataforma. Fora isso, combine os símbolos desta página como o plano do tema exigir.
Importe somente os símbolos listados em PUBLIC_THEME_API e PUBLIC_EDITOR_INTEGRATION. APIs marcadas como INTERNAL podem quebrar entre versões do editor.

Regras de ouro (agências e LLMs)

  1. Dados da loja → @corvex/theme-sdk (usePage, useCorvexCart, defineSectionData, …).
  2. Chrome do Editor e blocks ao vivo → @corvex/runtime (esta página).
  3. Nunca importe paths internos da plataforma, hooks não documentados aqui ou pacotes que o host já substitui (react continua vindo do host no bundle).
  4. Mesma árvore visual no canvas do builder, em /preview e na vitrine — o inspect do editor não deve trocar layout, grid ou carrossel.
  5. Sections com blocks têm dois padrões (A e B abaixo) — nunca misture {children} no editor com cards montados manualmente a partir de blocks/block_order.
  6. Integração com o builder só via @corvex/runtime e @corvex/theme-sdk. Não importe o motor do editor nem código interno da plataforma.
  7. Depois de alterar JSX de section/block: corvex validate . → corvex build . → corvex sync . → hard refresh no builder.

Onde o tema roda

Use useEditorPreviewCanvas() para saber se está no iframe do builder — não confunda com “qualquer preview”.

PUBLIC_THEME_API (vitrine)

Use na loja publicada, em /preview e sempre que não precisar de estado ao vivo do editor: Preferir hooks direto de @corvex/theme-sdk quando não precisa do re-export runtime.

PUBLIC_EDITOR_INTEGRATION (Builder)

Componentes

SectionBlockCanvas e BlockCanvas são <div> de layout — a plataforma garante que os blocks filhos participem do flex/grid do tema. Renderize {children} uma vez dentro do canvas correspondente. BlockCanvasRoot é INTERNAL. Bloco contêiner ≠ grupo de layout (layoutGroups). Contrato: Block Contract. Cookbook: Colunas agrupadas.

Hooks — qual usar?

useBuilderBlockEditLayout() existe por compatibilidade e sempre retorna false. Não altere layout, autoplay ou carrossel com base nele — o tema é WYSIWYG.

Padrão A — blocks renderizados com {children}

Slides, FAQ, grid de depoimentos, qualquer layout onde cada block é um componente React (blocks/testimonial-card/block.jsx, etc.).
Blocks fantasma: se no canvas do editor você montar cards com blocks.map() / block_order porque {children} veio vazio, esses cards não pertencem ao editor. A reordenação na árvore lateral pode funcionar, mas arrastar no canvas não persiste e seleção/inline edit quebram. No iframe do builder use sempre {children} — a plataforma gerencia blocks e drag-and-drop.O mesmo vale para banners padrão no JSX (if (!children) return DEFAULT_SLIDES). Isso não é Theme Default: some no primeiro block real e não é inspecionável. Looks iniciais = templates/*.json. theme-defaults.

Grid de depoimentos (canônico)

Carrossel com slides (blocks)

Boas práticas
  • Editor canvas: {children} sempre — nunca blocks.map() quando useEditorPreviewCanvas() é true.
  • Contagem: useSectionBlockCount() — não Children.count(children).
  • Renderize {children} uma única vez — sem cópia oculta para “modo editor”.
  • Classe de card/slide no block, não em wrapper manual em cima de {children}.
  • Autoplay e gestos: implemente no tema; a plataforma não fornece carrossel global.
Cookbooks: Slider · FAQ

Padrão B — blocks lidos sem {children} (marquee / faixa)

Somente quando a section nunca monta cada block como filho React — ex.: promo-bar que lê textos e desenha uma faixa animada, ou carrossel de vídeo onde o JSX monta <video> a partir de settings do block.
Se cada block tem block.jsx visível (depoimento, slide, FAQ item), isso é Padrão A — use {children} no editor. useSectionLiveBlocks() não substitui {children} nesses casos.

Padrão C — grade de produtos (card repetido por bloco)

Quando o lojista monta o card (imagem, título, preço…) com blocos e cada produto da grade deve repetir a mesma composição:
  1. A section busca produtos (useCorvexData ou defineSectionData).
  2. Por produto: Provider de contexto + função que itera block_order e renderiza o componente de cada blocks[id].type.
  3. No builder: RepeatedBlockCard (editorHost no primeiro card + renderMirror nos demais) e useSectionBlockTemplate(blocks, block_order) para o molde ao vivo.
  4. Blocks de catálogo não fazem fetch — leem o produto do contexto.
  5. No tema: @corvex/runtime e @corvex/theme-sdk. Não importe o motor do editor.
Não confunda com Product Card (snippet) nem com seções product-list que importam snippet fixo. Cookbook completo: Grade com blocos de catálogo.

useSectionBlockTemplate(blocks, block_order)

Retorno: { blocks, block_order } — no builder, settings e ordem ao vivo (proxy sobre o estado interno da section); na vitrine, os props serializados. Atalho para grades e qualquer loop que repete o molde de blocos. Equivalente de baixo nível: useSectionLiveBlocks() + merge com os props da section.

RepeatedBlockCard

Props: editorHost (boolean), className, children (repasse da section), renderMirror (função que retorna o JSX espelhado). Encapsula o par card âncora no builder + cards espelhados em listas repetidas (ex.: grade de produtos). Se o layout do tema for atípico, monte o mesmo comportamento com SectionBlockCanvas, {children} e useSectionBlockTemplate — a plataforma continua responsável pelo espelho nos props.

useSectionLiveBlocks()

Retorno: Use quando a section monta UI a partir de settings de cada block (vídeo, texto+link, ou grade que repete blocks por produto) e não repassa {children} na vitrine visível. Na vitrine/publicado, leia blocks + block_order das props (ou defaults do template) — liveItems reflete o estado ao vivo no editor. Cada entrada em blocks deve ter type estável (ex.: catalog-product-title). O name do schema.json do block é label no editor, não substitui type na serialização.

useSectionBlockMessages()

Retorno: array estável de { text, link? } extraído dos blocks — ideal para promo-bar / ticker com blocks só de texto.

Marquee — atributos obrigatórios

CSS do tema: @keyframes + variável --marquee-duration. Guia: Carrossel de vídeos.

Blocks — adicionar, remover e reordenar

A plataforma oferece o painel Itens no inspetor lateral quando a section tem sections/{id}/blocks.json. O lojista:
  • clica em Adicionar para criar um block (respeitando max_blocks);
  • arrasta pelo ícone ≡ para reordenar;
  • clica em um item para selecioná-lo no canvas;
  • remove com o botão de lixeira.
Responsabilidade do tema: refletir a ordem na UI — não implemente drag-and-drop próprio no canvas. No canvas, com inspecionar ativo, a plataforma desenha a linha de soltura e persiste o movimento. A árvore lateral (Itens / seções) e o canvas devem produzir o mesmo block_order / ordem de sections.
Sintoma clássico (ex.: grid de depoimentos): reordenar na árvore lateral funciona, mas arrastar cards no canvas não salva. Causa: cards montados manualmente com blocks/block_order no editor em vez de {children} (blocks fantasma). Correção: Padrão A — grid de depoimentos. Antes de culpar o editor, confirme que o canvas do builder renderiza {children} dentro de SectionBlockCanvas.

Manifest da section

Registre cada type em theme.json → blocks[]. Ver Blocks.

Ordem persistida

Cada instância na página guarda:

Defaults no template

Após reordenar no builder, salve o rascunho — a aba Preview lê o block_order persistido.

Edição inline — duplo clique no canvas

Campos text / textarea podem ser editados direto no canvas com duplo clique, além do inspetor lateral.

Pré-requisito no builder

  1. Ative o modo Inspecionar / Selecionar na barra do editor.
  2. Selecione a section ou o block desejado (opcional, mas recomendado).
  3. Duplo clique no texto — entra em edição; Esc cancela; Enter confirma (linha única); clique fora (blur) salva.
Fora do builder (/preview, vitrine) os componentes renderizam texto estático — sem placeholder de edição.

Settings da section — InlineText

Use propKey = id do field no schema.json (gravado nos props da section no editor).
Leia settings dos props flat (props.title) ou de props.settings — a plataforma pode passar ambos conforme o ambiente. Normalize no topo da section como no exemplo.

Settings do block — BlockInlineText

Use dentro de blocks/{id}/block.jsx. Grava em settings[fieldKey].

Quando não usar inline

Campos editáveis no inspetor sempre funcionam — InlineText / BlockInlineText são opcionais para UX de duplo clique.

Padrão C — texto inline (resumo)

Ver seção Edição inline — duplo clique acima. Envolva a section com SectionChrome e declare os mesmos ids no schema.json.

Checklist antes de publicar

  1. Canvas do builder — section visível; blocks adicionáveis na sidebar.
  2. /preview em nova aba — mesmo visual; sem classes exclusivas de “modo editor” forçadas no JSX.
  3. Vitrine — conteúdo vem de blocks/block_order ou settings, não só de estado ao vivo do editor.
  4. corvex validate . — schemas e manifest OK.
  5. corvex build . — bundle compila sem erro.
  6. corvex sync . — código sobe para a loja vinculada.
  7. Hard refresh no builder após deploy de nova API do runtime no editor.

Anti-padrões

Sintomas comuns (banner vazio, carrossel com 1 slide, loop infinito de render): Section Contract — blocks · cookbooks acima.

INTERNAL (não usar em temas)

Sem garantia de compatibilidade — não importe estes símbolos no tema: GenericInspector, SectionInspector, BlockSettingsInspector, BlockCanvasRoot, hooks internos de edição legados, useEditorViewport, … Prefira arquitetura declarativa (React + CSS) documentada nos cookbooks.

Referência rápida de imports

Dados e loaders continuam em @corvex/theme-sdk:

Veja também