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

# Blocos Custom code

> O bloco Custom code do Aftersell Cart: adicione seu próprio HTML ou React em qualquer lugar do drawer, inclusive dentro de Cart items.

> O bloco **Custom code** adiciona seu próprio HTML ou React ao carrinho. Coloque-o em qualquer seção do drawer, ou aninhe-o dentro de [**Cart items**](/pt/aftersell/cart/cart-items-block) como um sub-bloco para que ele se repita em cada linha. Diferente de outros blocos, ele não tem configurações de Content nem seção de Design: o bloco *é* o código, então você trabalha inteiramente na aba **Code** dele.

<Frame>
  <img src="https://mintcdn.com/aftersell/1Y3gBpUfxv16VGSW/images/aftersell/cart-custom-code-block-add-and-enable.gif?s=6717cc64a8765b0c06b65990f99e12ff" alt="Pré-visualização animada de adicionar e ativar um bloco Custom code no editor do Aftersell Cart" title="Pré-visualização animada de adicionar e ativar um bloco Custom code no editor do Aftersell Cart" width="1200" height="558" data-path="images/aftersell/cart-custom-code-block-add-and-enable.gif" />
</Frame>

<div id="add-and-turn-on-a-custom-code-block">
  ## Adicionar e ativar um bloco Custom code
</div>

1. Adicione um bloco **Custom code** a qualquer seção, ou como sub-bloco sob **Cart items**.
2. Selecione-o e abra a aba **Code**.
3. Escolha **HTML** ou **React component**. Blocos novos vêm por padrão em HTML.
4. Escreva seu código.
5. Se você escolheu React, clique em <span style={{display:'inline-flex',alignItems:'center',gap:'4px',background:'#1C1C1C',color:'#fff',border:'1px solid #0A0A0A',borderRadius:'4px',padding:'0 6px',fontSize:'0.85em',fontWeight:500,lineHeight:'1.4em',verticalAlign:'middle'}}><svg width="8" height="9" viewBox="0 0 10 12" fill="none" aria-hidden="true" style={{display:'block'}}><path d="M1.5 1.2v9.6L8.8 6 1.5 1.2Z" stroke="#fff" strokeWidth="1.5" strokeLinejoin="round" /></svg>Compile</span>.
6. Ative **"Use custom template"**. Para este bloco, esse botão significa "mostrar meu código personalizado", e ele vem desativado por padrão, então nada é renderizado até que você o ative.
7. Mantenha o botão de olho da barra lateral ativado para que o bloco permaneça visível aos compradores.

Tanto o botão de olho quanto **"Use custom template"** precisam estar ativados para o bloco aparecer.

<div id="behavior">
  ## Comportamento
</div>

* O bloco não renderiza nada até o carrinho ter carregado.
* Ele também não renderiza nada quando o olho da barra lateral está desativado, **"Use custom template"** está desativado, o código está vazio, ou o React falha ao compilar ou renderizar. Como uma falha é silenciosa, verifique seu bloco na [pré-visualização](/pt/aftersell/cart/previewing-carts) antes de publicar.

<div id="html-mode">
  ## Modo HTML
</div>

O modo HTML substitui um pequeno conjunto de tokens na sua marcação. Ele serve para conteúdo estático ou baseado em tokens, não para executar lógica.

* **Tags `<script>` inline não executam**, e o modo HTML **não tem acesso ao SDK nem a `window`.**
* Para lógica, use o [**modo React**](#react-mode) ou [Scripts personalizados](/pt/aftersell/cart/custom-scripts) com o [Cart SDK](/pt/aftersell/cart/sdk-overview).

<div id="tokens">
  ### Tokens
</div>

Os valores dos tokens são **strings formatadas** (formato de moeda da loja, um percentual com `%` ou uma quantidade), prontas para inserir na marcação:

| Token                    | O que mostra                                                       |
| ------------------------ | ------------------------------------------------------------------ |
| `{{pre_cart_total}}`     | Total do carrinho antes dos descontos.                             |
| `{{post_cart_total}}`    | Total do carrinho depois dos descontos.                            |
| `{{savings_amount}}`     | Valor economizado (total pré-desconto menos total pós-desconto).   |
| `{{savings_percentage}}` | Economia em percentual, incluindo o sinal `%` (por exemplo `15%`). |
| `{{cart_quantity}}`      | Número de itens visíveis no carrinho.                              |

<div id="example">
  ### Exemplo
</div>

```html theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
<div class="cart-external-custom-code_html">
  You saved {{savings_amount}} ({{savings_percentage}})
</div>
```

<div id="react-mode">
  ## Modo React
</div>

O modo React compila um componente e passa a ele os dados do carrinho mais uma ação de `add-to-cart`.

* O editor trava o wrapper em `function CustomCode(props: CustomCodeProps) { … }`, e você edita apenas o corpo entre essas linhas.
* Você precisa clicar em <span style={{display:'inline-flex',alignItems:'center',gap:'4px',background:'#1C1C1C',color:'#fff',border:'1px solid #0A0A0A',borderRadius:'4px',padding:'0 6px',fontSize:'0.85em',fontWeight:500,lineHeight:'1.4em',verticalAlign:'middle'}}><svg width="8" height="9" viewBox="0 0 10 12" fill="none" aria-hidden="true" style={{display:'block'}}><path d="M1.5 1.2v9.6L8.8 6 1.5 1.2Z" stroke="#fff" strokeWidth="1.5" strokeLinejoin="round" /></svg>Compile</span> e depois ativar **"Use custom template"**, antes que o bloco apareça.
* Seu componente pode usar `useState`, `useEffect`, `useMemo`, `useRef` e `useCallback`.
* Diferente do modo HTML, o React roda no contexto da página, então pode chamar `window` e o [Cart SDK](/pt/aftersell/cart/sdk-overview) quando estão disponíveis.
* Se o seu componente lançar erros em tempo de execução, o bloco não renderiza nada e o resto do carrinho continua funcionando.

<div id="props">
  ### Props
</div>

Totais e valores de economia são inteiros na [unidade menor](/pt/aftersell/cart/sdk-actions#formatmoneycents) da moeda (centavos para USD), então `$12.50` é `1250`, não `12.50`. Eles não são strings de dinheiro formatadas como os tokens HTML.

| Prop                                            | Tipo                        | Descrição                                                                                                                                    |
| ----------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `cart`                                          | `AftersellCart`             | O carrinho atual. Veja a [referência do objeto de carrinho](/pt/aftersell/cart/sdk-cart-object).                                             |
| `line`                                          | `AftersellCartLine \| null` | Definida apenas quando o bloco é um sub-bloco de Cart items (uma renderização por linha); `null` em uma seção.                               |
| `preCartTotal`                                  | `number`                    | O total do carrinho **antes dos descontos** (`original_total_price` da Shopify), na unidade menor da moeda (por exemplo, centavos).          |
| `postCartTotal`                                 | `number`                    | O total do carrinho **depois dos descontos**, na unidade menor da moeda.                                                                     |
| `savings`                                       | `{ amount, percentage }`    | Valor e percentual da economia.                                                                                                              |
| `addProduct(variantId, quantity?, properties?)` | `function`                  | Adiciona um produto ao carrinho, marcado com a atribuição deste bloco para que o [analytics](/pt/aftersell/cart/analytics) possa creditá-lo. |

<div id="the-cart-and-line-shapes">
  ### As estruturas de cart e line
</div>

`cart` e `line` são os mesmos objetos que o SDK expõe em todos os outros lugares, então são documentados uma única vez na **[referência do objeto de carrinho](/pt/aftersell/cart/sdk-cart-object)**: cada campo do carrinho, de uma linha e de um bundle.

Os que você vai usar com mais frequência: `cart.items`, `cart.itemCount`, `cart.totalPrice`, `line.title`, `line.quantity`, `line.finalLinePrice`.

Três coisas específicas deste bloco:

* **`line` só é definida em um sub-bloco de Cart items**, onde seu componente é renderizado uma vez por linha. Colocado como seção, `line` é `null` e você lê `cart.items` em vez disso.
* **Filhos de bundle não estão em `cart.items`.** Quando as linhas são [agrupadas em um bundle](/pt/aftersell/cart/sdk-use-case-bundles), apenas a linha âncora aparece; seus filhos ficam em `line.bundle.children`.
* **Linhas ocultadas por um [line transform](/pt/aftersell/cart/sdk-hooks#registerlinetransform) também não estão lá**, embora ainda contem para `cart.totalPrice`.

<div id="examples">
  ### Exemplos
</div>

Exibir a contagem de itens:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  return (
    <div className="cart-external-custom-code_jsx">
      {props.cart.itemCount} items
    </div>
  );
}
```

Como sub-bloco de Cart items, use `props.line` para conteúdo por produto. O bloco é renderizado uma vez por linha, marcado com o produto e a variante daquela linha:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  if (!props.line) return null;
  return (
    <div className="cart-external-custom-code_jsx">
      {props.line.productTitle}
      {props.line.variantTitle ? ` · ${props.line.variantTitle}` : ''}
    </div>
  );
}
```

<div id="reading-enrichment-metadata">
  ### Lendo metadados de enriquecimento
</div>

Cada item em `cart.items` carrega um campo `metadata`: um objeto vazio `{}` até que um [cart enricher](/pt/aftersell/cart/sdk-hooks#registercartenricher) o preencha. Uma vez preenchido, ele é indexado pelo `id` do enricher e contém os dados da Storefront para o produto ou variante daquela linha:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  return (
    <ul>
      {(props.cart.items ?? []).map((item) => {
        const note = item.metadata?.shipping?.shippingNote;
        return (
          <li key={item.key}>
            {item.title}
            {note ? ` · ${note.value}` : ''}
          </li>
        );
      })}
    </ul>
  );
}
```

`metadata` está sempre presente e tem como padrão um objeto vazio `{}` até que a busca assíncrona do enricher seja concluída (o teste de "ainda não enriquecido" é `Object.keys(item.metadata).length === 0`). Use encadeamento opcional (`item.metadata?.enricherId`) ao ler a chave de um enricher específico, já que essa chave está ausente até o enriquecimento chegar.

<div id="reading-discount-codes-and-line-discounts">
  ### Lendo códigos de desconto e descontos de linha
</div>

`cart.discountCodes` lista os códigos de desconto aplicados ao carrinho, e o `discountAllocations` de cada linha lista os descontos aplicados àquela linha específica:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  const codes = props.cart.discountCodes;
  return (
    <div>
      {codes.length > 0 && (
        <p>Active discounts: {codes.join(', ')}</p>
      )}
      <ul>
        {(props.cart.items ?? []).map((item) => {
          return (
            <li key={item.key}>
              {item.title}
              {item.discountAllocations.map(
                (discount) => ` · ${discount.title} (-${(discount.amount / 100).toFixed(2)})`
              )}
            </li>
          );
        })}
      </ul>
    </div>
  );
}
```

<div id="placement-and-limits">
  ## Posicionamento e limites
</div>

* **Região:** qualquer uma (topo, corpo ou parte inferior). Também disponível como sub-bloco de Cart items.
* **Máximo:** ilimitado.
* **Estado:** carrinho cheio e vazio (como bloco de seção). Como sub-bloco de Cart items, só é renderizado quando o carrinho tem linhas, uma instância por linha.
* Não é bloqueado, então você pode removê-lo ou ocultá-lo.
* Não há seção de Design por bloco. Estilize por meio da sua própria marcação, do [**CSS personalizado**](/pt/aftersell/cart/custom-css) e das suas [**Configurações de design**](/pt/aftersell/cart/design-settings) globais.

<div id="when-to-use-custom-code-block-vs-custom-template-vs-custom-script">
  ## Quando usar bloco custom code vs. template personalizado vs. script personalizado
</div>

|                                                                   | O que faz                                                                                     | Quando usar                                                                      | Exemplo                                                                                                                                                                                  |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Bloco Custom code**                                             | Adiciona um *novo* bloco com seu próprio HTML ou React.                                       | Algo que os blocos nativos não cobrem.                                           | Uma linha de total estimado que soma sua taxa fixa de frete ao total do carrinho, ou uma contagem regressiva de prazo de entrega acima do botão de checkout.                             |
| **[Template personalizado](/pt/aftersell/cart/custom-templates)** | Substitui a renderização de um bloco *existente* pelo seu JSX, usando os dados daquele bloco. | O bloco nativo está quase certo, mas você precisa de uma marcação diferente.     | Reconstruir a [linha Product](/pt/aftersell/cart/cart-items-block#custom-template) para que o nome da variante, a economia e o seletor de quantidade fiquem em uma única linha.          |
| **[Script personalizado](/pt/aftersell/cart/custom-scripts)**     | Executa JavaScript no carrinho por meio do [Cart SDK](/pt/aftersell/cart/sdk-overview).       | Lógica, eventos e configuração de todo o carrinho, em vez de marcação do drawer. | Gaste \$75 e ganhe uma sacola grátis: [adicione o brinde](/pt/aftersell/cart/sdk-use-case-free-gift) quando o carrinho ultrapassar o limite, e retire-o se o comprador cair abaixo dele. |
