SDK Helper
Las apps NubeSDK se ejecutan dentro de un web worker aislado, sin acceso directo al DOM. Todo lo que hace la app: leer el estado, renderizar componentes, navegar y almacenar datos pasa por la instancia del SDK que el runtime entrega al punto de entrada App(nube).
En la práctica, esa instancia nube termina pasando por todas las funciones y componentes de la app, y algunos patrones se repiten en cada proyecto: leer la página actual, estrechar tipos de página, renderizar un componente por producto, mostrar un toast al recibir un evento.
@tiendanube/nube-sdk-helper concentra esos patrones en un conjunto de utilidades pequeño y fuertemente tipado.
Instalación
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 es una peer dependency y debe instalarse junto con el paquete helper.
Registrar la instancia
El runtime entrega la instancia del SDK solo como argumento del punto de entrada. La idea central del helper es simple: registrá una vez, y todos los demás helpers llegan a ella por su cuenta, sin necesidad de pasar nube por toda la jerarquía de la 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`);
}
Tres funciones gestionan la instancia:
setNubeInstance(nube): registra la instancia (llamá una vez al inicio delApp).getNubeInstance(): devuelve la instancia registrada, lanzando un error descriptivo si aún no fue registrada.clearNubeInstance(): limpia la instancia (útil en tests).
Por qué esto importa
Con la instancia registrada globalmente, las acciones más comunes se convierten en funciones independientes que podés llamar desde cualquier lugar: un componente anidado, un módulo utilitario, un event handler, sin necesidad de recibir 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
}
// En cualquier otra parte de la app, sin `nube` en el scope:
function onCheckoutClick() {
navigate("/checkout"); // routes to the path internally via the SDK instance
ui.showToast("Taking you to checkout...", "info");
}
Sin el helper, sería necesario tener una referencia a nube en el scope y llamar a nube.getBrowserAPIs().navigate(...), además de construir el componente de toast a mano. El helper reduce ambos a una sola línea.
Lo mismo aplica para el almacenamiento en el 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");
}
Leer el estado con selectores
Los selectores siguen un patrón consistente: llamados sin argumento, leen el estado actual del SDK; pasando un estado explícito, se convierten en funciones 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
// Sin argumento: lee el estado actual de la instancia del SDK.
const items = getCartItems();
const pageType = getPageType();
const customer = getCustomer();
}
Pasá un estado mock a cualquier selector y se comporta como una función pura: sin efectos secundarios, sin depender de la instancia registrada. Este patrón aplica a toda la familia de selectores.
Guards
Los guards cumplen una doble función: validan en runtime y estrechan el tipo para TypeScript, desbloqueando los datos específicos de la página tipados por el 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);
}
}
A diferencia de un cast (as ProductPage), los guards verifican la estructura en runtime antes de estrechar el tipo. Si la condición no pasa, TypeScript no expone page.data.product.
Hay un guard para casi toda estructura encontrada en una app NubeSDK:
- Páginas:
isProductPage,isCategoryPage,isCheckoutPage,isHomePage,isAllProductsPage,isSearchPage - Carrito:
isCart,isCartItem,isCartValidationSuccess,isCartValidationPending,isCartValidationFail - Dominio:
isStore,isCustomer,isPayment,isShipping,isAddress, y más - Componentes / datos de página:
isNubeComponent,hasProductList,hasSections,hasSingleProduct,isSectionWithProducts
Getters
Además de los selectores de estado, los getters exponen los metadatos inyectados por el runtime sobre la app. Uno útil es getScriptURL, que analiza la URL desde donde se cargó el script de la app (cacheada como una 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
}
Esta es la forma idiomática de configurar una app desde la tag de script, sin necesidad de una solicitud adicional.
Page matching
pageMatch y onPage resuelven el mismo problema desde dos ángulos. pageMatch despacha una vez contra un estado provisto, y cada handler recibe el payload correctamente tipado para su página. onPage envuelve pageMatch, pero suscribe a la navegación, re-ejecutándose en cada cambio de página y devolviendo una función de cancelación.
Usá pageMatch para una decisión puntual basada en el estado actual:
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),
});
}
Usá onPage para reaccionar continuamente a la navegación del usuario:
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 específicamente, onCheckoutStep permite reaccionar a un step particular:
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
Una necesidad frecuente es renderizar algo en un slot de grilla de producto: un badge, un label, un ícono. forEachProduct extrae todos los productos del estado actual (independientemente del tipo de página), los mapea a través de una factory de renderizado, descarta resultados vacíos y asigna automáticamente un key único a partir del id del producto.
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 un badge sobre cada imagen de producto en la grilla del home.
onPage({
home: () => {
nube.render(
"product_grid_item_image_center_center",
forEachProduct((product) => <Badge product={product} />),
);
},
});
}
Sin JSX, la factory devuelve un objeto de componente directamente:
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 })),
);
},
});
}
Devolver null o undefined desde la factory omite el producto: esas entradas se filtran automáticamente.
Helpers de UI y eventos
ui agrupa las operaciones de vista más comunes, incluyendo renderizar el mismo componente en múltiples slots en una sola llamada:
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 y toastOn reducen el patrón repetitivo de "escuchar y reaccionar" a una línea cada uno, ambos devolviendo una función de cancelación:
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`);
}
Descubrimiento de slots
Los slots de una página no son fijos. En temas sectionable, la persona dueña de la tienda agrega, elimina y reordena secciones dinámicas, así que el mismo slot lógico puede existir varias veces, en otra posición, o no existir. Además, la misma sección a veces se expone con nombres distintos como slot estático y como slot dinámico — por ejemplo after_section_products_featured versus after_dynamic_section_featured_products. En la práctica, esto empuja a las apps a hardcodear nombres de slot y adivinar tema por tema.
Los helpers de slot envuelven nube.api.getAvailableSlots() para responder las preguntas que la app realmente tiene — ¿qué slots existen acá? y ¿dónde está la primera/última sección de este tipo? — y devuelven un slot listo para ui.render, o null cuando nada coincide.
El descubrimiento de slots depende de la API getAvailableSlots(), que no está disponible en el tema Patagonia ni en el Checkout por el momento. En esos contextos las consultas no devuelven slots.
Listar los slots de la página
Tres funciones asíncronas exponen el registro de slots de la página actual:
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 los slots de la página, separados por tipo.
const { static: statics, dynamic: dynamics } = await getAvailableSlots();
// Solo los puntos de inyección fijos del tema, direccionables por `slotId`.
const fixed = await getStaticSlots();
const hasNewsletter = fixed.some(
(slot) => slot.slotId === "before_section_newsletter",
);
// Solo los slots dinámicos, cada uno con las coordenadas de su sección.
const sections = await getDynamicSlots();
const featured = sections.filter(
(slot) => slot.sectionType === "featured_products",
);
}
getDynamicSlots() devuelve los slots crudos: cada uno lleva el sectionType que la sección realmente tiene en la página, sin resolución de nombres equivalentes. Para eso, usá las consultas de sección de abajo.
Encontrar el slot de una sección
Cuatro consultas responden "¿dónde está la sección X?" y devuelven un slot listo 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` acepta la promise directamente y no renderiza nada si es `null`.
ui.render(beforeFirstSection("newsletter"), <Component />);
ui.render(afterLastSection("newsletter"), <Component />);
}
Cada consulta sigue el mismo orden de resolución:
- Primero las secciones dinámicas. Filtra los slots dinámicos por tipo de sección y por posición (
before/after), y elige el de menorsectionIndex(first) o el de mayorsectionIndex(last). Esto funciona sin importar cuántas secciones de ese tipo existan ni dónde estén en la página. - Fallback al slot estático. Si el tema no tiene ninguna sección dinámica que coincida, busca el slot estático
${posición}_section_${tipo}— por ejemplobefore_section_newsletter. Los slots estáticos son únicos, así quebeforeFirstSectionybeforeLastSectiondevuelven el mismo slot en ese caso. - Nada encontrado. Registra un error
SlotNotFounden la consola y resuelve anull.
Nombres de sección equivalentes
Los slots estáticos se nombraron según la sección que envuelven (products_featured), mientras que las secciones dinámicas se nombraron según los datos de página que las alimentan (featured_products). La misma sección, entonces, responde a dos nombres según si el tema la renderiza como sección fija o dinámica.
El helper mantiene internamente una tabla de equivalencias (hoy featured_products ↔ products_featured) y ejecuta cada consulta sobre el tipo pedido y sus alias, probando primero la forma que la app usó. El resultado práctico: tu app sigue pasando el nombre que conoce, y la sección se encuentra de cualquier manera.
// Ambas llamadas encuentran la misma sección, sea estática o dinámica.
ui.render(afterLastSection("featured_products"), <Component />);
ui.render(afterLastSection("products_featured"), <Component />);
Los tipos de sección desconocidos se aceptan y resuelven a sí mismos, lo que cubre secciones personalizadas cuyo nombre solo existe en runtime. El tipo SectionType sugiere los nombres conocidos en el autocompletado, pero acepta cualquier string.
Cuando nada coincide
Una consulta que no encuentra nada no lanza excepción: registra un SlotNotFound en la consola y resuelve a null, de modo que un slot ausente se degrada a "nada renderizado" en lugar de romper la app. Al pasar la promise a ui.render, ese caso ya está resuelto. Si preferís usar await, verificá el resultado:
const slot = await beforeFirstSection("products_featured");
if (slot) {
ui.render(slot, <Component />);
}
Referencia de la API
Referencia formal de cada símbolo exportado en la raíz del paquete (@tiendanube/nube-sdk-helper).
Instancia
Gestionan la instancia del SDK que usa el resto del helper.
setNubeInstance(nube)
Registra la instancia de NubeSDK para la app actual. Llámala una vez, al inicio de App(nube).
setNubeInstance(nube: Readonly<NubeSDK>): void
getNubeInstance()
Devuelve la instancia registrada. Si no se registró ninguna, recurre a self.__SDK_INSTANCE__ y, en ausencia de ambas, lanza un error descriptivo.
getNubeInstance(): Readonly<NubeSDK>
clearNubeInstance()
Limpia la instancia registrada. Útil en tests o al reinicializar la app.
clearNubeInstance(): void
Getters
Exponen el estado actual y los metadatos que el runtime inyecta sobre la app.
getCurrentState()
Devuelve el estado actual (readonly) del SDK.
getCurrentState(): Readonly<NubeSDKState>
getAppData()
Devuelve los datos de la app inyectados por el runtime: id y script.
getAppData(): Readonly<{ id: string; script: string }>
getScriptURL()
Devuelve la URL desde la que se cargó el script de la app, como una instancia URL congelada (cacheada en la primera llamada).
getScriptURL(): Readonly<URL>
getScriptSearchParams()
Devuelve los URLSearchParams (readonly) de la URL del script.
getScriptSearchParams(): Readonly<URLSearchParams>
getScriptParam(key)
Devuelve el valor de un query param específico de la URL del script, o null si no está presente. Es la forma idiomática de configurar una app desde la etiqueta de script, sin una petición adicional.
getScriptParam(key: string): Nullable<string>
Selectores de estado
Accesores enfocados en las porciones más leídas del estado. Todos aceptan un state opcional; cuando se omite, leen el estado actual de la instancia registrada (pasa un estado explícito para volverlos puros).
getCart(state?: NubeSDKState): Cart
getCartItems(state?: NubeSDKState): CartItem[]
getPageType(state?: NubeSDKState): Page["type"] // ej.: "home", "product", "checkout"
getCustomer(state?: NubeSDKState): Nullable<Customer> // null cuando no está disponible en la página
Guards
Los guards cumplen doble función: validan en runtime y estrechan el tipo para TypeScript. A diferencia de un cast (as ProductPage), verifican la estructura antes de estrechar — si la comprobación falla, el tipo no se expone.
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` se estrechó a ProductPage, así que `page.data.product` está tipado.
console.log(page.data.product.name);
}
}
Páginas — reciben un Page y estrechan al tipo de página correspondiente:
| Guard | Estrecha a |
|---|---|
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 |
Carrito — reciben unknown y validan la estructura:
| Guard | Estrecha a |
|---|---|
isCart | Cart |
isCartItem | CartItem |
isCartValidationSuccess | validación de carrito exitosa |
isCartValidationPending | validación de carrito pendiente |
isCartValidationFail | validación de carrito fallida |
Dominio — reciben unknown y validan la estructura:
| Guard | Estrecha a |
|---|---|
isStore | Store |
isCustomer | Customer |
isPayment | Payment |
isShipping | Shipping |
isShippingOption | ShippingOption |
Dirección — reciben unknown y validan la estructura:
| Guard | Estrecha a |
|---|---|
isAddress | Address |
isShippingAddress | ShippingAddress |
isBillingAddress | BillingAddress |
Componentes y datos de página — útiles para comprobar el formato de page.data antes de acceder a él:
| Guard | Estrecha a |
|---|---|
isNubeComponent | NubeComponent |
hasProductList | { products: ProductDetails[] } |
hasSections | { sections: unknown[] } |
isSectionWithProducts | una sección que contiene products |
hasSingleProduct | { product: ProductDetails } |
Page matching
pageMatch(state, handlers)
Despacha al handler correspondiente al tipo de página en el estado que le pases. Cada handler recibe el payload correctamente tipado para su página. Se ejecuta una vez.
pageMatch(state: NubeSDKState, handlers: PageHandlers): void
onPage(handlers)
Se suscribe al evento page:loaded y llama al handler correspondiente en cada navegación. Devuelve una función de cancelación.
onPage(handlers: PageHandlers): () => void
onCheckoutStep(handlers)
Escucha checkout:ready y, cuando la página actual es un checkout, invoca el handler registrado para el step actual. También se ejecuta de inmediato para el step corriente si ya está en el checkout. Devuelve una función de cancelación.
onCheckoutStep(handlers: CheckoutStepHandlers): () => void
Tipos relacionados: PageDataMap, PageHandlerFunction<T>, PageHandlers, CheckoutStepHandlers.
Render
getProductsFromState(state)
Extrae todos los productos del estado, sin importar el tipo de página (listas directas, productos dentro de secciones y el producto principal en páginas de detalle). Devuelve un array vacío si no hay productos.
getProductsFromState(state: NubeSDKState): ProductDetails[]
forEachProduct(renderFactory)
Crea una función de render que extrae los productos del estado, mapea cada uno con renderFactory, descarta los resultados null/undefined y asigna automáticamente una key única a partir del id del producto.
forEachProduct(
renderFactory: (product: ProductDetails) => NubeComponent | null | undefined,
): (state: NubeSDKState) => NubeComponent[]
UI
ui es un objeto congelado con cuatro helpers de vista.
ui.showToast(message: string, variant?: ToastVariant): void // variant por defecto "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— muestra un toast en la esquina superior derecha.variantes"success" | "error" | "warning" | "info".clear— limpia un slot (nube.clearSlot). No acepta promises.render— renderiza un componente en un slot. Acepta un nombre de slot, un descriptorStaticSlot/DynamicSlot, o la promise devuelta por una consulta de sección : en ese caso espera la resolución, no renderiza nada si el resultado esnully registra cualquier error en la consola.renderAll— renderiza el mismo componente en varios slots en una sola llamada.
Tipos relacionados: ToastVariant, RenderableComponent, UIHelper, QuerySlotResult.
Descubrimiento de slots
Consultas sobre los slots disponibles en la página actual, construidas sobre nube.api.getAvailableSlots() . Todas son asíncronas y todas lanzan un error si no se registró ninguna instancia del SDK. Disponibles a partir de la versión 0.3.0 del helper.
getAvailableSlotsAPI()
Devuelve el adaptador de available slots de la instancia registrada. Se resuelve una vez y se memoiza durante toda la vida de la app, así que las consultas repetidas reutilizan el mismo canal de comandos.
getAvailableSlotsAPI(): AvailableSlotsCommands
getAvailableSlots()
Todos los slots de la página actual, separados por tipo.
getAvailableSlots(): Promise<{ static: StaticSlot[]; dynamic: DynamicSlot[] }>
getStaticSlots()
Solo los slots estáticos: los puntos de inyección fijos del tema, direccionables por su slotId.
getStaticSlots(): Promise<StaticSlot[]>
getDynamicSlots()
Solo los slots dinámicos. Cada uno lleva las coordenadas de su sección (sectionType, sectionId, sectionIndex), que es lo que permite elegir una instancia específica cuando la sección se repite. Los sectionType llegan tal como están en la página, sin resolución de nombres equivalentes.
getDynamicSlots(): Promise<DynamicSlot[]>
Consultas de sección
Encuentran el slot antes/después de la primera/última sección de un tipo. Buscan primero en las secciones dinámicas (por el menor o mayor sectionIndex) y, si no hay ninguna, caen al slot estático ${posición}_section_${tipo}. Como el slot estático es único, first y last devuelven el mismo slot en ese fallback. Cuando nada coincide, registran un SlotNotFound en la consola y resuelven a null.
beforeFirstSection(sectionType: SectionType): Promise<QuerySlotResult>
afterFirstSection(sectionType: SectionType): Promise<QuerySlotResult>
beforeLastSection(sectionType: SectionType): Promise<QuerySlotResult>
afterLastSection(sectionType: SectionType): Promise<QuerySlotResult>
Las consultas se ejecutan sobre el tipo pedido y sus nombres equivalentes, probando primero la forma que la app usó — ver Nombres de sección equivalentes .
SlotNotFound
Error que describe una consulta que no encontró nada. Las consultas no lo lanzan: lo registran vía SlotNotFound.log y devuelven 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 sugiere los nombres conocidos en el autocompletado, pero acepta cualquier string, para cubrir secciones personalizadas y dinámicas cuyo nombre solo se conoce en runtime.
Eventos
Wrappers ergonómicos alrededor de nube.on que devuelven una función de cancelación.
onEvent(event, listener)
Equivalente a nube.on(event, listener), pero la función devuelta desregistra el listener vía nube.off — sin necesidad de guardar referencia a la instancia y al listener para limpiarlo.
onEvent<T extends NubeSDKListenableEvent>(
event: T,
listener: EventListenerMap[T],
): () => void
toastOn(event, message, variant?)
Muestra un toast cada vez que el evento se dispara. El mensaje puede ser una cadena estática o una función que lo deriva del estado. Devuelve una función de cancelación.
toastOn<T extends NubeSDKListenableEvent>(
event: T,
message: string | ((state: Readonly<NubeSDKState>) => string),
variant?: ToastVariant,
): () => void
Browser
Acceso a las Browser APIs (storage, navegación) a través de la instancia del SDK. Ver también Browser APIs .
browser
Objeto que expone las Browser APIs (asyncLocalStorage, asyncSessionStorage, navigate, ...). Se materializa de forma lazy en el primer acceso a una propiedad y se cachea.
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 a una ruta dentro del dominio de la tienda. La ruta debe empezar con /.
navigate(route: `/${string}`): void
clearBrowserCache()
Limpia la caché interna de las Browser APIs, forzando una nueva instancia en el próximo acceso. Útil en tests.
clearBrowserCache(): void
Utilidades
Funciones de propósito general, independientes de la instancia del SDK.
deepClone(obj)
Clona un valor en profundidad. Usa structuredClone cuando está disponible (lo está, en el runtime del worker de NubeSDK), con fallback a serialización JSON.
deepClone<T>(obj: T): T
debounce(func, wait)
Devuelve una versión debounced de la función, que solo se ejecuta tras wait ms sin nuevas llamadas.
debounce<T extends (...args: never[]) => unknown>(
func: T,
wait: number,
): (...args: Parameters<T>) => void
throttle(func, limit)
Devuelve una versión throttled de la función, que se ejecuta como máximo una vez cada limit ms.
throttle<T extends (...args: never[]) => unknown>(
func: T,
limit: number,
): (...args: Parameters<T>) => void
Próximos pasos
Help us improve NubeSDK
Found an issue or have a suggestion? Let us know on GitHub.