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

@usesophi/sophi-widget-launcher

v1.0.1

Published

Sophi Widget Launcher for GTM and CDN integrations

Readme

@sophi/widget-launcher

Sophi Widget Launcher adds an AI shopping assistant to your storefront. It renders a floating button that opens a full-screen chat modal powered by the Sophi Web SDK.


Table of Contents


Quick Start

Option A — CDN (recommended for GTM)

Add the following snippet to your page before </body>. Replace the placeholder values with your actual API key and SDK URL.

<script>
  window.sophiWidgetConfig = {
    apiKey: "YOUR_API_KEY",
    sdk: {
      autoLoad: true,
      url: "https://cdn.jsdelivr.net/npm/@usesophi/sophi-web-sdk@latest/dist/index.umd.js"
    }
  };
</script>
<script
  src="https://cdn.jsdelivr.net/npm/@usesophi/sophi-widget-launcher@latest/dist/sophi-widget-launcher.global.global.js"
  async
></script>

Option B — npm / ESM

npm install @sophi/widget-launcher
import { initSophiWidgetLauncher } from "@sophi/widget-launcher";

initSophiWidgetLauncher({
  apiKey: "YOUR_API_KEY",
  sdk: {
    autoLoad: true,
    url: "https://cdn.jsdelivr.net/npm/@usesophi/sophi-web-sdk@latest/dist/index.umd.js"
  }
});

GTM Setup Guide

This section walks you through installing Sophi Widget Launcher via Google Tag Manager without touching your site's source code.

Prerequisites

  • Access to your GTM container (Publish permission required)
  • Your Sophi API key
  • The Sophi Web SDK CDN URL for your environment
  • The Sophi Widget Launcher CDN URL

Step 1 — Create the Config Tag

This tag sets up window.sophiWidgetConfig before the launcher script runs.

  1. In GTM, go to Tags → New.
  2. Click Tag Configuration → Custom HTML.
  3. Paste the following snippet, replacing the placeholder values:
<script>
  window.sophiWidgetConfig = {
    apiKey: "YOUR_API_KEY",
    environment: "production",

    sdk: {
      autoLoad: true,
      url: "https://cdn.jsdelivr.net/npm/@usesophi/sophi-web-sdk@latest/dist/index.umd.js"
    },

    launcher: {
      enabled: true,
      position: "right-bottom",
      text: "Ask Sophi",
      backgroundColor: "#111827",
      textColor: "#ffffff"
    },

    modal: {
      title: "Sophi"
    },

    handlers: {
      addToCart: function (data) {
        // Replace with your storefront's add-to-cart logic
        console.log("Sophi → addToCart", data);
      },
      sendToCheckout: function (data) {
        // Replace with your storefront's checkout logic
        console.log("Sophi → sendToCheckout", data);
      },
      addToFavorite: function (data) {
        console.log("Sophi → addToFavorite", data);
      }
    }
  };
</script>
  1. Name the tag Sophi - Widget Config.
  2. Under Triggering, select All Pages (or a more specific trigger if needed).
  3. Save the tag.

Step 2 — Create the Launcher Script Tag

This tag loads the actual launcher bundle from the CDN.

  1. In GTM, go to Tags → New.
  2. Click Tag Configuration → Custom HTML.
  3. Paste the following:
<script
  src="https://cdn.jsdelivr.net/npm/@usesophi/sophi-widget-launcher@latest/dist/sophi-widget-launcher.global.global.js"
  async
></script>

Replace x.y.z with the exact version you want to use (e.g. 1.0.0). Avoid @latest in production.

  1. Name the tag Sophi - Widget Launcher.
  2. Under Triggering, select All Pages.
  3. Save the tag.

Step 3 — Set Tag Firing Order

The config tag must run before the launcher script. Enforce this with tag sequencing:

  1. Open the Sophi - Widget Launcher tag.
  2. Expand Advanced Settings → Tag Sequencing.
  3. Check Fire a tag before [this tag] fires.
  4. Select Sophi - Widget Config from the dropdown.
  5. Save.

This guarantees window.sophiWidgetConfig is defined before the launcher script executes.


Step 4 — (Optional) Pass the Logged-In User ID

If your site renders the logged-in user ID in the page, you can forward it to Sophi via a Data Layer variable.

Push the user ID to the data layer (add this to your site's authentication code or another GTM tag):

<script>
  dataLayer.push({
    event: "userLoggedIn",
    sophiUserId: "{{ YOUR_USER_ID_VARIABLE }}"
  });
</script>

Then update the config tag to read from a GTM variable:

<script>
  window.sophiWidgetConfig = {
    apiKey: "YOUR_API_KEY",
    userId: "{{DLV - sophiUserId}}",  // Data Layer Variable
    sdk: { autoLoad: true, url: "..." }
  };
</script>

For dynamic login/logout after page load, call the JavaScript API directly instead (see Identifying Users).


Step 5 — Preview and Test

  1. Click Preview in GTM to enter debug mode.
  2. Navigate to your site — the floating Sophi button should appear.
  3. In the GTM debug panel, verify both tags show as Fired on page load.
  4. Click the Sophi button — the chat modal should open and the widget should initialize.
  5. Trigger an add-to-cart action inside the widget and confirm your addToCart handler is called (check the browser console).

Step 6 — Publish

Once testing looks good:

  1. Click Submit in GTM.
  2. Add a version name (e.g. Add Sophi Widget Launcher).
  3. Click Publish.

The widget is now live for all visitors.


GTM Tag Summary

| Tag name | Type | Trigger | Fires before | |---|---|---|---| | Sophi - Widget Config | Custom HTML | All Pages | — | | Sophi - Widget Launcher | Custom HTML | All Pages | Sophi - Widget Config |


Consent Mode (Optional)

If your site uses a cookie consent solution (e.g. CookieBot, OneTrust), you should fire the launcher tags only after consent is granted.

Instead of All Pages, set the trigger to fire on your consent-granted event, for example:

  • CookieBot: cookiebot_accept event
  • OneTrust: OneTrustGroupsUpdated event
  • Custom: sophiConsentGranted — a custom event you push to dataLayer after the visitor accepts

This ensures the launcher only loads for visitors who have consented to analytics/marketing cookies.


Configuration

Set window.sophiWidgetConfig before the launcher script loads, or pass the same object to initSophiWidgetLauncher().

Required fields

| Field | Type | Description | |---|---|---| | apiKey | string | Your Sophi API key. |

All options

window.sophiWidgetConfig = {
  // Required
  apiKey: "YOUR_API_KEY",

  // Optional — identify the current user
  userId: "user-123",

  // Optional — "production" (default) | "staging" | "development"
  environment: "production",

  // SDK auto-loading
  sdk: {
    autoLoad: true,            // Set true to let the launcher load the SDK script
    url: "https://cdn.jsdelivr.net/npm/@usesophi/sophi-web-sdk@latest/dist/index.umd.js"
  },

  // Floating launcher button
  launcher: {
    enabled: true,             // Set false to hide the button and control via JS API
    position: "right-center",  // "right-center" | "left-center" | "right-bottom" | "left-bottom"
    text: "Start Chat",        // Label shown on hover
    backgroundColor: "#111827",
    textColor: "#ffffff"
  },

  // Chat modal
  modal: {
    title: "Sophi"             // Header text inside the modal
  },

  // Widget container (advanced — only change if you embed the widget elsewhere)
  widget: {
    containerSelector: "#sophi-widget",
    width: "100%",
    height: "100%"
  },

  // Event handlers (see Event Handlers section below)
  handlers: {
    addToCart: (data) => { /* ... */ },
    sendToCheckout: (data) => { /* ... */ },
    addToFavorite: (data) => { /* ... */ },
    error: (error) => { /* ... */ }
  }
};

Event Handlers

Sophi emits commerce events that your storefront must handle. You can register handlers in sophiWidgetConfig.handlers (preferred) or as global window functions.

| Event | Config handler | Global fallback | |---|---|---| | User adds a product to cart | handlers.addToCart(data) | window.sophiAddToCart(data) | | User proceeds to checkout | handlers.sendToCheckout(data) | window.sophiSendToCheckout(data) | | User adds a product to favourites | handlers.addToFavorite(data) | window.sophiAddToFavorite(data) | | Widget error | handlers.error(error) | — |

Example using config handlers:

<script>
  window.sophiWidgetConfig = {
    apiKey: "YOUR_API_KEY",
    sdk: { autoLoad: true, url: "..." },
    handlers: {
      addToCart: function (data) {
        console.log("Add to cart:", data);
        // call your storefront cart API here
      },
      sendToCheckout: function (data) {
        console.log("Send to checkout:", data);
        // redirect or open checkout here
      }
    }
  };
</script>

Example using global window functions (alternative):

<script>
  window.sophiAddToCart = function (data) {
    // call your storefront cart API here
  };

  window.sophiSendToCheckout = function (data) {
    // redirect or open checkout here
  };
</script>

JavaScript API

After the script loads, window.sophiWidget exposes the following methods. You can call these from any JavaScript on the page.

// Open the chat modal (initializes the widget on first call)
window.sophiWidget.open();

// Close the chat modal
window.sophiWidget.close();

// Manually initialize the widget without opening the modal
window.sophiWidget.init();

// Destroy the widget instance (e.g. on logout)
window.sophiWidget.destroy();

// Check whether the widget has been initialized
window.sophiWidget.isInitialized(); // → boolean

// Check whether the modal is currently open
window.sophiWidget.isOpen(); // → boolean

// Get the underlying SDK instance for advanced use
window.sophiWidget.getInstance();

// Set or update the current user ID
window.sophiWidget.setUserId("user-123");

// Subscribe to SDK events
window.sophiWidget.on("add_to_cart", (data) => { /* ... */ });

// Unsubscribe from SDK events
window.sophiWidget.off("add_to_cart", handler);

The widget is not initialized automatically on page load. It initializes on the first open() or init() call.


Identifying Users

Pass userId in the config to associate sessions with a known user:

<script>
  window.sophiWidgetConfig = {
    apiKey: "YOUR_API_KEY",
    userId: "user-123",  // logged-in user ID
    sdk: { autoLoad: true, url: "..." }
  };
</script>

To update the user after the page has loaded (e.g. after login or logout):

// After login
window.sophiWidget.setUserId("user-456");

// After logout — pass null or undefined to clear the user
window.sophiWidget.setUserId(null);

setUserId handles the session safely:

  • If the widget has not been opened yet, the new ID will be used on next open.
  • If the modal is open, the widget is restarted immediately with the new ID.
  • If the modal is closed, the widget is destroyed and will restart with the new ID on the next open.

Advanced: Disable the Launcher Button

Set launcher.enabled: false to hide the floating button and control the widget entirely through the JavaScript API. This is useful when you want to trigger Sophi from your own button or link.

<script>
  window.sophiWidgetConfig = {
    apiKey: "YOUR_API_KEY",
    sdk: { autoLoad: true, url: "..." },
    launcher: { enabled: false }
  };
</script>

<!-- Your own trigger -->
<button onclick="window.sophiWidget.open()">Ask Sophi</button>

Advanced: Manual SDK Loading

If you load the Sophi Web SDK yourself (e.g. it is already bundled in your app), omit sdk.autoLoad. The launcher will use window.SophiWebSDK directly.

<!-- Load the SDK first -->
<script src="https://cdn.jsdelivr.net/npm/@usesophi/sophi-web-sdk@latest/dist/index.umd.js"></script>

<!-- Then load the launcher without autoLoad -->
<script>
  window.sophiWidgetConfig = {
    apiKey: "YOUR_API_KEY"
    // sdk.autoLoad is false by default
  };
</script>
<script src="https://cdn.jsdelivr.net/npm/@usesophi/sophi-widget-launcher@latest/dist/sophi-widget-launcher.global.global.js" async></script>