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

@wexio/messenger-widget-react

v1.0.28

Published

Native React component embed for the Wexio web messenger. Renders inside a Shadow DOM portal for style isolation.

Readme

Welcome to @wexio/messenger-widget-react 👋

Version License: MIT Documentation

Native React component for the Wexio web messenger. Renders inside a Shadow DOM portal for full style isolation — same WidgetShell runtime as the script-injected iframe and the <wexio-widget> web component. Same chat, same visitor identity, same backend; the only difference is where the React tree mounts.

🏠 Website 📚 Developer Docs

📂 Description

Installation

yarn add @wexio/messenger-widget-react

or

npm install @wexio/messenger-widget-react

react >= 18 and react-dom >= 18 are peer dependencies — the widget uses the host's React tree.

Quick start

Import the package on every page that should display the messenger (or on a common component used by them) and render the component. This must be done on the client side.

import { WexioWidget } from "@wexio/messenger-widget-react";

export default function App() {
  return (
    <>
      {/* your app */}
      <WexioWidget publicKey="pk_live_..." />
    </>
  );
}

That's it — the widget mounts a floating launcher, handles its own theme/locale/state, and the operator dashboard sees the visitor immediately. The component manages its own lifecycle internally, so re-renders due to host DOM changes won't trigger a re-boot.

Identifying users

Pass a verified user to log a known visitor in (the Wexio equivalent of Intercom's boot({ user_id, ... })). Provide ONE proof — a Google FedCM id_token, a host-signed jwt, or the legacy userId + userHash HMAC pair:

<WexioWidget
  publicKey="pk_live_..."
  user={{
    jwt: serverSignedJwt, // host-signed identity token (recommended)
    name: "Ada Lovelace",
    email: "[email protected]",
  }}
/>

Memoise user. Fresh object literals every render churn the env (the handshake is internally guarded against re-firing unless the proof actually changes, but it's tidier to avoid).

Props

| Prop | Type | Description | | ----------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | publicKey | string | Wexio integration public key (pk_live_...). Omit to render in demo mode (bundled mock content for landing pages or Storybook). | | user | VisitorIdentity | Verified identity. See Identifying users. | | config | InjectableWidgetConfig | Pre-resolved widget config. Set this if you already have the config server-rendered or fetched app-wide — skips the bootstrap fetch. | | onResize | (size: { width: number; height: number }) => void | Fired whenever the widget's intended dimensions change (open ↔ closed ↔ expanded). Use for host-side layout sync. | | onOpen | () => void | Fired when the visitor opens the panel (taps the launcher, peek bubble, etc.). | | onClose | () => void | Fired when the visitor taps the close chip. | | className | string | Pass-through class on the outer host <div>. Style this with normal layout CSS. | | style | React.CSSProperties | Pass-through inline styles for the outer host <div>. |

UI locale is operator-controlled. The widget ships 33 UI locales (English, Ukrainian, German, Spanish — incl. es-MX, French, Italian, Dutch, Portuguese — incl. pt-BR, Swedish, Danish, Norwegian, Finnish, Polish, Czech, Slovak, Turkish, Romanian, Hungarian, Greek, Arabic, Hebrew, Hindi, Thai, Vietnamese, Indonesian, Japanese, Korean, Chinese — zh + zh-TW, plus regional English variants). The operator's localeStrategy (set in the Wexio dashboard) decides whether to follow the visitor's browser (AUTO), the host page's <html lang> (WEBSITE), or pin to a chosen language (DEFAULT + defaultLocale). The visitor can also override their language from the in-widget Profile tab.

Bot protection (Cloudflare Turnstile)

When the operator enables Cloudflare Turnstile for the integration (Wexio dashboard → Security), the widget transparently runs an interaction-only challenge before the visitor handshake — no host wiring required. The launcher stays unclickable until the challenge resolves; on failure a small "couldn't verify you're human" popup appears anchored above the launcher with a retry button. The challenge token is attached to the prechat and identified-visitor handshake server-side, so operator-side rate-limiting / abuse rules apply automatically.

Methods

The component's open / close lifecycle is driven via the onOpen / onClose callbacks plus the visitor's tap on the launcher — no host-side imperative call is needed for normal use.

An imperative window.WexioWidget surface (show, hide, showSpace, setLocale, onUnreadCountChange, …) is on the roadmap to mirror the script loader's API, but doesn't ship in the current React package. For deep-link / programmatic control today, mount the widget conditionally from your own host state.

Types

VisitorIdentity

interface VisitorIdentity {
  googleIdToken?: string; // Google FedCM id_token (preferred)
  jwt?: string;           // Host-signed JWT
  userId?: string;        // Legacy HMAC pair…
  userHash?: string;      // …(HMAC-SHA256(userId, integrationSecret))
  name?: string;
  email?: string;
  phone?: string;
  attributes?: Record<string, unknown>;
}

InjectableWidgetConfig

The pre-resolved widget config shape (theme, features, blocks, prechat, messenger chrome, sounds, locale strategy, bot protection). Pull it from the package:

import type { InjectableWidgetConfig } from "@wexio/messenger-widget-react";

The integration's Cloudflare Turnstile bot-protection check (when the operator enables it in the Wexio dashboard) is wired automatically — the widget loads the CF script, runs the challenge before the visitor handshake, and shows a retry popup above the launcher if the challenge fails. Hosts don't need to wire anything extra.

SSR

The component renders null on the server. The Shadow-DOM portal target mounts on the first useEffect, so the widget is invisible during SSR/hydration and appears on first paint. Wrap in <Suspense fallback={null}> if you need to defer hydration in RSC-heavy apps.

Browser support

Modern evergreen browsers — anything that supports Shadow DOM and ES2020. Internet Explorer is not supported.

Troubleshooting

Messenger not showing on page

  • Check that the correct publicKey is being passed.
  • Check the messenger is active for your integration on https://app.wexio.io.
  • Confirm the component renders on the client (not during SSR) — <WexioWidget> returns null until the first useEffect.

No user data attached

  • Verify you're computing userHash server-side as HMAC-SHA256(userId, integrationSecret). Never expose the integration secret to the browser.
  • Confirm the proof you pass in user is one of: googleIdToken, jwt, or userId + userHash. Passing multiple proofs uses the first one detected (Google → jwt → HMAC).

TypeScript errors after upgrade

The public type surface is locked to entries/public.ts in the source repo. If you previously relied on undocumented props (locale, prefill, lightboxViewport, mode, configOverride, useDummyData, previewData), they are no longer exposed — they were either dashboard-only or moved to operator-side config. Remove them and the build will pass. The widget auto-resolves to production when publicKey is set and demo (bundled mock content) otherwise; UI locale is controlled by the operator's localeStrategy config and the visitor's Profile-tab language switcher.

Use with other frameworks

The underlying widget runtime is a Web Component, so it works in any modern framework — even without a typed wrapper:

<wexio-widget public-key="pk_live_..."></wexio-widget>
<script type="module" src="https://cdn.wexio.io/widget/widget.js"></script>

Typed wrappers for the popular frameworks:

For plain HTML / script-injection setups, paste the loader snippet from https://learn.wexio.io/docs/web-widget.

Author

👤 Wexio (https://wexio.io)

Show your support

Give a ⭐️ if this package helped you!

📝 License

This project is MIT licensed.


Created with ❤️ by Wexio