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. |
Requisitos
- Nuxt
2.15ou superior e Vue2.7. - Módulo
@nuxtjs/axioscom obaseURLapontando 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.
<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. |
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. |
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>
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.
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.
<RocketBanner>
<!-- 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" />
loading: ssr ou ondemand
| 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. |
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.
Props
| 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. |
Imagens responsivas
- 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). Nossr, vai com várias larguras e o navegador escolhe. - O primeiro banner da posição
herocarrega 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.
Métricas
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. |
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 ologinuma vez por sessão. Login já enviado pelo módulo na loja não sai de novo. - Compra: lê o
purchaseque 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.
purchase que já está no dataLayer. Sem o acionador do evento, ele pode
rodar antes do push e a compra não sai.
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: trueno módulo loga no console cada evento enviado.?rocket-search-debug=truena URL destaca vitrines e banners da Rocket na página por 1 hora;=falsedesliga.
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. |