Pular para o conteúdo principal

SDK Helper

Apps NubeSDK rodam dentro de um web worker isolado, sem acesso direto ao DOM. Tudo que o app faz: ler o estado, renderizar componentes, navegar e armazenar dados passa pela instância do SDK que o runtime entrega ao ponto de entrada App(nube).

Na prática, essa instância nube acaba sendo passada por todas as funções e componentes do app, e alguns padrões se repetem em todo projeto: ler a página atual, estreitar tipos de página, renderizar um componente por produto, exibir um toast ao receber um evento.

@tiendanube/nube-sdk-helper concentra esses padrões em um conjunto de utilitários pequeno e fortemente tipado.

Instalação

npm install @tiendanube/nube-sdk-helper @tiendanube/nube-sdk-types

@tiendanube/nube-sdk-types é uma peer dependency e deve ser instalada junto.

Registrando a instância

O runtime entrega a instância do SDK apenas como argumento do ponto de entrada. A ideia central do helper é simples: registre uma vez, e todos os outros helpers chegam até ela por conta própria, sem precisar passar nube por toda a árvore do app.

src/App.ts
import {
setNubeInstance,
getCurrentState,
ui,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before anything else

const state = getCurrentState();
ui.showToast(`You are on the ${state.location.page.type} page`);
}

Três funções gerenciam a instância:

  • setNubeInstance(nube): registra a instância (chame uma vez no topo do App).
  • getNubeInstance(): retorna a instância registrada, lançando um erro descritivo se ela ainda não foi registrada.
  • clearNubeInstance(): limpa a instância (útil em testes).

Por que isso importa

Com a instância registrada globalmente, as ações mais comuns viram funções independentes que podem ser chamadas de qualquer lugar: um componente aninhado, um módulo utilitário, um event handler, sem precisar receber nube como parâmetro.

import { navigate, setNubeInstance, ui } from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper
}

// Em qualquer outro lugar do app, sem `nube` no escopo:
function onCheckoutClick() {
navigate("/checkout"); // routes to the path internally via the SDK instance
ui.showToast("Taking you to checkout...", "info");
}

Sem o helper, seria necessário ter uma referência a nube no escopo e chamar nube.getBrowserAPIs().navigate(...), além de construir o componente de toast manualmente. O helper reduz ambos a uma linha.

O mesmo se aplica ao armazenamento no browser:

import { browser, setNubeInstance } from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export async function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

await browser.asyncLocalStorage.setItem("seen-banner", "true");
const seen = await browser.asyncLocalStorage.getItem("seen-banner");
}

Lendo o estado com seletores

Os seletores seguem um padrão consistente: chamados sem argumento, leem o estado atual do SDK; passando um estado explícito, tornam-se funções puras.

import {
getCartItems,
getCustomer,
getPageType,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

// Sem argumento: lê o estado atual da instância do SDK.
const items = getCartItems();
const pageType = getPageType();
const customer = getCustomer();
}
Testabilidade

Passe um estado mock para qualquer seletor e ele se comporta como uma função pura: sem efeitos colaterais, sem depender da instância registrada. Esse padrão vale para toda a família de seletores.

Guards

Guards fazem dupla função: validam em runtime e estreitam o tipo para o TypeScript, desbloqueando os dados específicos da página tipados pelo compilador.

import {
getCurrentState,
isProductPage,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

const { page } = getCurrentState().location;

if (isProductPage(page)) {
// `page` is now narrowed to a ProductPage, so `page.data.product` is typed.
console.log(page.data.product.name);
}
}
Validação e tipagem juntos

Diferente de um cast (as ProductPage), os guards verificam a estrutura em runtime antes de estreitar o tipo. Se a condição não passar, o TypeScript não expõe page.data.product.

Há um guard para quase toda estrutura encontrada em um app NubeSDK:

  • Páginas: isProductPage, isCategoryPage, isCheckoutPage, isHomePage, isAllProductsPage, isSearchPage
  • Carrinho: isCart, isCartItem, isCartValidationSuccess, isCartValidationPending, isCartValidationFail
  • Domínio: isStore, isCustomer, isPayment, isShipping, isAddress, e mais
  • Componentes / dados de página: isNubeComponent, hasProductList, hasSections, hasSingleProduct, isSectionWithProducts

Getters

Além dos seletores de estado, os getters expõem os metadados injetados pelo runtime sobre o app. Um exemplo útil é getScriptURL, que analisa a URL de onde o script do app foi carregado (cacheada como uma URL congelada):

import {
getScriptParam,
getScriptURL,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

const url = getScriptURL();
console.log("Script origin:", url.origin);
console.log("Script pathname:", url.pathname);

// Read configuration passed as query params on the script URL, e.g. ?variant=b
const variant = getScriptParam("variant"); // string | null
}

Essa é a forma idiomática de configurar um app a partir da tag de script, sem precisar de uma requisição adicional.

Page matching

pageMatch e onPage resolvem o mesmo problema de ângulos diferentes. pageMatch despacha uma vez contra um estado fornecido, e cada handler recebe o payload corretamente tipado para a sua página. onPage envolve pageMatch, mas subscreve à navegação, re-executando a cada mudança de página e retornando uma função de cancelamento.

Use pageMatch para uma decisão pontual com base no estado atual:

import {
getCurrentState,
pageMatch,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

// Runs once against the state you pass in.
pageMatch(getCurrentState(), {
product: (state, product) => console.log("Product:", product.name),
checkout: (state, checkout) => console.log("Step:", checkout.step),
});
}

Use onPage para reagir continuamente à navegação do usuário:

import { onPage, setNubeInstance } from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

const stop = onPage({
product: (state, product) => console.log("Viewing product:", product.id),
checkout: (state, checkout) => {
if (checkout.step === "success") console.log("Purchase complete");
},
// category / home handlers are optional
});

// Call stop() later, when you no longer need to react to navigation.
void stop;
}

Para checkout especificamente, onCheckoutStep permite reagir a um step específico:

import { onCheckoutStep, setNubeInstance } from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

onCheckoutStep({
success: () => console.log("Purchase complete"),
});
}

Render

Uma necessidade frequente é renderizar algo em um slot de grade de produto: um badge, um label, um ícone. forEachProduct extrai todos os produtos do estado atual (independentemente do tipo de página), mapeia cada um por uma factory de renderização, descarta resultados vazios e atribui automaticamente um key único a partir do id do produto.

import {
forEachProduct,
onPage,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";
import { Badge } from "./components/Badge";

export function App(nube: NubeSDK) {
setNubeInstance(nube);

// Renderiza um badge sobre cada imagem de produto na grade da home.
onPage({
home: () => {
nube.render(
"product_grid_item_image_center_center",
forEachProduct((product) => <Badge product={product} />),
);
},
});
}

Sem JSX, a factory retorna um objeto de componente diretamente:

import {
forEachProduct,
onPage,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

onPage({
home: () => {
nube.render(
"product_grid_item_image_bottom_right",
forEachProduct((product) => ({ type: "txt", children: product.name })),
);
},
});
}

Retornar null ou undefined da factory pula o produto: essas entradas são filtradas automaticamente.

Helpers de UI e eventos

ui agrupa as operações de view mais comuns, incluindo renderizar o mesmo componente em múltiplos slots em uma chamada:

import { setNubeInstance, ui } from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

ui.renderAll(["corner_top_left", "corner_top_right"], {
type: "txt",
children: "Hi",
});
ui.showToast("Done!", "success");
ui.clear("corner_top_right");
}

onEvent e toastOn reduzem o padrão repetitivo de "escutar e reagir" a uma linha cada, ambos retornando uma função de cancelamento:

import { onEvent, setNubeInstance, toastOn } from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

const off = onEvent("cart:update", (state) => {
console.log("items:", state.cart.items.length);
});

// Call off() later, when you no longer need it.
void off;

toastOn("cart:add:success", "Added to cart", "success");
toastOn("cart:update", (state) => `Cart: ${state.cart.items.length} items`);
}

Descoberta de slots

Os slots de uma página não são fixos. Em temas sectionable, o lojista adiciona, remove e reordena seções dinâmicas, então o mesmo slot lógico pode existir várias vezes, em outra posição, ou não existir. Além disso, a mesma seção às vezes é exposta com nomes diferentes como slot estático e como slot dinâmico — por exemplo after_section_products_featured versus after_dynamic_section_featured_products. Na prática, isso empurra o app para hardcodear nomes de slot e adivinhar o comportamento tema a tema.

Os helpers de slot envolvem nube.api.getAvailableSlots() para responder às perguntas que o app realmente tem — quais slots existem aqui? e onde está a primeira/última seção deste tipo? — devolvendo um slot pronto para ui.render, ou null quando nada corresponde.

Disponibilidade

A descoberta de slots depende da API getAvailableSlots(), que não está disponível no tema Patagonia nem no Checkout neste momento. Nesses contextos as consultas não retornam slots.

Listando os slots da página

Três funções assíncronas expõem o registro de slots da página atual:

import {
getAvailableSlots,
getDynamicSlots,
getStaticSlots,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export async function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

// Todos os slots da página, separados por tipo.
const { static: statics, dynamic: dynamics } = await getAvailableSlots();

// Apenas os pontos de injeção fixos do tema, endereçáveis pelo `slotId`.
const fixed = await getStaticSlots();
const hasNewsletter = fixed.some(
(slot) => slot.slotId === "before_section_newsletter",
);

// Apenas os slots dinâmicos, cada um com as coordenadas da sua seção.
const sections = await getDynamicSlots();
const featured = sections.filter(
(slot) => slot.sectionType === "featured_products",
);
}

getDynamicSlots() devolve os slots crus: cada um carrega o sectionType que a seção realmente tem na página, sem resolução de nomes equivalentes. Para isso, use as consultas de seção abaixo.

Encontrando o slot de uma seção

Quatro consultas resolvem a pergunta "onde está a seção X?" e devolvem um slot pronto para renderizar:

import {
afterLastSection,
beforeFirstSection,
setNubeInstance,
ui,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";
import { Text } from "@tiendanube/nube-sdk-jsx";

function Component() {
return <Text>Hello</Text>;
}

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

// `ui.render` aceita a promise diretamente e não renderiza nada se for `null`.
ui.render(beforeFirstSection("newsletter"), <Component />);
ui.render(afterLastSection("newsletter"), <Component />);
}

Cada consulta segue a mesma ordem de resolução:

  1. Seções dinâmicas primeiro. Filtra os slots dinâmicos pelo tipo de seção e pela posição (before / after), e escolhe o de menor sectionIndex (first) ou maior sectionIndex (last). Isso funciona independentemente de quantas seções daquele tipo existem e de onde elas estão na página.
  2. Fallback para o slot estático. Se o tema não tem nenhuma seção dinâmica correspondente, procura o slot estático ${posição}_section_${tipo} — por exemplo before_section_newsletter. Slots estáticos são únicos, então beforeFirstSection e beforeLastSection devolvem o mesmo slot nesse caso.
  3. Nada encontrado. Registra um erro SlotNotFound no console e resolve para null.

Nomes de seção equivalentes

Os slots estáticos foram nomeados a partir da seção que envolvem (products_featured), enquanto as seções dinâmicas foram nomeadas a partir dos dados que as alimentam (featured_products). A mesma seção, portanto, responde a dois nomes, dependendo de o tema renderizá-la como seção fixa ou dinâmica.

O helper mantém internamente uma tabela de equivalências (hoje featured_productsproducts_featured) e roda cada consulta sobre o tipo pedido e seus apelidos, tentando primeiro a grafia que o app usou. O resultado prático: o app continua passando o nome que conhece, e a seção é encontrada de qualquer forma.

// Ambas as chamadas encontram a mesma seção, seja ela estática ou dinâmica.
ui.render(afterLastSection("featured_products"), <Component />);
ui.render(afterLastSection("products_featured"), <Component />);

Tipos de seção desconhecidos são aceitos e resolvem para si mesmos, o que cobre seções customizadas cujo nome só existe em runtime. O tipo SectionType sugere os nomes conhecidos no autocomplete, mas aceita qualquer string.

Quando nada corresponde

Uma consulta que não encontra nada não lança exceção: ela registra um SlotNotFound no console e resolve para null, de forma que um slot ausente vira "nada renderizado" em vez de quebrar o app. Passando a promise para ui.render, esse caso já está tratado. Se você preferir usar await, verifique o resultado:

const slot = await beforeFirstSection("products_featured");

if (slot) {
ui.render(slot, <Component />);
}

Referência da API

Referência formal de cada símbolo exportado na raiz do pacote (@tiendanube/nube-sdk-helper).

Instância

Gerenciam a instância do SDK usada por todo o resto do helper.

setNubeInstance(nube)

Registra a instância do NubeSDK para o app atual. Chame uma vez, no início do App(nube).

setNubeInstance(nube: Readonly<NubeSDK>): void

getNubeInstance()

Retorna a instância registrada. Se nenhuma foi registrada, tenta o fallback self.__SDK_INSTANCE__ e, na ausência de ambos, lança um erro descritivo.

getNubeInstance(): Readonly<NubeSDK>

clearNubeInstance()

Limpa a instância registrada. Útil em testes ou ao reinicializar o app.

clearNubeInstance(): void

Getters

Expõem o estado atual e os metadados injetados pelo runtime sobre o app.

getCurrentState()

Retorna o estado atual (readonly) do SDK.

getCurrentState(): Readonly<NubeSDKState>

getAppData()

Retorna os dados do app injetados pelo runtime: id e script.

getAppData(): Readonly<{ id: string; script: string }>

getScriptURL()

Retorna a URL de onde o script do app foi carregado, como uma instância URL congelada (cacheada na primeira chamada).

getScriptURL(): Readonly<URL>

getScriptSearchParams()

Retorna os URLSearchParams (readonly) da URL do script.

getScriptSearchParams(): Readonly<URLSearchParams>

getScriptParam(key)

Retorna o valor de um query param específico da URL do script, ou null se ausente. É a forma idiomática de configurar um app a partir da tag de script, sem uma requisição adicional.

getScriptParam(key: string): Nullable<string>

Seletores de estado

Acessores focados nas fatias mais lidas do estado. Todos aceitam um state opcional; quando omitido, leem o estado atual da instância registrada (passe um estado explícito para torná-los puros).

getCart(state?: NubeSDKState): Cart
getCartItems(state?: NubeSDKState): CartItem[]
getPageType(state?: NubeSDKState): Page["type"] // ex.: "home", "product", "checkout"
getCustomer(state?: NubeSDKState): Nullable<Customer> // null quando indisponível na página

Guards

Guards fazem dupla função: validam em runtime e estreitam o tipo para o TypeScript. Diferente de um cast (as ProductPage), verificam a estrutura antes de estreitar — se a checagem falhar, o tipo não é exposto.

import {
getCurrentState,
isProductPage,
setNubeInstance,
} from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

const { page } = getCurrentState().location;
if (isProductPage(page)) {
// `page` foi estreitado para ProductPage, então `page.data.product` é tipado.
console.log(page.data.product.name);
}
}

Páginas — recebem um Page e estreitam para o tipo de página correspondente:

GuardEstreita para
isProductPageProductPage
isCategoryPageCategoryPage
isCheckoutPageCheckoutPage
isAllProductsPageAllProductsPage
isSearchPageSearchPage
isHomePageHomePage
isAccountPageAccountPage
isAccountLoginPageAccountLoginPage
isAccountRegisterPageAccountRegisterPage
isAccountInfoPageAccountInfoPage
isAccountResetPageAccountResetPage
isAccountNewPasswordPageAccountNewPasswordPage
isAccountOrdersPageAccountOrdersPage

Carrinho — recebem unknown e validam a estrutura:

GuardEstreita para
isCartCart
isCartItemCartItem
isCartValidationSuccessvalidação de carrinho com sucesso
isCartValidationPendingvalidação de carrinho pendente
isCartValidationFailvalidação de carrinho com falha

Domínio — recebem unknown e validam a estrutura:

GuardEstreita para
isStoreStore
isCustomerCustomer
isPaymentPayment
isShippingShipping
isShippingOptionShippingOption

Endereço — recebem unknown e validam a estrutura:

GuardEstreita para
isAddressAddress
isShippingAddressShippingAddress
isBillingAddressBillingAddress

Componentes e dados de página — úteis para checar o formato do page.data antes de acessá-lo:

GuardEstreita para
isNubeComponentNubeComponent
hasProductList{ products: ProductDetails[] }
hasSections{ sections: unknown[] }
isSectionWithProductsseção contendo products
hasSingleProduct{ product: ProductDetails }

Page matching

pageMatch(state, handlers)

Despacha para o handler correspondente ao tipo da página no estado fornecido. Cada handler recebe o payload corretamente tipado para a sua página. Executa uma vez.

pageMatch(state: NubeSDKState, handlers: PageHandlers): void

onPage(handlers)

Subscreve ao evento page:loaded e chama o handler correspondente a cada navegação. Retorna uma função de cancelamento.

onPage(handlers: PageHandlers): () => void

onCheckoutStep(handlers)

Escuta checkout:ready e, quando a página atual é um checkout, invoca o handler registrado para o step atual. Também executa imediatamente para o step corrente, se já estiver no checkout. Retorna uma função de cancelamento.

onCheckoutStep(handlers: CheckoutStepHandlers): () => void

Tipos relacionados: PageDataMap, PageHandlerFunction<T>, PageHandlers, CheckoutStepHandlers.

Render

getProductsFromState(state)

Extrai todos os produtos do estado, independentemente do tipo de página (listas diretas, produtos dentro de seções e o produto principal de páginas de detalhe). Retorna um array vazio se não houver produtos.

getProductsFromState(state: NubeSDKState): ProductDetails[]

forEachProduct(renderFactory)

Cria uma função de render que extrai os produtos do estado, mapeia cada um pela renderFactory, descarta resultados null/undefined e atribui automaticamente um key único a partir do id do produto.

forEachProduct(
renderFactory: (product: ProductDetails) => NubeComponent | null | undefined,
): (state: NubeSDKState) => NubeComponent[]

UI

ui é um objeto congelado com quatro helpers de view.

ui.showToast(message: string, variant?: ToastVariant): void  // variant padrão "info"
ui.clear(slot: UISlot): void
ui.render(slot: UISlot | StaticSlot | DynamicSlot, component: RenderableComponent): void
ui.render(slot: Promise<QuerySlotResult>, component: RenderableComponent): void
ui.renderAll(slots: UISlot[], component: RenderableComponent): void
  • showToast — exibe um toast no canto superior direito. variant é "success" | "error" | "warning" | "info".
  • clear — limpa um slot (nube.clearSlot). Não aceita promises.
  • render — renderiza um componente em um slot. Aceita um nome de slot, um descritor StaticSlot / DynamicSlot, ou a promise devolvida por uma consulta de seção : nesse caso, aguarda a resolução, não renderiza nada se o resultado for null e registra eventuais erros no console.
  • renderAll — renderiza o mesmo componente em múltiplos slots em uma chamada.

Tipos relacionados: ToastVariant, RenderableComponent, UIHelper, QuerySlotResult.

Descoberta de slots

Consultas sobre os slots disponíveis na página atual, construídas sobre nube.api.getAvailableSlots() . Todas são assíncronas e todas lançam erro se nenhuma instância do SDK foi registrada. Disponíveis a partir da versão 0.3.0 do helper.

getAvailableSlotsAPI()

Devolve o adaptador de available slots da instância registrada. É resolvido uma vez e memoizado pelo tempo de vida do app, então consultas repetidas reutilizam o mesmo canal de comandos.

getAvailableSlotsAPI(): AvailableSlotsCommands

getAvailableSlots()

Todos os slots da página atual, separados por tipo.

getAvailableSlots(): Promise<{ static: StaticSlot[]; dynamic: DynamicSlot[] }>

getStaticSlots()

Apenas os slots estáticos: os pontos de injeção fixos do tema, endereçáveis pelo slotId.

getStaticSlots(): Promise<StaticSlot[]>

getDynamicSlots()

Apenas os slots dinâmicos. Cada um carrega as coordenadas da sua seção (sectionType, sectionId, sectionIndex), o que permite escolher uma instância específica quando a seção se repete. Os sectionType vêm como estão na página, sem resolução de nomes equivalentes.

getDynamicSlots(): Promise<DynamicSlot[]>

Consultas de seção

Encontram o slot antes/depois da primeira/última seção de um tipo. Procuram primeiro nas seções dinâmicas (pelo menor ou maior sectionIndex) e, na ausência delas, caem para o slot estático ${posição}_section_${tipo}. Como o slot estático é único, first e last devolvem o mesmo slot nesse fallback. Quando nada corresponde, registram um SlotNotFound no console e resolvem para null.

beforeFirstSection(sectionType: SectionType): Promise<QuerySlotResult>
afterFirstSection(sectionType: SectionType): Promise<QuerySlotResult>
beforeLastSection(sectionType: SectionType): Promise<QuerySlotResult>
afterLastSection(sectionType: SectionType): Promise<QuerySlotResult>

As consultas rodam sobre o tipo pedido e seus nomes equivalentes, tentando primeiro a grafia que o app usou — veja Nomes de seção equivalentes .

SlotNotFound

Erro que descreve uma consulta que não encontrou nada. As consultas não o lançam: elas o registram via SlotNotFound.log e devolvem null.

class SlotNotFound extends Error {
constructor(queryDescription: string, appid: string | number);
static log(queryDescription: string): void;
}

Tipos relacionados:

type QuerySlotResult = StaticSlot | DynamicSlot | null;
type SectionType = "newsletter" | "products_sale" | "products_new" | "products_featured" | "featured_products" | (string & {});

SectionType sugere os nomes conhecidos no autocomplete, mas aceita qualquer string, para cobrir seções customizadas e dinâmicas cujo nome só é conhecido em runtime.

Eventos

Wrappers ergonômicos em torno de nube.on que retornam uma função de cancelamento.

onEvent(event, listener)

Equivalente a nube.on(event, listener), mas a função retornada remove o listener via nube.off — sem precisar guardar referência à instância e ao listener para limpar.

onEvent<T extends NubeSDKListenableEvent>(
event: T,
listener: EventListenerMap[T],
): () => void

toastOn(event, message, variant?)

Exibe um toast sempre que o evento dispara. A mensagem pode ser uma string estática ou uma função que a deriva do estado. Retorna uma função de cancelamento.

toastOn<T extends NubeSDKListenableEvent>(
event: T,
message: string | ((state: Readonly<NubeSDKState>) => string),
variant?: ToastVariant,
): () => void

Browser

Acesso às Browser APIs (storage, navegação) através da instância do SDK. Veja também Browser APIs .

browser

Objeto que expõe as Browser APIs (asyncLocalStorage, asyncSessionStorage, navigate, ...). É materializado de forma lazy na primeira propriedade acessada e cacheado.

import { browser, setNubeInstance } from "@tiendanube/nube-sdk-helper";
import type { NubeSDK } from "@tiendanube/nube-sdk-types";

export async function App(nube: NubeSDK) {
setNubeInstance(nube); // call this first, before any other helper

await browser.asyncLocalStorage.setItem("seen-banner", "true");
const seen = await browser.asyncLocalStorage.getItem("seen-banner");
}

Navega para uma rota dentro do domínio da loja. A rota deve começar com /.

navigate(route: `/${string}`): void

clearBrowserCache()

Limpa o cache interno das Browser APIs, forçando uma nova instância no próximo acesso. Útil em testes.

clearBrowserCache(): void

Utilitários

Funções de propósito geral, independentes da instância do SDK.

deepClone(obj)

Clona um valor em profundidade. Usa structuredClone quando disponível (é o caso no runtime do NubeSDK), com fallback para serialização JSON.

deepClone<T>(obj: T): T

debounce(func, wait)

Retorna uma versão debounced da função, que só executa após wait ms sem novas chamadas.

debounce<T extends (...args: never[]) => unknown>(
func: T,
wait: number,
): (...args: Parameters<T>) => void

throttle(func, limit)

Retorna uma versão throttled da função, que executa no máximo uma vez a cada limit ms.

throttle<T extends (...args: never[]) => unknown>(
func: T,
limit: number,
): (...args: Parameters<T>) => void

Próximos passos

  • Events — Lista completa de eventos disponíveis no NubeSDK
  • State — Estrutura de estado do NubeSDK
  • UI Slots — Slots disponíveis para renderização

Help us improve NubeSDK

Found an issue or have a suggestion? Let us know on GitHub.