En esta página

Referencia SDK

SDK, runtime y UI

Exports principales para los sitios React generados por Nimlio: cliente de API, hooks, runtime bilingüe, formato COP y componentes conectados. El SDK viene dentro de tu sitio de código en Nimlio; no se instala desde un registro público.

Volver a docs

Recetas

Puntos de partida para copiar y pegar con los hooks del storefront headless. Cada uno ya está exportado por el SDK; muestran el código y no lo ejecutan.

Soportado significa que el hook o la clase está exportado por @nimlio/sdk en esta versión y el ejemplo usa solo sus opciones y campos reales.

Crea el cliente y el provider

Soportado

createClient solo acepta una llave publicable que empiece por nk_pub_ y lanza un error con cualquier otra. baseUrl es opcional: si la omites, el cliente usa el valor de build o de la configuración del sitio y, si no hay ninguno, la ruta del mismo origen /api/v1. NimlioProvider crea su propio cliente de TanStack Query a menos que pases queryClient.

import { createClient } from "@nimlio/sdk";
import { NimlioProvider } from "@nimlio/sdk/react";

const client = createClient({ key: "nk_pub_xxxxxxxx" });

export function App({ children }) {
return <NimlioProvider client={client}>{children}</NimlioProvider>;
}

Lista productos con paginación

Soportado

page empieza en 1 y pageSize va de 1 a 100 (por defecto 50); el SDK los convierte en offset y limit de la API. data.meta trae hasMore, nextCursor y limit. useProducts devuelve la primera página como un arreglo plano. Los precios son priceAmount en centavos de COP y pueden ser null.

import { useProductsPage } from "@nimlio/sdk/react";
import { money } from "@nimlio/runtime";

export function Catalog({ page }: { page: number }) {
const { data, isPending, error } = useProductsPage({ page, pageSize: 24 });
if (isPending) return <p>Cargando…</p>;
if (error) return <p>{error.code}</p>;
return (
<>
<ul>
{data.data.map((p) => (
<li key={p.id}>
{p.name} {p.priceAmount != null ? money(p.priceAmount) : null}
</li>
))}
</ul>
{data.meta.hasMore ? <a href={`?page=${page + 1}`}>Siguiente</a> : null}
</>
);
}
Relacionado

Detalle de producto y reseñas

Soportado

useProduct carga un producto por id y además emite el evento de analítica view_content una vez por id de producto. useProductReviews recibe las mismas opciones page y pageSize y devuelve las reseñas junto con meta con count y average.

import { useProduct, useProductReviews } from "@nimlio/sdk/react";

export function ProductPage({ id }: { id: string }) {
const product = useProduct(id);
const reviews = useProductReviews(id, { page: 1, pageSize: 10 });
// product.data.name, reviews.data?.data (list), reviews.data?.meta.average
return null;
}

Checkout: cotizar, crear y consultar

Soportado

El storefront nunca envía precios. Cada item lleva solo un id, un type y una cantidad (más variantId cuando el producto tiene opciones); el servidor resuelve precios unitarios, descuentos, crédito de regalo y envío desde el catálogo publicado al cotizar y de nuevo al crear el pedido. Un cuerpo que incluya price, total, discount, currency o businessId se rechaza con 400 client_order_fields_not_allowed.

import { useRef, useState } from "react";
import { useQuoteOrder, useCreateOrder, useOrderStatus } from "@nimlio/sdk/react";

export function Checkout({ discountCode, shippingRateId }: { discountCode?: string; shippingRateId?: string }) {
const quote = useQuoteOrder();
const create = useCreateOrder();
const [orderId, setOrderId] = useState("");
// Order creation requires an Idempotency-Key. The SDK sends one per call by default;
// keeping one key per checkout attempt makes a re-submit replay the same order.
// Mint a fresh key when the cart changes. Raw fetch must send the header itself.
const attemptKey = useRef(crypto.randomUUID());
// An empty id keeps the query disabled; polling stops on a terminal status.
const status = useOrderStatus(orderId, { poll: 3000 });

async function placeOrder() {
// Selections only: ids, quantities and codes, never prices.
const checkout = {
items: [{ id: "product-id", type: "product" as const, quantity: 2 }],
discountCode,
shippingRateId,
};

// 1. Ask the server what the cart costs.
await quote.mutateAsync({ ...checkout, customerCity: "Medellín" });
// quote.data.subtotal, .discount and .shippingOptions come from the published catalog.

// 2. Create the order with the same selections.
const order = await create.mutateAsync({
input: {
...checkout,
customer: { name: "Ana Pérez", phone: "+573001112233" },
paymentMethod: "online",
},
options: { idempotencyKey: attemptKey.current },
});
setOrderId(order.orderId);
}

return (
<button onClick={placeOrder} disabled={create.isPending}>
{status.data?.status ?? "Pay"}
</button>
);
}

useOrderStatus consulta cada 3000 ms con poll: true o con el intervalo que pases, y se detiene solo en un estado terminal. Crear un pedido requiere Idempotency-Key: useCreateOrder envía una clave generada y el SDK reintenta los fallos transitorios con esa misma clave (useQuoteOrder nunca reintenta); pasa options.idempotencyKey, estable durante todo el intento de pago, para que un reenvío repita el mismo pedido. Con fetch directo envía el encabezado Idempotency-Key o recibirás 400 idempotency_key_required. Formatea los montos con money(), que espera centavos de COP.

Captura NimlioApiError

Soportado

Las peticiones fallidas lanzan NimlioApiError con status, code, reason, fieldErrors y requestId, y los hooks exponen el mismo error en su resultado. Las mutaciones nunca reintentan solas; las lecturas reintentan una vez por defecto con el query client del provider.

import { NimlioApiError } from "@nimlio/sdk";

try {
await create.mutateAsync(input);
} catch (e) {
if (e instanceof NimlioApiError) {
// e.status, e.code, e.reason, e.fieldErrors, e.requestId
if (e.code === "invalid_input") showFieldErrors(e.fieldErrors);
else if (e.code === "rate_limited") retryLater();
else report(e.requestId);
}
}
Relacionado

Referencia

24 de 24 exports

@nimlio/sdk

functioncreateClient(options?: NimlioClientOptions): NimlioClient

Crea el cliente tipado de la Platform API para llaves publicables seguras en navegador.

Ejemplo

const nimlio = createClient({ key: config.key });
const sitio = await nimlio.site.get();
functionclass NimlioApiError

Superficie tipada de errores del SDK.

Ejemplo

try { await nimlio.site.get(); } catch (error) {
  if (error instanceof NimlioApiError) console.log(error.code);
}

@nimlio/sdk/react

componentNimlioProvider(props: NimlioProviderProps): ReactNode

Entrega el cliente SDK a hooks de React dentro de sitios tenant generados.

Ejemplo

<NimlioProvider client={nimlio}><App /></NimlioProvider>
hookuseCreateAppointment(options?: NimlioWriteMutationOptions<{ manageUrl?: string; mode: "requested" | "booked"; serviceName?: string; slot?: { endsAt: string; startsAt: string; };...

Crea intenciones de cita; Nimlio recalcula la disponibilidad en el servidor.

Ejemplo

crearCita.mutate({ serviceId, startsAt, customerName, customerPhone });
hookuseServices(options?: NimlioQueryOptions<{ currency?: string; description?: string; durationMinutes?: number; id: string; imageUrl?: string; name: string; priceAmount?: number; ...

Hook de React para código de sitios tenant en Nimlio.

Ejemplo

const { data: servicios } = useServices();
hookuseSite(options?: NimlioQueryOptions<{ autoLocale: boolean; breakpoints?: Record<string, never>; business: { addressLine1?: string; city?: string; country?: string; description?...

Hook de React para código de sitios tenant en Nimlio.

Ejemplo

const { data: sitio } = useSite();
hookuseSlots(params: { serviceId: string; staffId?: string; date: string; }, options?: NimlioQueryOptions<{ endsAt: string; staffId: string; startsAt: string; }[], readonly ["nimlio...

Hook de React para código de sitios tenant en Nimlio.

Ejemplo

const { data: horarios } = useSlots({ serviceId, staffId, date });

@nimlio/runtime

functiondefineConfig(config: NimlioRuntimeConfigInput): NimlioRuntimeConfig

Export público del SDK de Nimlio.

Ejemplo

export default defineConfig({ routes: [{ path: '/', module: 'src/pages/index.tsx', kind: 'static' }] });
componentLocaleProvider(props: { locale?: Locale; defaultLocale?: Locale; messages?: Partial<Record<Locale, LocaleMessages>>; children?: ReactNode; }): ReactElement<...>

Proveedor de React para código de sitios tenant en Nimlio.

Ejemplo

<LocaleProvider defaultLocale="es"><App /></LocaleProvider>
functionmoney(copCentavos: number, locale?: Locale | "es-CO" | "en-US"): string

Formatea centavos enteros en COP para textos tenant en español o inglés.

Ejemplo

money(12500000, "es-CO") // "$ 125.000"
functionreadSiteConfig(overrides?: Partial<NimlioSiteConfig>): NimlioSiteConfig

Export público del SDK de Nimlio.

Ejemplo

const config = readSiteConfig();
componentSeo(props: SeoProps): null

Tipo público del SDK de Nimlio.

Ejemplo

<Seo title="Reservas" description="Agenda tu visita en línea" />
componentSiteImage(props: SiteImageProps): ReactElement<unknown, string | JSXElementConstructor<any>>

Tipo público del SDK de Nimlio.

Ejemplo

<SiteImage src={service.imageUrl} alt={service.name} />
hookuseLocale(): LocaleContextValue

Hook de React para código de sitios tenant en Nimlio.

Ejemplo

const { locale, setLocale } = useLocale();

@nimlio/ui

componentBookingWidget(props?: BookingWidgetProps): ReactElement<unknown, string | JSXElementConstructor<any>>

Componente de reservas tematizable conectado a servicios, personal, horarios y citas de Nimlio.

Ejemplo

<BookingWidget locale="es" />
componentContactForm(props: ContactFormProps): ReactNode

Componente de formulario tematizable para prospectos y envíos de formularios personalizados.

Ejemplo

<ContactForm formId="contact" locale="es" />
componentLocaleSwitcher(props: LocaleSwitcherProps): Element

Tipo público del SDK de Nimlio.

Ejemplo

<LocaleSwitcher locales={["es", "en"]} />
componentMenuList(props: MenuListProps): Element

Tipo público del SDK de Nimlio.

Ejemplo

<MenuList items={productos} formatPrice={(centavos) => money(centavos, "es-CO")} />
componentProductGrid(props: ProductGridProps): ReactNode

Tipo público del SDK de Nimlio.

Ejemplo

<ProductGrid products={productos} onOrderIntent={abrirCarrito} />
componentPropertyList(props: PropertyListProps): ReactNode

Tipo público del SDK de Nimlio.

Ejemplo

<PropertyList properties={propiedades} />
functionresolveVariant(options: readonly VariantPickerOption[], variants: readonly VariantPickerVariant[], value: Readonly<Record<string, string>>): VariantPickerVariant

Devuelve la variante activa que coincide con una selección completa de opciones, o null.

Ejemplo

const variant = resolveVariant(product.options, product.variants, value);
componentVariantPicker(props: VariantPickerProps): ReactNode

Chips de opciones para un producto con variantes; se controla con un mapa de selección y se tematiza con las variables CSS --nimlio-variant-*.

Ejemplo

const [valor, setValor] = useState<Record<string, string>>({});
<VariantPicker options={producto.options} variants={producto.variants} value={valor} onChange={setValor} />
componentWhatsAppButton(props: WhatsAppButtonProps): Element

Tipo público del SDK de Nimlio.

Ejemplo

<WhatsAppButton phone="+573001112233" label="Escríbenos" />

Usa estos paquetes en lugar de secretos, código de servidor propio o dependencias externas no permitidas.