nudgewidget
v1.0.0
Published
AI-powered multilingual navigation widget with Lingo.dev integration
Maintainers
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 nudgewidgetQuick 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 customHTMLElement.
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:
navigatequestionfillselectclickconfirmsuggestwaitcontext
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
createNudgeWidgetexecutes afterdocument.bodyexists
- Voice button does nothing:
- browser may not support Web Speech API
- microphone permission may be blocked
- Commands not understood:
- check
locales.supportedand workflow trigger phrases - enable
debug: trueand inspect translated command/intent flow
- check
- 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 buildLicense
MIT
