Pular para o conteúdo

Kits Nativos da Plataforma

O Kit Nativo da Plataforma é a implementação de kit usada quando um produto principal representa um conjunto de itens que precisam ser comprados juntos. Nesse modelo, a compra não depende apenas do SKU do produto principal: a página precisa resolver também o SKU de cada item interno do kit antes de enviar a compra ao carrinho.

Este guia explica a lógica de kit nativo da plataforma sem depender de acesso à estrutura padrão do template. Os exemplos de código abaixo usam a semântica esperada pelo fluxo de kit: bundle, product-block-bundle, data-bundle-section, data-product-box, data-quickview-type, data-main-bundle-product-id e data-bundle-add.

📘 Demonstração do componente

Se você precisar resumir a implementação do kit nativo em poucas regras, são estas:

  1. O produto principal precisa ser tratado como kit nativo da plataforma.
  2. A página precisa conhecer os produtos internos do kit.
  3. Cada item interno precisa resolver um sku válido antes da compra final.
  4. A compra envia o SKU principal do kit e a lista bundle_skus[].
  5. Se qualquer item exigir personalização, a compra em bloco deve ser bloqueada.

Uma implementação correta de kit nativo precisa resolver quatro partes:

  • Liquid: identifica que o produto é um kit, carrega os produtos internos e renderiza um bloco para cada item.
  • Seleção de variantes: garante que cada item interno exponha um name="sku" com o SKU escolhido.
  • JavaScript de compra: lê o SKU principal, coleta os SKUs internos e monta bundle_skus[].
  • Carrinho: recebe POST /carrinho/adicionar com sku, quantity e bundle_skus[].

O quickview pode ser usado para carregar o formulário dos itens internos sob demanda, mas não é obrigatório. O requisito obrigatório é que, no momento do clique em data-bundle-add, todos os blocos data-product-box tenham um name="sku" válido.

Um kit nativo da plataforma é um produto principal que representa um conjunto de itens comprados em uma única operação. Tecnicamente, esse produto é identificado na plataforma como product_type == 'bundle'. Ele não é comprado como um item simples: a compra só é válida quando o frontend consegue montar o conjunto completo da operação.

Na prática, o kit nativo depende de três elementos:

  • Um produto principal do kit;
  • Uma lista de produtos internos;
  • Uma forma de resolver o SKU selecionado de cada item interno.

A lógica de kit nativo deve ser usada quando:

  • A PDP representa um kit como produto principal;
  • Os itens internos fazem parte da composição obrigatória da compra;
  • A escolha de variante dos itens internos é necessária;
  • O carrinho precisa receber uma compra consolidada do kit.

Se a necessidade for apenas sugerir produtos opcionais, o fluxo correto não é kit nativo, e sim um recurso como compre junto.

Antes de implementar o kit nativo, valide se estes elementos existem no seu contexto:

RequisitoMotivo
identificação de que o produto atual é um kit nativoativa o fluxo correto da PDP
lista dos produtos internos do kitdefine quais itens compõem a compra
SKU principal do kitnecessário para o payload final
dados suficientes para selecionar a variante de cada item internosem isso não é possível gerar bundle_skus[]
regra clara para itens com personalizaçãodefine quando a compra deve ser bloqueada

A implementação do kit nativo precisa respeitar estas regras:

  1. O produto principal deve entrar em um fluxo específico de kit nativo.
  2. A página deve exibir os produtos internos do kit nativo.
  3. Cada item interno precisa permitir resolver uma variante válida.
  4. A compra do kit só pode acontecer depois que todos os SKUs internos forem resolvidos.
  5. O carrinho deve receber o SKU principal do kit e a lista bundle_skus[].
  6. Se qualquer item do kit exigir personalização, a compra em bloco deve ser bloqueada.
  7. O kit nativo não deve ser tratado como uma simples extensão da compra padrão de um produto comum.

Para implementar o kit nativo corretamente, a lógica de frontend precisa ter acesso, no mínimo, aos seguintes dados:

DadoUso
indicador de que o produto é kit nativoativa o fluxo de kit
lista dos produtos internosdefine os itens que precisam participar da compra
SKU principal do kitpreenche o campo sku do payload
SKU selecionado de cada item internopreenche bundle_skus[]
tags ou metadados de personalizaçãopermitem bloquear a compra em bloco quando necessário

O fluxo funcional do kit nativo pode ser resumido assim:

  1. identificar que o produto atual é um kit nativo;
  2. trocar a compra comum pela compra de kit nativo;
  3. carregar ou renderizar os produtos internos;
  4. permitir a seleção de variante de cada item interno;
  5. resolver o sku de cada item;
  6. montar o payload do carrinho;
  7. enviar a compra;
  8. abrir o carrinho em caso de sucesso.

Na lógica de kit nativo, o payload enviado ao carrinho contém:

  • sku: SKU do produto principal do kit;
  • quantity: quantidade do kit;
  • bundle_skus[]: lista dos SKUs selecionados dos produtos internos.

Exemplo do payload:

sku=KIT-PRINCIPAL
quantity=1
bundle_skus[]=SKU-ITEM-1
bundle_skus[]=SKU-ITEM-2
bundle_skus[]=SKU-ITEM-3

Esse envio é feito para:

POST /carrinho/adicionar

com Content-Type: application/x-www-form-urlencoded.

A lógica de compra do kit nativo deve prever estes cenários:

  • Se a resposta vier com 202, o frontend precisa respeitar o Retry-After e tentar novamente;
  • Se a resposta vier com erro, o botão do kit deve entrar em estado de falha ou indisponibilidade temporária;
  • Se a resposta for bem-sucedida, o carrinho deve ser aberto ou atualizado.

Se qualquer item interno do kit exigir personalização, a compra em bloco deve ser desabilitada.

Essa regra existe porque, nesse caso, a compra do item depende de uma etapa extra de preenchimento ou validação que não pode ser resolvida apenas com a consolidação de SKUs.

Na prática, isso significa:

  • O kit continua sendo exibido;
  • Os itens internos continuam visíveis;
  • O botão final do kit fica indisponível;
  • O usuário precisa adicionar os itens individualmente.

Esses dois fluxos agrupam produtos, mas não são a mesma funcionalidade.

RecursoComo funcionaEndpoint principal
kit nativo da plataforma (bundle)produto principal com compra consolidada por SKU principal + bundle_skus[]POST /carrinho/adicionar
compre juntoseleção manual de produtos relacionados, normalmente enviada como lista de items[]POST /carrinho/adicionar/kit

Se a dúvida for sobre um kit cadastrado como produto principal, o fluxo correto é o de kit nativo.

O kit nativo não deve ser tratado como solução genérica para qualquer agrupamento de produtos.

Na implementação de kit nativo, ele não faz estas coisas automaticamente:

  • Não substitui o fluxo de compre junto;
  • Não resolve personalização dos itens internos;
  • Não dispensa a seleção de variante dos produtos internos;
  • Não reutiliza a compra simples de um produto comum sem adaptação;
  • Não usa o endpoint de items[] do compre junto.

Mesmo fora de uma estrutura padrão, uma implementação de kit nativo precisa manter esta separação lógica:

  • Um container principal do kit;
  • Um campo com o SKU principal;
  • Uma lista de blocos dos itens internos;
  • Um mecanismo para resolver a variante de cada item interno;
  • Um botão final que consolida os SKUs internos e dispara a compra.

Se você estiver construindo o kit manualmente, o frontend precisa conseguir localizar:

  • Um container principal do kit;
  • Um input oculto com o SKU principal;
  • Um bloco por item interno;
  • Um input name="sku" resolvido dentro de cada item interno;
  • Um botão final para adicionar o kit;
  • Uma forma de bloquear ou sinalizar kits com personalização.

Mesmo em uma implementação customizada, o kit nativo precisa preservar um contrato mínimo entre a marcação HTML e a lógica de compra.

Sem esse contrato, o JavaScript não consegue identificar o kit nem montar bundle_skus[] de forma confiável.

ElementoPapel na compra
container principal do kitdelimita o contexto do kit
input com SKU principalfornece o sku do produto de kit nativo
bloco de item internodelimita cada produto que compõe o kit
input name="sku" dentro de cada itemfornece o SKU efetivamente escolhido daquele item
botão final do kitdispara a rotina de adição ao carrinho

Se qualquer um desses pontos estiver ausente, a compra do kit nativo fica incompleta ou inconsistente.

Conteúdo necessário no container principal do kit

Seção intitulada “Conteúdo necessário no container principal do kit”

A sua implementação provavelmente terá um template, partial ou componente principal responsável por renderizar o kit nativo. Independentemente do nome desse arquivo, ele precisa concentrar o estado principal da compra.

Esse container principal deve conter, no mínimo:

  • A identificação de que aquele bloco representa um kit nativo;
  • O SKU principal do kit em um input acessível ao JavaScript;
  • A lista dos itens internos que compõem o kit;
  • A renderização ou carregamento dos blocos de item interno;
  • A validação de bloqueio por personalização;
  • O botão final de compra do kit.

Em termos funcionais, esse bloco principal é responsável por responder estas perguntas:

  • Este produto deve usar fluxo de kit nativo?
  • Qual é o SKU principal do kit?
  • Quais são os produtos internos que participam da compra?
  • A compra do kit está liberada ou bloqueada?
  • Onde está o botão que dispara a adição ao carrinho?

Se esse bloco não expuser essas informações, a lógica de compra do kit fica sem contexto suficiente para funcionar.

Neste exemplo, {% load_products %} carrega em products os produtos internos do kit a partir dos IDs de product.bundle_children. A variável has_customization é calculada antes da renderização dos itens para decidir se o kit pode ser comprado em bloco.

{% if product.bundle_children.size > 0 %}
<div class="bundle" data-bundle-section>
<input type="hidden" value="{{ product.variants[0].sku }}" data-main-bundle-product-id>
{% assign bundle_product_ids = '' %}
{% for item in product.bundle_children %}
{% if forloop.first %}
{% assign bundle_product_ids = item.product_id %}
{% else %}
{% assign bundle_product_ids = bundle_product_ids | append: ',' | append: item.product_id %}
{% endif %}
{% endfor %}
{% assign bundle_product_ids = bundle_product_ids | split: ',' | uniq | join: ',' %}
{% load_products ids: bundle_product_ids %}
{% assign has_customization = false %}
{% for bundle_product in products %}
{% assign customs_tag = bundle_product.tags | where: 'type', 'personalizacao' | first %}
{% if customs_tag and customs_tag != blank %}
{% assign has_customization = true %}
{% break %}
{% endif %}
{% endfor %}
{% for item in product.bundle_children %}
{% assign item_id = item.product_id %}
{% assign item_quantity = item.quantity %}
{% assign bundle_product = products | where: "id", item_id | first %}
{% if item_quantity > 0 %}
{% for i in (1..item_quantity) %}
{% render 'partials/content/product/bundle/product_block_bundle',
product: bundle_product,
show_short_description: false,
has_customization: has_customization
%}
{% endfor %}
{% endif %}
{% endfor %}
{% if has_customization %}
<p class="custom-message">Este kit contém produtos com personalização. Adicione-os individualmente ao carrinho.</p>
<button type="button" class="button-default -unavailable" data-bundle-add>
Indisponível
</button>
{% else %}
<button type="button" class="button-default" data-bundle-add>
Adicionar kit no carrinho
</button>
{% endif %}
</div>
{% endif %}

Nesse bloco, os pontos mais importantes do contrato são:

  • data-bundle-section no container principal;
  • data-main-bundle-product-id com o SKU principal do kit;
  • Renderização repetida dos itens internos;
  • data-bundle-add no botão final;
  • Bloqueio explícito quando existe personalização.

Conteúdo necessário em cada bloco de item do kit

Seção intitulada “Conteúdo necessário em cada bloco de item do kit”

A sua implementação também precisa de um bloco para cada item interno do kit nativo. Novamente, o nome do arquivo pode variar, mas a responsabilidade funcional é a mesma.

Cada bloco de item interno deve conter, no mínimo:

  • Identificação do produto interno;
  • Nome e mídia do item;
  • Área para seleção de variante ou atributos;
  • Lógica para resolver a variante escolhida;
  • Um input name="sku" com o SKU final daquele item, ou uma estrutura que permita ao JavaScript preencher esse valor.

Na prática, cada bloco de item precisa deixar o produto interno pronto para responder:

  • Qual item do kit está sendo exibido?
  • Qual variante o usuário escolheu?
  • Qual SKU corresponde a essa escolha?
  • Esse SKU está disponível para leitura no momento da compra?

Se a resposta para a última pergunta for não, o kit não terá como montar bundle_skus[] corretamente.

Neste exemplo, has_customization é recebido do container principal do kit. A variável imgs_without_lazy representa quantas imagens devem carregar sem lazy loading; quando ela não existir no contexto da loja, o snippet define 0 como padrão.

{% assign image_urls = product.images | map: 'url' | uniq %}
{% assign img_limit = 1 %}
{% assign imgs_without_lazy = imgs_without_lazy | default: 0 %}
{% assign short_description = product.description %}
{% if product.description contains '<hr/>' %}
{% assign short_description = product.description | split: '<hr/>' | first %}
{% endif %}
<div class="product-block-bundle" {% unless has_customization %} data-product-box="{{ product.id }}" data-quickview-type="bundle" {% endunless %}>
<div class="heading">
{% if has_customization %}
<a href="{{ product.url }}" aria-label="{{ product.name }}">
{% endif %}
<div class="images">
<figure class="image -square">
{% for image in image_urls limit: img_limit %}
{% capture data_srcset %}
{{ image | resize: '350x' }} 350w,
{{ image | resize: '420x' }} 420w,
{{ image | resize: '480x' }} 480w,
{{ image | resize: '767x' }} 767w
{% endcapture %}
{% capture data_sizes %}
(max-width: 350px) 350px,
(max-width: 480px) 480px,
(max-width: 991px) 350px,
(max-width: 1280px) 420px,
(max-width: 1440px) 480px,
767px
{% endcapture %}
{% if forloop.index <= imgs_without_lazy %}
<img srcset="{{ data_srcset | strip_newlines | strip }}" sizes="{{ data_sizes | strip_newlines | strip }}" alt="Foto do produto {{ product.name }}"/>
{% else %}
<img class="lazy" loading="lazy" data-srcset="{{ data_srcset | strip_newlines | strip }}" sizes="{{ data_sizes | strip_newlines | strip }}" alt="Foto do produto {{ product.name }}"/>
{% endif %}
{% endfor %}
</figure>
</div>
<div class="infos">
<h3 class="name">
{{ product.name }}
</h3>
</div>
{% if has_customization %}
</a>
{% endif %}
</div>
{% if show_short_description != blank and short_description != blank %}
<div class="description">
{{ short_description }}
</div>
{% endif %}
</div>

Esse exemplo mostra dois comportamentos importantes:

  • Quando o kit pode ser comprado em bloco, o item recebe data-product-box e data-quickview-type="bundle";
  • Quando existe personalização, esse item deixa de participar do fluxo de compra em bloco e vira apenas um link para a PDP do produto.

Esse é o cenário em que o formulário dos itens internos é carregado sob demanda.

O fluxo é este:

  1. o bloco do item é renderizado com data-product-box e data-quickview-type="bundle";
  2. o JavaScript observa esse bloco;
  3. quando o item entra em viewport, o frontend carrega o formulário de quickview;
  4. o formulário é anexado dentro do próprio .product-block-bundle;
  5. esse formulário passa a expor name="sku" para a compra final do kit.

Exemplo de marcação para quickview do kit nativo

Seção intitulada “Exemplo de marcação para quickview do kit nativo”
<div class="product-block-bundle" data-product-box="{{ product.id }}" data-quickview-type="bundle">
<div class="heading">
<div class="images">
<figure class="image -square">
{% assign image_urls = product.images | map: 'url' | uniq %}
{% for image in image_urls limit: 1 %}
{% capture data_srcset %}
{{ image | resize: '350x' }} 350w,
{{ image | resize: '420x' }} 420w,
{{ image | resize: '480x' }} 480w,
{{ image | resize: '767x' }} 767w
{% endcapture %}
{% capture data_sizes %}
(max-width: 350px) 350px,
(max-width: 480px) 480px,
(max-width: 991px) 350px,
(max-width: 1280px) 420px,
(max-width: 1440px) 480px,
767px
{% endcapture %}
<img srcset="{{ data_srcset | strip_newlines | strip }}" sizes="{{ data_sizes | strip_newlines | strip }}" alt="Foto do produto {{ product.name }}"/>
{% endfor %}
</figure>
</div>
<div class="infos">
<h3 class="name">
{{ product.name }}
</h3>
</div>
</div>
</div>

Nesse cenário, o formulário não precisa estar presente no HTML inicial. A rotina de quickview o insere dentro do elemento marcado com data-product-box.

Exemplo do carregamento do quickview em JavaScript

Seção intitulada “Exemplo do carregamento do quickview em JavaScript”

Neste exemplo, bundleConfig representa as configurações do tema para o formulário do item interno, como exibir botão, usar dropdown e aplicar variação visual.

const QuickviewBundle = {
bundleConfig: {},
showButton: false,
dropdown: false,
style: '-default',
handleBundleForm: async function(product, id) {
const isBundle = true;
QuickviewBundle.showButton = QuickviewBundle.bundleConfig.showButton || false;
QuickviewBundle.dropdown = QuickviewBundle.bundleConfig.dropdown || false;
QuickviewBundle.style = QuickviewBundle.bundleConfig.style || '-default';
// getQuickviewForm deve ser importado ou exposto pelo módulo de utilidades do tema.
const form = await getQuickviewForm(id, '', QuickviewBundle.dropdown, QuickviewBundle.showButton, QuickviewBundle.style, isBundle);
if (!form) {
return;
}
const productForm = product.querySelector('form.add-to-cart');
if (!productForm) {
product.appendChild(form);
// ProductPurchase é o objeto responsável por inicializar seleção de variantes e compra do formulário inserido.
window.ProductPurchase.init();
}
},
};

O efeito prático desse fluxo é: cada .product-block-bundle passa a ter, dentro de si, um form.add-to-cart com o name="sku" que será lido na compra do kit nativo.

Você também pode implementar o kit nativo sem quickview.

Nesse cenário:

  • Cada item do kit já precisa renderizar o formulário de compra diretamente na PDP;
  • Esse formulário precisa manter o mesmo contrato de leitura do fluxo padrão;
  • No clique final, o kit nativo continua lendo name="sku" dentro de cada item interno.

O ponto importante é que o quickview não é obrigatório para a lógica do kit nativo. O que é obrigatório é existir, em cada item interno, uma forma confiável de obter o SKU escolhido no momento da compra.

Se você não usar quickview, a recomendação é manter a mesma organização semântica do bloco do item e garantir que o formulário de compra fique dentro do próprio elemento marcado com data-product-box.

Exemplo de item do kit nativo sem quickview mantendo o mesmo contrato

Seção intitulada “Exemplo de item do kit nativo sem quickview mantendo o mesmo contrato”
<div class="product-block-bundle" data-product-box="{{ product.id }}">
<div class="heading">
<div class="images">
<figure class="image -square">
{% assign image_urls = product.images | map: 'url' | uniq %}
{% for image in image_urls limit: 1 %}
{% capture data_srcset %}
{{ image | resize: '350x' }} 350w,
{{ image | resize: '420x' }} 420w,
{{ image | resize: '480x' }} 480w,
{{ image | resize: '767x' }} 767w
{% endcapture %}
{% capture data_sizes %}
(max-width: 350px) 350px,
(max-width: 480px) 480px,
(max-width: 991px) 350px,
(max-width: 1280px) 420px,
(max-width: 1440px) 480px,
767px
{% endcapture %}
<img srcset="{{ data_srcset | strip_newlines | strip }}" sizes="{{ data_sizes | strip_newlines | strip }}" alt="Foto do produto {{ product.name }}"/>
{% endfor %}
</figure>
</div>
<div class="infos">
<h3 class="name">
{{ product.name }}
</h3>
</div>
</div>
{% comment %}
Renderize aqui o formulário de compra do produto interno.
Esse formulário precisa gerar um input name="sku" com o SKU escolhido.
O formulário pode ser o mesmo usado na compra comum, desde que fique dentro de data-product-box.
{% endcomment %}
</div>

A diferença principal nesse caso é que o formulário já vem renderizado de imediato, em vez de ser injetado depois. O contrato da compra, porém, continua o mesmo: o JavaScript do kit nativo precisa encontrar name="sku" dentro de cada item.

A parte de JavaScript do kit nativo tem três responsabilidades principais:

  1. ouvir o clique do botão final do kit;
  2. localizar o SKU principal e os SKUs dos itens internos;
  3. enviar a compra ao carrinho e tratar retry, erro e sucesso.

Esse é o comportamento da camada que observa o botão final do kit e delega a compra para a store.

const BundleSelection = {
handleBundleSubmit: function() {
const bundleEl = document.querySelector('[data-bundle-section]');
if (!bundleEl) return;
const button = bundleEl.querySelector('[data-bundle-add]');
if (!button) return;
button.addEventListener('click', event => {
event.preventDefault();
// Store é o objeto responsável por centralizar os fluxos de compra.
Store.addProduct(bundleEl, bundleEl.parentElement);
});
},
init: function() {
BundleSelection.handleBundleSubmit();
}
};

A camada de compra do frontend precisa executar esta sequência:

  1. localizar o container principal do kit;
  2. localizar todos os blocos dos itens internos;
  3. ler o name="sku" de cada item;
  4. montar a lista bundle_skus[];
  5. ler o SKU principal do kit;
  6. montar o payload da compra;
  7. enviar POST /carrinho/adicionar;
  8. tratar retry, erro e sucesso.

Exemplo completo da rotina de compra do kit nativo

Seção intitulada “Exemplo completo da rotina de compra do kit nativo”
addBundle: async function(form, parent) {
let bundle_skus = [];
const bundleProducts = form.querySelectorAll('[data-product-box]');
bundleProducts.forEach(product => {
bundle_skus.push(product.querySelector('[name="sku"]').value);
});
const bundleObj = {
sku: document.querySelector('[data-main-bundle-product-id]').value,
quantity: 1,
bundle_skus
};
let formBody = [];
for (const key in bundleObj) {
if (bundleObj.hasOwnProperty(key)) {
const value = bundleObj[key];
if (key === 'bundle_skus' && Array.isArray(value)) {
value.forEach(item => {
formBody.push(`${encodeURIComponent(key)}[]=${encodeURIComponent(item)}`);
});
} else {
const encodedValue = Array.isArray(value)
? value.map(item => encodeURIComponent(item)).join(',')
: encodeURIComponent(value);
formBody.push(`${encodeURIComponent(key)}=${encodedValue}`);
}
}
}
formBody = formBody.join('&');
try {
while (true) {
const response = await fetch('/carrinho/adicionar', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json, text/javascript, */*; q=0.01',
},
body: formBody,
});
if (response.status === 202) {
const retryAfter = response.headers.get('Retry-After');
const delay = retryAfter ? parseInt(retryAfter, 10) : 3000;
await new Promise(resolve => setTimeout(resolve, delay));
} else {
if (!response.ok) {
const button = form.querySelector('[data-bundle-add]');
if (button) {
button.classList.add('-unavailable');
const innerHTML = button.innerHTML;
button.innerHTML = 'Erro ao adicionar no carrinho';
setTimeout(() => {
button.classList.remove('-unavailable');
button.innerHTML = innerHTML;
}, 2000);
}
return;
}
// CartDrawer é o objeto responsável por abrir ou atualizar o carrinho lateral.
CartDrawer.show();
break;
}
}
} catch (error) {
const button = form.querySelector('[data-bundle-add]');
if (button) {
button.classList.add('-unavailable');
const innerHTML = button.innerHTML;
button.innerHTML = 'Erro ao adicionar no carrinho';
setTimeout(() => {
button.classList.remove('-unavailable');
button.innerHTML = innerHTML;
}, 2000);
}
}
},

Esse exemplo mostra a lógica esperada para a compra do kit nativo:

  • Leitura de [data-product-box];
  • Leitura de name="sku" dentro de cada item;
  • Leitura de [data-main-bundle-product-id];
  • Serialização manual de bundle_skus[];
  • POST /carrinho/adicionar;
  • Tratamento de 202 com retry;
  • Fallback visual no botão em caso de erro;
  • Abertura do Cart Drawer em caso de sucesso.

O ponto mais importante dessa compra é este: o JavaScript não “descobre” sozinho quais variantes usar. Ele depende de cada item interno já ter resolvido e preenchido corretamente seu name="sku".

Se um item interno não tiver name="sku", ou se esse valor estiver vazio, o kit nativo deixa de ter dados suficientes para uma compra correta.

Sem quickview, a camada de compra continua com a mesma responsabilidade final: ler o SKU principal e todos os bundle_skus[].

O que muda é a origem desse name="sku" em cada item interno:

  • Com quickview, ele costuma ser preenchido por um formulário carregado dinamicamente;
  • Sem quickview, ele precisa vir do formulário já renderizado dentro do próprio item.

Ou seja: remover quickview não muda o contrato da compra. Muda apenas quem resolve e expõe o sku de cada item.

Estados de interface que o kit nativo precisa prever

Seção intitulada “Estados de interface que o kit nativo precisa prever”

Além da montagem do payload, a implementação do kit precisa prever estados claros de interface:

  • Kit carregando os itens internos;
  • Item interno aguardando carregamento ou seleção de variante;
  • Item interno com SKU resolvido;
  • Kit bloqueado por personalização;
  • Kit em processamento de compra;
  • Kit com erro de adição;
  • Kit adicionado com sucesso.

Documentar esses estados ajuda a evitar implementações incompletas que resolvem apenas o payload, mas deixam falhas de experiência e validação.

Se você estiver implementando um kit nativo do zero, a sequência recomendada é:

  1. validar se o produto deve entrar no fluxo de kit nativo;
  2. garantir que os produtos internos estejam disponíveis na PDP;
  3. definir se a seleção de variante será feita com quickview ou inline;
  4. renderizar o container principal do kit;
  5. renderizar os blocos dos itens internos;
  6. garantir que cada item resolva e exponha seu name="sku";
  7. bloquear a compra em bloco se houver personalização;
  8. consolidar o SKU principal do kit com os SKUs internos;
  9. enviar o payload ao carrinho;
  10. tratar sucesso, erro e retry.

O motivo mais comum é existir personalização em algum item interno do kit nativo.

Verifique se todos os itens internos do kit têm name="sku" preenchido corretamente no momento do clique.

O kit usa /carrinho/adicionar ou /carrinho/adicionar/kit?

Seção intitulada “O kit usa /carrinho/adicionar ou /carrinho/adicionar/kit?”

O kit nativo usa POST /carrinho/adicionar. O fluxo de POST /carrinho/adicionar/kit pertence ao compre junto.

Não obrigatoriamente. O quickview é apenas uma estratégia de carregamento da seleção dos itens internos. O requisito real é conseguir resolver o SKU de cada item antes da compra final.

No mínimo, a identificação do kit nativo, o SKU principal, os itens internos carregados, a validação de bloqueio e o botão final de compra.

O que precisa existir em cada bloco de item do kit?

Seção intitulada “O que precisa existir em cada bloco de item do kit?”

No mínimo, a identificação do item, a seleção de variante e uma forma confiável de disponibilizar o name="sku" final daquele item.

  • Não trate o kit como uma simples variação do botão de compra padrão.
  • Não misture kit nativo com compre junto.
  • Não esconda o contrato do payload do kit nativo.
  • Não altere os seletores principais do fluxo sem ajustar a camada de compra.
  • Sempre documente onde o name="sku" é resolvido em cada item interno.
  • Sempre teste o fluxo com e sem quickview.
  • Se remover quickview, mantenha a mesma lógica de leitura dentro de data-product-box.