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

nudgewidget

v1.0.0

Published

AI-powered multilingual navigation widget with Lingo.dev integration

Readme

Nudge Widget

AI-powered multilingual navigation widget for web apps. Users can type or speak commands in their language, and Nudge translates, understands intent, and automates navigation/form actions.

Features

  • Voice and text commands in multiple languages
  • Lingo.dev-powered translation for commands, responses, options, and page content
  • DOM automation: button clicking, form filling, option selection, submit
  • Guided multi-step workflows with translated questions/options
  • Shadow DOM UI isolation with floating launcher + chat panel
  • Translation stats tracking and local cache

Installation

npm install nudgewidget

Quick Start

import { createNudgeWidget, type NudgeWorkflow } from "nudgewidget";

const workflows: NudgeWorkflow[] = [
  {
    id: "invite-user",
    title: "Invite user",
    trigger: ["invite a user", "add teammate"],
    steps: [
      { type: "navigate", route: "/settings/team" },
      { type: "question", key: "email", prompt: "What email should I invite?" },
      { type: "fill", field: "email", valueKey: "email" },
      { type: "click", target: "Invite" },
      { type: "confirm", message: "Invitation sent." }
    ]
  }
];

const widget = createNudgeWidget({
  apiKey: "YOUR_LINGO_API_KEY",
  locales: {
    default: "en",
    supported: ["en", "es", "fr", "zh-CN", "hi", "ar"],
    autoDetect: true
  },
  navigation: {
    navigate: (path) => {
      // Integrate your router
      history.pushState({}, "", path);
      window.dispatchEvent(new PopStateEvent("popstate"));
    },
    getCurrentPath: () => window.location.pathname
  },
  workflows,
  ui: {
    brandName: "Nudge",
    accentColor: "#2563eb",
    position: "bottom-right"
  },
  features: {
    voice: true,
    pageTranslation: true,
    formAutofill: true
  },
  debug: false
});

widget.open();

Configuration

NudgeConfig

  • apiKey: required Lingo.dev API key.
  • locales.default: default locale.
  • locales.supported: allowed locales.
  • locales.autoDetect: detect browser locale on startup.
  • navigation.navigate(path): required route handler.
  • navigation.getCurrentPath(): optional route getter.
  • workflows: optional workflow definitions.
  • ui.position: bottom-right | bottom-left | top-right | top-left.
  • ui.brandName, ui.accentColor, ui.zIndex, ui.showTranslationStats, ui.darkMode.
  • features.voice, features.pageTranslation, features.formAutofill.
  • lingo.cacheEnabled, lingo.cacheTTL, lingo.batchSize, lingo.timeout, lingo.retryAttempts.
  • automation.clickDelay, automation.typeSpeed, automation.waitForNavigation.
  • debug.
  • mount: "auto" or custom HTMLElement.

Lingo.dev Integration

The package integrates directly with Lingo.dev translation endpoints from the browser client.

Nudge makes continuous translation calls during interactions:

  • user command -> English intent normalization
  • bot response -> user locale
  • workflow prompts/options -> user locale
  • workflow answers -> English for automation logic
  • page text batches during continuous translation mode

Translation cache reduces duplicate calls and tracks:

  • total calls
  • cache hits/misses
  • average latency
  • usage by context

Workflows

Workflow steps supported:

  • navigate
  • question
  • fill
  • select
  • click
  • confirm
  • suggest
  • wait
  • context

Workflow questions are translated to the user locale; answers are translated back to English and stored in workflow memory.

Usage Examples

React

import { useEffect } from "react";
import { createNudgeWidget } from "nudgewidget";

export function App() {
  useEffect(() => {
    const widget = createNudgeWidget({
      apiKey: process.env.REACT_APP_LINGO_KEY!,
      locales: { default: "en", supported: ["en", "es", "fr"] },
      navigation: { navigate: (path) => (window.location.href = path) }
    });

    return () => widget.destroy();
  }, []);

  return <main>Your app</main>;
}

Next.js

"use client";

import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { createNudgeWidget } from "nudgewidget";

export function NudgeBootstrap() {
  const router = useRouter();

  useEffect(() => {
    const widget = createNudgeWidget({
      apiKey: process.env.NEXT_PUBLIC_LINGO_KEY!,
      locales: { default: "en", supported: ["en", "es"] },
      navigation: { navigate: (path) => router.push(path) }
    });

    return () => widget.destroy();
  }, [router]);

  return null;
}

Vue

import { onMounted, onBeforeUnmount } from "vue";
import { createNudgeWidget } from "nudgewidget";

let widget: ReturnType<typeof createNudgeWidget> | null = null;

onMounted(() => {
  widget = createNudgeWidget({
    apiKey: import.meta.env.VITE_LINGO_KEY,
    locales: { default: "en", supported: ["en", "fr"] },
    navigation: { navigate: (path) => history.pushState({}, "", path) }
  });
});

onBeforeUnmount(() => {
  widget?.destroy();
});

Vanilla JS

<script type="module">
  import { createNudgeWidget } from "nudgewidget";

  const widget = createNudgeWidget({
    apiKey: "YOUR_LINGO_KEY",
    locales: { default: "en", supported: ["en", "es", "zh-CN"] },
    navigation: { navigate: (path) => history.pushState({}, "", path) }
  });

  window.nudge = widget;
</script>

API Reference

createNudgeWidget(config)

Returns NudgeInstance.

NudgeInstance

  • open()
  • close()
  • toggle()
  • setLocale(locale)
  • getLocale()
  • startWorkflow(workflowId)
  • cancelWorkflow()
  • getTranslationStats()
  • translatePage(locale)
  • stopPageTranslation()
  • on(event, handler)
  • destroy()

Troubleshooting

  • Widget does not appear:
    • ensure code runs in browser (not SSR-only path)
    • ensure createNudgeWidget executes after document.body exists
  • Voice button does nothing:
    • browser may not support Web Speech API
    • microphone permission may be blocked
  • Commands not understood:
    • check locales.supported and workflow trigger phrases
    • enable debug: true and inspect translated command/intent flow
  • Page translation not changing text:
    • highly dynamic virtualized UIs may require repeated observation windows
    • ensure elements are not inside the widget shadow root

Development

npm install
npm run test
npm run build

License

MIT