v0.1.0 Uappi Nuxt 2 / Vue 2.7

Documentação do módulo Nuxt

Busca, autocomplete, vitrines, banners e analytics da Rocket Search para lojas Uappi. Um pacote npm registrado no nuxt.config.js — os componentes ficam disponíveis em qualquer página do tema.

Visão geral

O storefront da Uappi é uma aplicação Nuxt 2, então a integração é um módulo Nuxt e não um <script>: o tema instala o pacote @rocketsearch/nuxt-uappi, registra o módulo e usa os componentes onde quiser. As funcionalidades são as mesmas do SDK Linx 2.0.0.

Peça Responsabilidade
Plugin $rocket Sessão, contexto da página, envio de eventos, page_view na navegação SPA e add_to_cart automático.
<RocketAutocomplete> Campo de busca do header, com termos e produtos sugeridos.
<RocketSearch> Página de busca completa: facetas, faixa de preço, ordenação e paginação.
<RocketShowcase> Vitrine de produtos em carrossel, por posição cadastrada no painel.
<RocketBanner> Banners do painel, renderizados no servidor ou sob demanda.
Produtos vêm da Uappi A Rocket Search decide quais produtos aparecem e em que ordem; nome, preço, imagem e estoque exibidos são lidos da API da própria Uappi. O card mostra sempre o dado vigente da loja.

Requisitos

  • Nuxt 2.15 ou superior e Vue 2.7.
  • Módulo @nuxtjs/axios com o baseURL apontando para a API da Uappi (o padrão dos temas Uappi).
  • Domínio da loja liberado no painel da Rocket Search para a API Key usada.

Instalação

npm install @rocketsearch/nuxt-uappi

Registre o módulo em nuxt.config.js:

modules: [
  '@nuxtjs/axios',
  ['@rocketsearch/nuxt-uappi', {
    storeId: 'minha-loja',
    apiKey: 'pk_live_xxxxxxxxxxxx',
    uappiDomain: 'loja.minhaloja.com.br'
  }]
]

Pronto — com isso a loja já tem analytics rodando. Os componentes são registrados automaticamente; não é preciso importar nada.

Preconnect incluído O módulo adiciona <link rel="preconnect" href="https://api.rocketsearch.com.br" crossorigin> no <head> de todas as páginas. Não é preciso adicionar à mão.

Configuração

As opções vão no segundo item do array do módulo, ou numa chave rocketSearch na raiz do nuxt.config.js.

Opções do módulo

Opção Padrão Descrição
storeId req — Identificador da loja na Rocket Search.
apiKey req — Chave pública da loja (pk_live_…). Enviada no header X-API-Key.
uappiDomain — Domínio da API Uappi da loja. Se não bater com o axios.baseURL do tema, o módulo não sobe — evita que o tema de uma loja sirva o catálogo de outra.
siteOrigin https://{uappiDomain} Origin enviado nas chamadas feitas no servidor (banner loading="ssr"). Precisa ser um domínio liberado no painel.
searchPagePath /busca Rota da página de busca, para onde o autocomplete envia.
searchPageParam busca Parâmetro da URL com o termo buscado.
apiUrl https://api.rocketsearch.com.br/api/v2 Base da API. Só muda em homologação.
debug false Loga no console cada evento enviado.
storeId ou apiKey ausentes O módulo não sobe e avisa no log do build. A loja continua funcionando, só sem Rocket Search.

Busca e Autocomplete

<RocketAutocomplete>

Substitui o campo de busca do header. Sugere termos e produtos enquanto o cliente digita; com o campo vazio, mostra os termos mais buscados. Enter ou o botão levam à página de busca.

<RocketAutocomplete input-placeholder="O que você procura?" :products-limit="4" />
Prop Padrão Descrição
minChars 2 Caracteres antes de buscar sugestões.
productsLimit painel Máximo de produtos sugeridos.
termsLimit painel Máximo de termos sugeridos.
mediaSize small Tamanho da imagem do produto na Uappi.
inputPlaceholder O que você procura? Placeholder do campo.
searchButtonType icon icon ou text.
searchButtonText Buscar Texto do botão quando searchButtonType="text".
suggestionsTitle, productsTitle — Títulos das colunas de sugestões.

<RocketSearch>

A página de busca completa. Lê o termo da URL (?busca=), mantém filtros, ordenação e página na URL e funciona com voltar/avançar do navegador. Crie uma view para a rota de busca do tema e coloque o componente nela:

<RocketSearch :page-size="24" facets-mode="side" />
Prop Padrão Descrição
pageSize 20 Produtos por página.
facetsMode side side (coluna lateral) ou fixed (gaveta). No mobile é sempre gaveta.
livescroll false Carrega a próxima página ao rolar, no lugar da paginação.
isCategory, categoryId — Modo categoria (veja abaixo).
mediaSize medium Tamanho da imagem do produto na Uappi.
Redirect de termo Se o termo tiver uma regra de redirect no painel, a página navega para a URL cadastrada antes de mostrar resultados.

Modo categoria

Com is-category, a página lista a categoria em vez de um termo, com as mesmas facetas e ordenação. O id é o da categoria na Uappi:

<RocketSearch is-category :category-id="$store.state.dadosPageAtual.conteudo.id" />

Usando o card do tema

A grade vem com um card simples. Para manter o card da loja (preço, selos, botão de compra), use o slot #product — ele recebe o produto no formato da Uappi. O mesmo slot existe na vitrine.

<RocketSearch>
  <template #product="{ product }">
    <CommonProductCard :product="product" />
  </template>
</RocketSearch>
Clique rastreado sem configuração O clique é identificado pelo link do produto dentro do slot. Qualquer card que tenha um link para a página do produto já é rastreado.

Mantendo a listagem do tema

Se o tema já tem a própria página de listagem (filtros laterais, ordenação, paginação) e a loja quer manter esse visual, dá para trocar só a fonte dos dados: rocketSearchListing busca na Rocket e devolve a resposta no mesmo formato da Front API da Uappi (/v2/front/url/product/listing/search). O resto do tema continua igual.

import {
  rocketSearchListing,
  dispatchListingSearch,
  dispatchListingClick
} from '@rocketsearch/nuxt-uappi/runtime/listing.js';

// No lugar do GET da listagem, quando a rota for a de busca:
const data = await rocketSearchListing({
  $rocket: this.$rocket,
  $axios: this.$axios,
  query: this.$route.query,   // busca, pg, ipp, order, preco + facetas
  limit: 12,                  // itens por página quando não há ?ipp
  titleSuffix: ' | Minha Loja'
});

// Evento de busca: no cliente, depois de montar a página (no SSR ele não sai)
dispatchListingSearch(this.$rocket, data);

// Clique num card da grade
dispatchListingClick(this.$rocket, data, product, index);

A URL segue o vocabulário da listagem da Uappi: busca, pg, ipp, order (id da ordenação da Rocket) e preco=min-max. As facetas entram como ?BTUs=9.000;12.000. Os filtros nativos da Uappi (marca, filtro, atributo, selo) e os parâmetros de campanha (utm_*, gclid…) são ignorados, para que um link antigo não zere a busca.

Funciona no SSR A busca roda no servidor (bom para SEO); só os eventos ficam para o navegador. Por isso dispatchListingSearch é chamado de novo no mounted e marca o evento como enviado para não duplicar.

Vitrines

As vitrines são cadastradas no painel com um tipo de página (home, produto, categoria, busca) e uma posição. O componente mostra a vitrine daquela posição na página atual; sem vitrine cadastrada, não renderiza nada.

<RocketShowcase>

<RocketShowcase position="top" />
<RocketShowcase position="middle" />
<RocketShowcase position="bottom" />

O tipo de página vem do tema (dadosPageAtual): na home busca as vitrines da home, na página de produto as de produto, e assim por diante. Todas as vitrines da página saem de uma única chamada à API.

Props e slots

Prop / slot Padrão Descrição
position req — Posição cadastrada no painel (top, middle, bottom).
pageType página atual Força o tipo de página (home, product, category, search).
mediaSize medium Tamanho da imagem no card padrão.
slot #product card padrão Card de cada produto: recebe { product, position }.
slot padrão carrossel Troca o carrossel inteiro (por exemplo, pelo carrossel do tema): recebe { showcase, products }.

Para a vitrine da Rocket sair com o carrossel e o título do próprio tema, use o slot padrão:

<RocketShowcase position="top">
  <template #default="{ showcase, products }">
    <CommonShowcase :title="showcase.name" :data="{ produtos: products }" />
  </template>
</RocketShowcase>

O clique continua medido: o componente reconhece o produto pelo link do card, qualquer que seja o markup do tema. O wrapper tem margem vertical de 60px; zere com uma classe própria se o componente do tema já trouxer o espaçamento.

Colunas no desktop e no mobile seguem o layout cadastrado no painel. Se a vitrine tiver um banner vinculado, ele aparece acima dos produtos; um banner cadastrado sozinho numa posição de vitrine aparece no lugar dela.

Banners

Banners cadastrados no painel, com imagem desktop e mobile, link, texto opcional e teste A/B.

<!-- Banner principal: já vem no HTML, com carrossel se houver mais de um -->
<RocketBanner position="hero" loading="ssr" carousel />

<!-- Banner do meio da página: só carrega quando chega perto da tela -->
<RocketBanner position="middle" ratio="4/1" />
Modo Quando usar
ssr Banner no topo da página. O servidor busca o banner e ele chega pronto no HTML, sem esperar o JavaScript — é o que melhora o LCP.
ondemand (padrão) Banner abaixo da dobra. A chamada só acontece quando o espaço chega a 200px da tela, então não pesa no carregamento inicial.
Segmentação por região e ssr No modo ssr quem chama a API é o servidor da loja, então a região (UF) considerada é a do servidor, não a do visitante. Banner com segmentação regional deve usar ondemand.
Prop Padrão Descrição
position req — Posição cadastrada no painel (hero, middle…).
loading ondemand ssr ou ondemand.
ratio — Proporção do espaço (ex.: 4/1). Reserva a altura e mostra um esqueleto enquanto carrega, para a página não pular.
carousel false Com mais de um banner na posição, mostra em carrossel. Sem ele, empilha.
limit — Máximo de banners exibidos.
pageType página atual Força o tipo de página.
sizes 100vw Atributo sizes da imagem quando o banner não ocupa a largura toda.
rootMargin 200px Antecedência do modo ondemand.
imageResizing true Redimensiona a imagem pela Cloudflare. Desligue se a imagem estiver num domínio sem esse recurso.
  • A imagem mobile do painel é usada em telas de até 768px.
  • No modo ondemand, a imagem é pedida na largura exata do espaço (considerando a densidade da tela). No ssr, vai com várias larguras e o navegador escolhe.
  • O primeiro banner da posição hero carrega com prioridade alta; os demais, só quando estão para aparecer.
  • Se o redimensionamento falhar para uma imagem, o banner usa a imagem original em vez de sumir.

Impressão e clique são enviados automaticamente. A impressão só conta quando o banner fica pelo menos metade visível por 1 segundo; o clique registra a posição relativa na imagem, que alimenta o mapa de calor do painel.

Link interno navega sem recarregar a página. Link externo espera o evento ser enviado antes de sair.

API JavaScript

O módulo injeta $rocket no contexto do Nuxt: this.$rocket nos componentes e context.$rocket em asyncData, fetch, middlewares e plugins.

this.$rocket

Membro Retorno Descrição
config object Opções resolvidas do módulo.
getSessionId() Promise<string> ID de sessão da visita (rs-anon-…).
search(params) Promise<object> Busca produtos. Executa o redirect do termo, se houver.
autocomplete(term) Promise<object> Termos e produtos sugeridos. Com termo vazio, os mais buscados.
searchImage(file, params) Promise<object> Busca por imagem: data URI base64 ou URL pública.
getShowcasesByContext(type) Promise<Array> Vitrines de um tipo de página.
getBannersByContext(type, { position }) Promise<Array> Banners de um tipo de página. Em caso de erro, devolve lista vazia.
dispatchEvent(type, data) Promise Envia um evento de analytics.
getPage() object Contexto da página atual: { section, productId, categoryId }.
// Busca simples
const data = await this.$rocket.search({ q: 'split', page: 1 });
console.log(data.total, data.products); // produtos com id e preço; o resto vem da Uappi

// Vitrines da home
const showcases = await this.$rocket.getShowcasesByContext('home');

Eventos dos componentes

Componente Evento Payload
RocketSearch @products-loaded { products, total, term }
RocketShowcase @products-loaded { showcase, products }

Use o @products-loaded da busca para alimentar o SEO e o GTM do tema, que leem dadosPageAtual:

<RocketSearch @products-loaded="onProductsLoaded" />

onProductsLoaded ({ products, term }) {
  this.$store.commit('setDadosPageAtual', {
    estrutura: { nivel: 'product/listing/search', seo: { title: term, indexar: false } },
    conteudo: { produtos: products }
  });
}

Analytics

Só de registrar o módulo, visualização de produto, navegação e carrinho já são rastreados. Os componentes rastreiam busca, clique e impressão sozinhos.

Eventos automáticos

Evento Disparado quando
page_view A seção muda (home, busca, categoria, produto…), inclusive em navegação sem recarregar a página.
view Página de produto carrega, ou uma vitrine ou banner entra na tela.
search Busca executada com termo não vazio.
click Clique em produto no autocomplete, na busca ou numa vitrine, e clique em banner.
add_to_cart Qualquer adição ao carrinho do tema — o módulo observa a chamada de carrinho da API Uappi, sem instrumentar botões. Se o envio falhar, é reenviado na próxima página.
Atribuição de origem Um produto aberto a partir da busca, do autocomplete ou de uma vitrine leva essa origem para os eventos seguintes da sessão (view, add_to_cart), como no SDK Linx.

dispatchEvent()

Para eventos que o módulo não cobre:

this.$rocket.dispatchEvent('click', {
  productId: '391',
  meta: { source: 'minha-vitrine' }
});

Sessão, tipo de página e origem da visita são adicionados automaticamente.

Checkout: login e compra

O checkout da Uappi roda fora da aplicação Nuxt, então o login feito ali e o purchase saem por uma tag do GTM. Crie uma tag HTML personalizado com dois acionadores: Visualização de página com Page Path contém /checkout, e Evento personalizado = purchase.

<script src="https://api.rocketsearch.com.br/sdk/uappi/rocket-checkout.js"
        data-store-id="minha-loja" data-api-key="pk_live_..."></script>
  • Login: a cada página do checkout, o script consulta a API do front da Uappi (checkout/user) e envia o login uma vez por sessão. Login já enviado pelo módulo na loja não sai de novo.
  • Compra: lê o purchase que a Uappi envia ao dataLayer na confirmação (transaction_id, value, items) e liga a compra à sessão e às vitrines gravadas pelo módulo. Recarregar a confirmação não envia de novo.

Os dois acionadores disparam juntos na confirmação; o script não duplica nada. data-debug="true" loga os eventos no console.

Não troque o acionador do purchase pelo de página O script lê o purchase que já está no dataLayer. Sem o acionador do evento, ele pode rodar antes do push e a compra não sai.
Mesma aba A sessão passa da loja para o checkout pelo sessionStorage. Se o comprador abrir o checkout em outra aba, a compra é registrada sem atribuição e o login não é enviado.

CSS

Cada componente traz o próprio CSS, com classes prefixadas por rocket-search__. As cores seguem variáveis que o tema pode sobrescrever no próprio CSS:

.rocket-search {
  --primary-color: #0a4ea2;
  --secondary-color: #e30613;
}

Debug e Troubleshooting

Modo debug

  • debug: true no módulo loga no console cada evento enviado.
  • ?rocket-search-debug=true na URL destaca vitrines e banners da Rocket na página por 1 hora; =false desliga.

Problemas comuns

Sintoma Causa provável
Componente desconhecido (<RocketSearch>) Módulo não subiu: veja o log do build. storeId/apiKey ausentes ou uappiDomain diferente do axios.baseURL.
"Domínio não autorizado" O domínio da loja não está liberado no painel para essa API Key. No modo ssr, confira o siteOrigin.
Vitrine não aparece Não há vitrine cadastrada para aquela posição e tipo de página, ou os produtos dela estão inativos na Uappi.
Banner não aparece Não há banner ativo para a posição, ou o recurso de banners não está habilitado para a loja.
Suporte Dúvidas de integração ou liberação de domínio: painel dashboard.rocketsearch.com.br.