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
Yarn
pnpm
npm install @tiendanube/nube-sdk-helper @tiendanube/nube-sdk-types
yarn add @tiendanube/nube-sdk-helper @tiendanube/nube-sdk-types
pnpm add @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.
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 doApp).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();
}
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);
}
}
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`);
}
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:
| Guard | Estreita para |
|---|---|
isProductPage | ProductPage |
isCategoryPage | CategoryPage |
isCheckoutPage | CheckoutPage |
isAllProductsPage | AllProductsPage |
isSearchPage | SearchPage |
isHomePage | HomePage |
isAccountPage | AccountPage |
isAccountLoginPage | AccountLoginPage |
isAccountRegisterPage | AccountRegisterPage |
isAccountInfoPage | AccountInfoPage |
isAccountResetPage | AccountResetPage |
isAccountNewPasswordPage | AccountNewPasswordPage |
isAccountOrdersPage | AccountOrdersPage |
Carrinho — recebem unknown e validam a estrutura:
| Guard | Estreita para |
|---|---|
isCart | Cart |
isCartItem | CartItem |
isCartValidationSuccess | validação de carrinho com sucesso |
isCartValidationPending | validação de carrinho pendente |
isCartValidationFail | validação de carrinho com falha |
Domínio — recebem unknown e validam a estrutura:
| Guard | Estreita para |
|---|---|
isStore | Store |
isCustomer | Customer |
isPayment | Payment |
isShipping | Shipping |
isShippingOption | ShippingOption |
Endereço — recebem unknown e validam a estrutura:
| Guard | Estreita para |
|---|---|
isAddress | Address |
isShippingAddress | ShippingAddress |
isBillingAddress | BillingAddress |
Componentes e dados de página — úteis para checar o formato do page.data antes de acessá-lo:
| Guard | Estreita para |
|---|---|
isNubeComponent | NubeComponent |
hasProductList | { products: ProductDetails[] } |
hasSections | { sections: unknown[] } |
isSectionWithProducts | seçã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, 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).render— renderiza um componente em um slot.renderAll— renderiza o mesmo componente em múltiplos slots em uma chamada.
Tipos relacionados: ToastVariant, RenderableComponent, UIHelper.
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");
}
navigate(route)
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
Help us improve NubeSDK
Found an issue or have a suggestion? Let us know on GitHub.