npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

shopmate-sdk

v1.2.2

Published

Shopmate browser SDK

Readme

ShopMate SDK

Lightweight browser SDK for storefront carts and ShopMate checkout.

Use it to:

  • add products to a local browser cart from storefront controls;
  • retain cart state in localStorage;
  • open ShopMate checkout in a secure cross-origin iframe;
  • receive minimal user-facing notifications plus lifecycle events;
  • integrate through npm ESM imports in browser apps or through HTML attributes;
  • receive verified checkout lifecycle and order-success events.

The SDK is browser-only at runtime. It can be installed from npm and imported into React, Vite, and other client-side browser bundles, but it must not be executed in Node.js or during server-side rendering because it uses native browser APIs (window, document, URL, URLSearchParams, CustomEvent, localStorage, and iframe).


Installation

npm install shopmate-sdk

Quick start

JavaScript, TypeScript, or React client application

import ShopMate from 'shopmate-sdk';

const shopmate = new ShopMate({
  orgId: 2,
  cartPosition: 'right-bottom',
});

shopmate.extract();

new ShopMate(...) creates an instance only. Call extract() after the storefront markup has been rendered.

For React, initialize it from a client-only effect so the SDK runs after the browser has mounted the page:

import { useEffect } from 'react';
import ShopMate from 'shopmate-sdk';

export function Storefront() {
  useEffect(() => {
    const shopmate = new ShopMate({
      orgId: 2,
      cartPosition: 'right-bottom',
    });

    shopmate.extract();
  }, []);

  return <button data-shopmate-product-id="101">Add to cart</button>;
}

Explicit initialization helper

Use initShopMate() when you want the SDK to register itself as window.ShopMateInstance and automatically scan the page when the body is ready.

import { initShopMate } from 'shopmate-sdk';

const shopmate = initShopMate({
  orgId: 2,
  cartPosition: 'right-bottom',
  onOrderSuccess: ({ payload }) => {
    console.log('Order completed:', payload);
  },
});

Plain script tag

<script
  src="https://cdn.jsdelivr.net/npm/shopmate-sdk@latest/shopmate-sdk.min.js"
  data-org-id="2"
  data-cart-position="right-bottom"
></script>

The browser bundle exposes:

window.ShopMate;
window.initShopMate;
window.ShopMateInstance;

When the script is loaded through a normal <script src="..."> tag with data-org-id, it initializes after the page load event and scans the document automatically.


Smallest storefront integration

<button data-shopmate-product-id="101" data-shopmate-quantity="1">
  Add to cart
</button>

<button data-shopmate-checkout="true">
  Checkout
</button>

<script
  src="https://cdn.jsdelivr.net/npm/shopmate-sdk@latest/shopmate-sdk.min.js"
  data-org-id="2"
  data-cart-position="right-bottom"
></script>

The floating cart button uses 🛒; the checkout modal close button uses .


Supported storefront markup

Add a product

<button data-shopmate-product-id="101" data-shopmate-quantity="1">
  Add to cart
</button>

Supported attributes:

  • data-shopmate-product-id — positive numeric product ID; required.
  • data-shopmate-quantity — positive integer quantity; optional, defaults to 1.
  • data-shopmate-coupon-id — optional coupon applied before adding the product.

Calling the same product trigger again increments its existing cart quantity. The SDK caps a product quantity at 999.

Apply or clear a coupon

<button data-shopmate-coupon-id="WELCOME10">
  Apply coupon
</button>

Coupon-only triggers must not also have data-shopmate-product-id.

Open checkout

<button data-shopmate-checkout="true">
  Checkout
</button>

URL-based checkout trigger

<a href="https://shopmate.hoshonto.com/api/v1/pub/checkout?pid=101,102">
  Checkout now
</a>

For URL triggers, ShopMate supports:

  • pid=101,102 — adds each listed product with quantity 1;
  • couponId=WELCOME10 — applies a coupon;
  • c=<JSON cart> — imports a cart payload such as {"i":[{"i":101,"q":2}]}.

For c, use URL encoding when constructing the link manually. Prefer URLSearchParams rather than string concatenation.


Configuration

const shopmate = new ShopMate({
  orgId: 2,
  baseUrl: 'https://shopmate.hoshonto.com',
  checkoutPath: '/api/v1/pub/checkout',
  cartPosition: 'right-bottom',
  enableFloatingCart: true,
  showNotifications: true,
  checkoutLoadTimeoutMs: 20_000,
});

| Option | Type | Default | Description | |---|---|---:|---| | orgId | number | Required | Positive integer organization ID. | | baseUrl | string | https://shopmate.hoshonto.com | HTTP/HTTPS origin hosting ShopMate APIs and checkout. | | checkoutPath | string | /api/v1/pub/checkout | Checkout iframe route. | | cartPosition | ShopMateCartPosition | right-bottom | Floating cart location. | | storageKey | string \| (orgId) => string | shopmate:cart:${orgId} | Cart storage-key override. | | enableFloatingCart | boolean | true | Renders the floating 🛒 cart control. | | autoExtract | boolean | true | Used by initShopMate() and browser auto-init to scan the page when ready. | | selectors | object | See below | Custom product, checkout, and URL checkout selectors. | | labels | object | See below | Accessible labels and checkout copy. | | theme | object | See below | UI colors, radius, and stacking level. | | showNotifications | boolean | true | Shows minimal SDK toast notifications. Events and callbacks still run when false. | | notificationDurationMs | number | 4500 | Default visible duration for toast notifications. | | checkoutLoadTimeoutMs | number | 20000 | Iframe load timeout before a retry notification is shown. | | onNotify | (notification) => void | — | Receives every SDK status notification. | | onWarn | (warning) => void | — | Receives recoverable SDK warnings. | | onOrderSuccess | (event) => void | — | Receives verified order-success events from checkout. |

Cart positions

left-top      top      right-top
left-center   center   right-center
left-bottom   bottom   right-bottom

selectors

selectors: {
  product: '[data-shopmate-product-id]',
  checkout: '[data-shopmate-checkout="true"]',
  checkoutLink: 'https://shopmate.hoshonto.com/api/v1/pub/checkout?',
}

labels

labels: {
  floatingCartAriaLabel: 'Open ShopMate checkout',
  closeCheckout: 'Close checkout',
  openingCheckout: 'Opening checkout...',
}

theme

theme: {
  primaryColor: '#2563eb',
  accentColor: '#0f766e',
  dangerColor: '#ef4444',
  textColor: '#0f172a',
  surfaceColor: '#ffffff',
  overlayColor: 'rgba(15,23,42,.62)',
  borderRadius: '22px',
  zIndex: 2147483647,
}

Public API

extract(rootElement?: HTMLElement): void

Scans the supplied element, or document.body, and attaches click handlers to supported storefront triggers. Calling it more than once is safe; the SDK does not attach duplicate handlers to previously processed elements.

shopmate.extract();
shopmate.extract(document.querySelector('#product-list'));

addToCart(itemId: number, quantity?: number, element?: HTMLElement): boolean

Adds quantity to an existing product or creates a cart item. Returns false for invalid values, unavailable SDK state, or the maximum distinct-item limit.

shopmate.addToCart(101, 2);

The cart allows up to 100 distinct products and up to 999 units per product.

setCartItemQuantity(itemId: number, quantity: number): boolean

Sets an absolute quantity for an item. Use 0 to remove it.

shopmate.setCartItemQuantity(101, 3);
shopmate.setCartItemQuantity(101, 0);

setCoupon(couponId?: string | null): void

Applies a coupon. Pass null, undefined, or an empty string to clear it.

shopmate.setCoupon('WELCOME10');
shopmate.setCoupon(null);

getCart(): ShopMateCart

Returns an isolated copy of the cart.

const cart = shopmate.getCart();
// { i: [{ i: 101, q: 2 }], couponId: 'WELCOME10' }

getCartStorageKey(): string

Returns the active cart localStorage key.

shopmate.getCartStorageKey();
// shopmate:cart:2

getCheckoutQuery(nextUrl?: string): ShopMateCheckoutQuery

Returns the current checkout query contract:

{
  orgId: '2',
  c: '{"i":[{"i":101,"q":2}]}',
  next: 'https://storefront.example/cart',
}

buildCheckoutUrl(nextUrl?: string): string

Builds the checkout iframe URL. Returns an empty string and reports a notification when URL construction fails or exceeds the 8,000-character safety limit.

openCheckout(buttonElement?: HTMLElement): boolean

Builds and opens the checkout iframe. It shows a processing state on the supplied button and returns false when checkout cannot be opened.

shopmate.openCheckout(document.querySelector('#checkout-button'));

The SDK adds only the fullscreen checkout container and close button. Authentication, payment methods, customer account state, and checkout content are handled inside the iframe.

closeCheckout(showNotification = true): void

Closes the iframe, clears the iframe src, restores page scrolling, and optionally shows a close notification.

createCheckoutIframe(): HTMLIFrameElement

Creates the checkout iframe with the required sandbox and payment permissions. This is an advanced API; normal integrations should call openCheckout().

runWhenBodyReady(action: () => void): void

Runs a DOM operation immediately when document.body exists, otherwise after DOMContentLoaded.

initShopMate(config): ShopMate

Creates an instance, assigns it to window.ShopMateInstance, and runs extract() when autoExtract is not false.


Notifications and error handling

ShopMate keeps visible notifications minimal and professional. The SDK still emits every lifecycle notification through callbacks and browser events, but built-in toast UI is reserved for user-impacting states.

Built-in toast UI is shown for:

  • invalid configuration;
  • cart and storage warnings;
  • cart addition and coupon updates;
  • checkout failures;
  • order success.

Checkout opening, opened, ready, and closed states are still emitted to onNotify and shopmate:notification; they are not shown as redundant toasts.

const shopmate = initShopMate({
  orgId: 2,
  onNotify(notification) {
    console.log(notification.level, notification.code, notification.message);
  },
  onWarn(warning) {
    console.warn(warning.code, warning.message, warning.cause);
  },
});

To suppress built-in toast UI but retain callbacks and browser events:

const shopmate = initShopMate({
  orgId: 2,
  showNotifications: false,
});

Callback exceptions are isolated. An exception thrown inside onNotify, onWarn, or onOrderSuccess is logged and does not interrupt core SDK behavior.


Browser events

The SDK dispatches native CustomEvent events on window.

shopmate:notification

Dispatched for every SDK notification. event.detail is a ShopMateNotification.

window.addEventListener('shopmate:notification', (event) => {
  console.log(event.detail);
});

shopmate:order-success

Dispatched after a verified checkout order-success message. event.detail is:

{
  orgId: 2,
  cart: { i: [{ i: 101, q: 2 }] },
  payload: { /* checkout-provided result */ },
}
window.addEventListener('shopmate:order-success', (event) => {
  console.log('Order success:', event.detail);
});

shopmate:close

Dispatch this event from host code to close the checkout.

window.dispatchEvent(
  new CustomEvent('shopmate:close', {
    detail: { orgId: 2 },
  }),
);

If no orgId is supplied, each active ShopMate instance can react to the close event. Provide orgId when more than one instance may exist on a page.


Cross-origin checkout contract

Checkout is intentionally cross-origin. The parent storefront sends cart context in the iframe URL and does not inspect iframe DOM, storage, cookies, or authentication state.

The checkout application is responsible for its own authentication, including any cookies or redirect flow it requires.

The SDK accepts postMessage events only when both conditions are true:

  1. event.origin matches the configured baseUrl origin; and
  2. event.source is the currently active checkout iframe window.

Supported checkout messages:

| Message type | Effect | |---|---| | closeCheckout or shopmate:close | Closes checkout. | | shopmate:checkout-loading or shopmate:loading | Emits a processing notification. | | shopmate:checkout-ready or shopmate:ready | Marks checkout ready and clears the load timeout. | | shopmate:checkout-error or shopmate:error | Shows an error notification and retry action. | | shopmate:order-success, shopmate:orderSuccess, or orderSuccess | Clears the cart, closes checkout, and emits order success. |

Checkout-frame example

The checkout application must send messages to the exact, allowlisted storefront origin. Do not derive this origin from untrusted request values.

const storefrontOrigin = 'https://storefront.example';

function notifyParent(type: string, payload?: unknown) {
  if (window.parent !== window) {
    window.parent.postMessage({ type, payload }, storefrontOrigin);
  }
}

notifyParent('shopmate:checkout-loading');

try {
  await initializeCheckout();
  notifyParent('shopmate:checkout-ready');
} catch (error) {
  notifyParent('shopmate:checkout-error', {
    code: 'CHECKOUT_INITIALIZATION_FAILED',
  });
}

After order creation:

notifyParent('shopmate:order-success', {
  orderId: createdOrder.id,
});

Security requirements

The SDK cart payload is convenience state, not a trusted order record. The checkout backend must validate all client-provided values.

The backend must:

  • verify that every product exists, is active, and belongs to orgId;
  • recalculate prices, discounts, taxes, delivery charges, inventory, and totals server-side;
  • validate coupon eligibility and usage server-side;
  • validate and constrain quantities server-side;
  • validate next against a strict redirect allowlist before redirecting;
  • treat c, pid, couponId, and all URL query values as untrusted input;
  • use short-lived, server-side checkout sessions when cart URLs can become large or sensitive.

Do not expose credentials, privileged API keys, or trusted pricing data in cart URLs.


Script-tag attributes

The browser bundle supports these attributes:

<script
  src="https://cdn.jsdelivr.net/npm/shopmate-sdk@latest/shopmate-sdk.min.js"
  data-org-id="2"
  data-base-url="https://shopmate.hoshonto.com"
  data-auth-token="optional-token"
  data-persist-auth-token="true"
  data-cart-position="right-bottom"
  data-auto-extract="true"
  data-floating-cart="true"
  data-show-notifications="true"
></script>

| Attribute | Description | |---|---| | data-org-id | Required positive organization ID. | | data-base-url | Optional ShopMate base URL. | | data-auth-token | Optional token used only by the SDK request helper. | | data-persist-auth-token | Set to false to avoid token persistence. | | data-cart-position | Floating cart position. | | data-auto-extract | Set to false to skip automatic DOM extraction. | | data-floating-cart | Set to false to hide the floating cart. | | data-show-notifications | Set to false to disable built-in toast UI. |


Build outputs

npm run build generates the package artifacts:

  • shopmate-sdk.js — readable browser global bundle;
  • shopmate-sdk.min.js — minified browser global bundle;
  • dist/index.mjs — ESM bundle;
  • dist/index.min.mjs — minified ESM bundle;
  • dist/index.d.ts — TypeScript declarations.

NPM scripts

npm run build      Build all artifacts
npm run watch      Build in watch mode
npm run typecheck  Run TypeScript type checking only
npm test           Build and verify browser bundle behavior

Package exports

shopmate-sdk          Default ShopMate class export
shopmate-sdk/min      Minified module build
shopmate-sdk/browser  Browser bundle path

Local demo

Build the package, then open examples/storefront-demo.html in a browser.


Publishing to npm

Prerequisites

  • npm account with publish permission for shopmate-sdk;
  • authenticated npm session:
npm login

Release process

  1. Update version:

    npm version patch
    npm version minor
    npm version major
  2. Validate and build:

    npm run typecheck
    npm test
    npm run build
  3. Inspect the package contents:

    npm pack --dry-run
  4. Publish:

    npm publish
  5. Verify:

    npm view shopmate-sdk

The CDN browser bundle is available through jsDelivr after publication:

https://cdn.jsdelivr.net/npm/shopmate-sdk@latest/shopmate-sdk.min.js
https://cdn.jsdelivr.net/npm/shopmate-sdk@<version>/shopmate-sdk.min.js

Publishing checklist

  • [ ] Version updated and committed.
  • [ ] npm run typecheck succeeds.
  • [ ] npm test succeeds.
  • [ ] npm run build succeeds.
  • [ ] README and changelog are updated.
  • [ ] npm pack --dry-run includes only intended files.
  • [ ] npm whoami confirms the correct npm account.
  • [ ] Package published with npm publish.
  • [ ] CDN path checked after publication.