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

@olotalk/widget-loader

v0.14.0

Published

Embed the [Olotalk](https://olotalk.com) AI chat widget on any website with a single `<script>` tag — no framework required.

Readme

@olotalk/widget-loader

Embed the Olotalk AI chat widget on any website with a single <script> tag — no framework required.

The loader handles config fetching, browser compatibility detection, and dynamic loading of the widget bundle from the CDN. Your visitors get a grounded, RAG-powered chat assistant that answers questions based on your own content.


Quick start

<script
  src="https://cdn.jsdelivr.net/npm/@olotalk/widget-loader@0/dist/loader.iife.js"
  data-olotalk-widget-id="YOUR_WIDGET_ID"
  async
></script>

Paste this before </body> on any page. The widget appears immediately as a floating launcher in the bottom-right corner. The published bundle bakes in https://api.olotalk.com as the default API origin — self-hosters override with data-olotalk-origin.

Get your widget ID from the Olotalk dashboard.


Configuration

Via HTML attributes

All attributes are read from the <script> tag itself.

| Attribute | Type | Description | |---|---|---| | data-olotalk-widget-id | string | Required. Your widget ID from the dashboard. | | data-olotalk-origin | string | Base URL of your Olotalk API. Optional for Olotalk Cloud (the published bundle defaults to https://api.olotalk.com); set this only when self-hosting the BFF. | | data-olotalk-locale | string | Force a display language. Accepts any well-formed BCP-47 tag (e.g. "en", "fr", "vi", "ja-JP"). When omitted, the loader auto-detects from the visitor's stored preference, the page's <html lang>, then navigator.language — bounded by the widget's supportedLocales so an unsupported visitor language falls through to the operator's default. | | data-olotalk-version | string | Pin a specific published @olotalk/widget npm version. | | data-olotalk-cdn-base | string | Override the widget asset base URL (for self-hosting). |

Via window.OlotalkConfig

Declare a global config object before the loader script for programmatic setup:

<script>
  window.OlotalkConfig = {
    widgetId: "YOUR_WIDGET_ID",
    locale: "fr",
    theme: "dark",
    placement: "embedded",
    mount: "#chat-container",
    // origin: "https://bff.example.com", // self-hosted only
  };
</script>
<script src="https://cdn.jsdelivr.net/npm/@olotalk/widget-loader@0/dist/loader.iife.js"></script>

Full config reference

| Option | Type | Default | Description | |---|---|---|---| | widgetId | string | — | Required. Your widget ID. | | origin | string | https://api.olotalk.com (cloud build) | Base URL of your Olotalk API. Self-hosters override; the source-level fallback is window.location.origin. | | locale | string | Auto-detected | Force language. Any BCP-47 tag (e.g. "en", "fr", "vi", "ja-JP"). When omitted, the loader uses (in order): visitor's localStorage preference → page <html lang>navigator.language, gated by the widget's supportedLocales. | | theme | "light" | "dark" | object | "light" | Color scheme or custom theme overrides. | | placement | "floating" | "embedded" | "floating" | Floating launcher button or inline panel. | | mount | string | document.body | CSS selector for the widget mount point (use with "embedded"). | | version | string | matching widget package version | Pin a specific @olotalk/widget npm version (e.g. "0.12.0"). When omitted, the loader resolves the published widget version that matches the loader build, then uses version.json for cache-busting when available. | | cdnBase | string | jsDelivr CDN | Override widget asset base URL for self-hosting. | | cssUrl | string | Auto-resolved | Override the widget CSS URL. In a future release this will be provided automatically by the widget config from the dashboard. |


JavaScript API

The loader exposes a global Olotalk() command queue. You can call it before or after the script loads.

// Open or close the panel programmatically
Olotalk('open')
Olotalk('close')

// Re-initialize with a different config
Olotalk('init', { locale: 'fr' })

// Remove the widget from the page entirely
Olotalk('destroy')

Commands queued before the widget loads are replayed automatically once it is ready.


Multilingual

The widget supports any BCP-47 locale out of the box. The operator declares which languages their site ships (supportedLocales) in the dashboard; the runtime handles the rest.

Resolution priority (chrome language)

  1. Explicit data-olotalk-locale / OlotalkConfig.locale
  2. Visitor's previously-accepted choice (localStorage, per widget)
  3. Page's <html lang> — primary signal on multilingual sites with one URL per language
  4. navigator.language — visitor's browser preference
  5. Operator's defaultLocale from the dashboard

Steps 3 and 4 are gated by supportedLocales: if the operator declares ["fr"], an English-speaking visitor falls through to French chrome (intentional — the site has no English content to ground on).

Adaptive switching

When a visitor types their first message in a different supported language than the current chrome (e.g. a French question on an English widget configured for both), the bot replies in that language and the widget surfaces a small inline toast: "Continue in French? · Yes / No". On Yes, the entire chrome flips to French and the choice is persisted to localStorage so the next session opens directly in French.

Static vs LLM-translated locales

| Tier | Locales | Latency | |---|---|---| | Hand-translated | en, fr, de (+ regional aliases) | Zero — bundled | | LLM-translated | Any other BCP-47 (vi, ja, ar, sw, …) | One-time ~1–3s on first load per locale, then cached |

See ADR 0050 for the full design.


Version pinning

By default, the loader fetches the published @olotalk/widget version that matches the loader build. To override that and lock a specific widget version:

<!-- Pin widget bundle to a specific version -->
<script
  src="https://cdn.jsdelivr.net/npm/@olotalk/widget-loader@0/dist/loader.iife.js"
  data-olotalk-widget-id="YOUR_WIDGET_ID"
  data-olotalk-version="0.12.0"
></script>

Or pin the loader itself by version:

<script src="https://cdn.jsdelivr.net/npm/@olotalk/widget-loader@0/dist/loader.iife.js" ...></script>

When version is pinned, the loader skips the build-version lookup and loads that exact package version directly.


Asset versioning

When version is omitted, the loader fetches ${base}/version.json with cache: "no-cache" and appends ?v=<buildVersion> to the widget JS, IIFE, and auto-resolved CSS URLs. This keeps same-page reloads fresh during local development and makes immutable caching safe for self-hosted or CDN-served widget bundles.

If version.json is unavailable or cannot be fetched, the loader falls back to the unversioned asset URLs.


Self-hosting

To serve widget assets from your own server instead of jsDelivr:

<script
  src="/path/to/loader.iife.js"
  data-olotalk-widget-id="YOUR_WIDGET_ID"
  data-olotalk-cdn-base="/assets/widget"
></script>

The loader will fetch olotalk-widget.js, olotalk-widget.iife.js, olotalk-widget.css, and version.json from the provided base URL.

If data-olotalk-cdn-base points to a different origin, version.json must be fetchable with CORS enabled for automatic cache-busting. If not, the loader still works but falls back to the unversioned asset URLs.


npm install

If you are using a bundler or framework, you can import the loader directly:

npm install @olotalk/widget-loader
import { ensureWidget } from '@olotalk/widget-loader'

ensureWidget({
  widgetId: 'YOUR_WIDGET_ID',
  // origin: 'https://bff.example.com', // self-hosted only
})

License

MIT © Olotalk