> ## Documentation Index
> Fetch the complete documentation index at: https://docs-loja.usecorvex.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Block Contract

> Contrato de um Block — arquivos, schema, props e relação com a Section.

Um **block** é um subcomponente editável **dentro** de uma section — por exemplo um título, parágrafo ou item de FAQ.

***

## Arquivos do block

Para cada ID em `theme.json` → `blocks`:

| Arquivo | Obrigatório? |
| - | - |
| `blocks/{id}/block.jsx` | Sim |
| `blocks/{id}/schema.json` | Sim |
| `blocks/{id}/blocks.json` | Só no **bloco contêiner** |

***

## Registro no tema

1. O ID precisa estar em `theme.json` → `blocks[]`.
2. `block.jsx` exporta o componente como **default export**.
3. Convém nomear `{PascalCase}Block` — ex.: `heading` → `HeadingBlock`.

***

## `schema.json`

| Campo | Obrigatório? |
| - | - |
| `type` | Convém ser igual ao ID da pasta |
| `name` | Sim — label no inspector **e** identidade do nó na página salva. Depois do primeiro `corvex sync`, não altere (sem “legado”, “v2”, tradução). O ID estável é `type` / pasta. |
| `settings` | Opcional — campos editáveis |

Blocks não precisam de `category`.

***

## Props do componente

| Prop | O que é |
| - | - |
| `settings` | Valores do lojista — sempre dentro de `settings` |
| `isEditing` | Opcional — edição inline no preview |
| `onSettingsChange` | Opcional — `(patch) => void` com `isEditing` |

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
export default function HeadingBlock({ settings = {} }) {
  const Tag = settings.level === 'h3' ? 'h3' : 'h2';
  return <Tag>{settings.text || 'Título'}</Tag>;
}
```

Não use props na raiz (`text`, `level` direto) — tudo fica em `settings.*`.

Valores iniciais de **campo**: `default` em cada setting do `schema.json`, como nas sections.

Looks iniciais da **lista** (vários slides na home): `templates/*.json` com `blocks` + `block_order`, não um array no JSX. [theme-defaults](https://docs-loja.usecorvex.com.br/guides/theme-defaults.md).

***

## Section que aceita blocks

### Manifest (`sections/{id}/blocks.json`)

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "blocks": [{ "type": "heading" }, { "type": "text" }],
  "max_blocks": 12
}
```

* `blocks[].type` precisa corresponder a um block registrado no tema.
* `max_blocks` é opcional — limite de instâncias na section.
* `corvex build` (≥ 2.3.4) anexa este arquivo no bundle. **Não** importe `blocks.json` no `section.jsx` e **não** declare propriedade estática no componente.

### Instância na página

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "hero",
  "settings": { "height": "large" },
  "blocks": {
    "b1": { "type": "heading", "settings": { "text": "Título", "level": "h2" } }
  },
  "block_order": ["b1"]
}
```

* `block_order` define a ordem de renderização.
* O lojista reordena blocks no painel **Itens** do editor (arrastar ≡). Na vitrine, itere `block_order` — ver [Runtime API](https://docs-loja.usecorvex.com.br/reference/runtime-api.md#blocks-—-adicionar,-remover-e-reordenar).

***

## Bloco contêiner (grupo)

Um bloco com `blocks/{id}/blocks.json` aceita **filhos diretos** (um nível extra). O tipo vive no tema (`blocks/group/` ou equivalente) — a plataforma não impõe um `group` no host.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
// blocks/group/blocks.json
{
  "blocks": [{ "type": "text" }],
  "max_blocks": 12
}
```

* Mesmo formato do manifest da seção. `corvex build` anexa `blockManifest` no componente do bloco.
* Fase 1: o contêiner **não** pode listar outro contêiner. `corvex validate` rejeita isso.
* No JSX do contêiner, `{children}` dentro de `BlockCanvas` (`@corvex/runtime`). Sem `.map` de filhos.
* Isto não é [grupo de layout](https://docs-loja.usecorvex.com.br/reference/contracts/theme.md) (`layoutGroups`): aquele organiza seções globais.

### Instância aninhada

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "grouped-columns",
  "settings": {},
  "blocks": {
    "g1": {
      "type": "group",
      "settings": { "direction": "column" },
      "blocks": {
        "t1": { "type": "text", "settings": { "text": "Join the club" } }
      },
      "block_order": ["t1"]
    }
  },
  "block_order": ["g1"]
}
```

Bloco sem `block_order` (ou array vazio) é folha. Cookbook: [Colunas agrupadas](https://docs-loja.usecorvex.com.br/cookbook/grouped-columns.md).

***

## Edição inline no canvas (opcional)

Para campos `text` / `textarea`, use `BlockInlineText` de `@corvex/runtime` — duplo clique no builder com **Inspecionar** ativo:

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { BlockInlineText } from '@corvex/runtime';

export default function HeadingBlock({ settings = {} }) {
  return (
    <BlockInlineText
      fieldKey="text"
      tag="h2"
      value={settings.text || 'Título'}
    />
  );
}
```

`fieldKey` = `id` do field no `schema.json` do block. Detalhes: [Runtime API — edição inline](https://docs-loja.usecorvex.com.br/reference/runtime-api.md#edição-inline-—-duplo-clique-no-canvas).

***

## O que evitar

* Usar o mesmo ID como section e block sem registrar ambos explicitamente.
* Contêiner dentro de contêiner (mais de um nível extra) — fora da fase 1.
* Tipos de campo fora da lista estável ([Schema overview](https://docs-loja.usecorvex.com.br/schema/overview.md)).
* Mudar o id da pasta / `type` depois que há páginas. `name` é rótulo e pode mudar. Detalhe: [Section Contract — identidade](https://docs-loja.usecorvex.com.br/reference/contracts/section.md#identidade-type-estável-name-livre).

***

## Exemplo mínimo válido

`blocks/heading/schema.json`:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "heading",
  "name": "Título",
  "settings": [
    { "id": "text", "type": "text", "label": "Texto", "default": "Título" },
    {
      "id": "level",
      "type": "select",
      "label": "Nível",
      "default": "h2",
      "options": [{ "value": "h2", "label": "H2" }, { "value": "h3", "label": "H3" }]
    }
  ]
}
```

`blocks/heading/block.jsx`:

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
export default function HeadingBlock({ settings = {} }) {
  const Tag = settings.level === 'h3' ? 'h3' : 'h2';
  return <Tag>{settings.text}</Tag>;
}
```

`theme.json` → `"blocks": [ "heading", … ]`

***

## Veja também

* [Section Contract](https://docs-loja.usecorvex.com.br/reference/contracts/section.md)
* [Schema overview](https://docs-loja.usecorvex.com.br/schema/overview.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.