Skip to content

Conversation

@17prateek12
Copy link

@17prateek12 17prateek12 commented Jan 23, 2026

Voice Translation Assistant Demo

This PR adds a new community project under /community/voice-translation-assistance.

✅ Features

  • Speech-to-Text using Web Speech API
  • AI Translation using Lingo.dev SDK (via backend)
  • Multi-language support
  • Text-to-Speech output
  • Clean frontend UI
  • Dedicated backend with retry support
  • Complete README for both frontend and backend

📁 Project Structure

community/
└── voice-translation-assistance-backend/
└── voice-translation-assistance-frontend/

This project is intended as a community demo showing how to use the Lingo.dev SDK in real-time translation workflows.

Summary by CodeRabbit

  • New Features
    • Introduced a Voice Translation Assistant featuring a backend API for text translation and a React-based frontend enabling users to record voice, transcribe audio, translate to multiple languages, and playback translations via text-to-speech synthesis.
    • Key features include language selection, intuitive UI controls for recording and playback, and debounced translation requests for optimized performance.

✏️ Tip: You can customize this high-level summary in your review settings.

davidturnbull and others added 30 commits September 23, 2025 18:43
* fix: lockedKeys in xcstrings

* chore: formatting
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: add biome formatter

* chore: formatting

* chore: removed console.log

* chore: changeset
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix: upd biome formatter

* chore: add changeset
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix: upd biome formatting logging

* chore: add changeset
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix: biome JS API v3 bug

* chore: add changeset
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add Product lingodotdev#1 of week badge

Added badge for Product Hunt lingodotdev#1 Product of the Week.

* Add/update PH badges

Updated Product Hunt badge from lingodotdev#1 to lingodotdev#2 for Product of the Day and added couple of other badges

* Fix: badge description (week) for Product Hunt recognition

* chore: add changeset

---------

Co-authored-by: Sumit Saurabh <sumitm4pro@192.168.1.4>
* fix: use initial checksums for all retranslation buckets

* chore: add changeset

* chore: fix formatting
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: add provider settings

* chore: formatting and changeset

* chore: removed a redundant test
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…otdev#1218)

* feat: add 'show locked-keys' and 'show ignored-keys' commands

* chore: add changeset

* chore: fix formatting
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix: regex replacement

* chore: add changeset
github-actions bot and others added 24 commits January 20, 2026 09:42
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
…odotdev#1270)

* Add Malayalam translation for README and update i18n.json

* chore: add changeset for Malayalam translation update

* Update readme/ml.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update readme/ml.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: fix Malayalam README and i18n.json (remove 'or')

* chore: add signed commit

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sumit Saurabh <62152915+sumitsaurabh927@users.noreply.github.com>
Co-authored-by: Max Prilutskiy <5614659+maxprilutskiy@users.noreply.github.com>
Co-authored-by: Veronica Prilutskaya <veronica@lingo.dev>
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
Co-authored-by: Lingo.dev <support@lingo.dev>
* chore: fix readme

* chore: empty changeset
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
* chore: upgrade to ai sdk 5 to resolve security vulns

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* chore: changeset

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* feat: upgrade to zod 4

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* chore: remove zod-to-json-schema from the codebase

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: use "Z" not "z"

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: use error.issues

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: perform more zod 4 migrations

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: resolve type errors in mcp.ts (used any, might manually verify
everything still works fine)

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: remove defaults from optional fields in zod 4 (fixes failing tests)

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* chore: fmt

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* chore: remove unused zod-to-json-schema dep

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: use prefault

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: revert

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: upgrade new deps

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: sort deps

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* fix: revert to zod 3 for docs script

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* chore: upgrade to ai sdk 6

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

* chore: sync lockfile

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>

---------

Signed-off-by: The-Best-Codes <bestcodes.official@gmail.com>
Co-authored-by: Max Prilutskiy <5614659+maxprilutskiy@users.noreply.github.com>
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
* chore: remove old mcp command

* chore(cli): changeset
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
…flag is used (lingodotdev#1776)

Co-authored-by: AndreyHirsa <--global>
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
…patibility (lingodotdev#1759)

* feat(cli): integrate glob package and add lingo.dev command script

* feat(cli): add lingo.dev command script for Windows

* chore(cli): remove incorrect lingo.dev command script for Windows

* chore(cli): rename command script from lingo.dev to lingo

* chore(cli): update command handling for Windows 11 bash compatibility

---------

Co-authored-by: Max Prilutskiy <5614659+maxprilutskiy@users.noreply.github.com>
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
* feat(cli): integrate glob package and add lingo.dev command script

* feat(cli): add lingo.dev command script for Windows

* chore(cli): remove incorrect lingo.dev command script for Windows

* chore(cli): rename command script from lingo.dev to lingo

* chore(cli): update command handling for Windows 11 bash compatibility

* chore(cli): rename CLI binary entry point to 'lingo.dev'

* chore: add changeset for rolling back 'lingo.dev' version

---------

Co-authored-by: Max Prilutskiy <5614659+maxprilutskiy@users.noreply.github.com>
Co-authored-by: Veronica Prilutskaya <veronica@lingo.dev>
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
* chore(cli): rename CLI binary entry point from 'lingo' to 'lingo.dev'

* chore: add changeset for rolling back 'lingo.dev' version
Co-authored-by: Max Prilutskiy <maks.prilutskiy@gmail.com>
@ashutoshdebug
Copy link
Contributor

@17prateek12 looks like something bad happened!

@coderabbitai
Copy link

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

A complete voice-to-text translation application is introduced with Node.js/Express backend and React/Vite frontend. The backend provides a translation API using the Lingo.dev SDK with retry logic. The frontend offers speech recording, transcription, translation to selected target languages, and audio playback of translations.

Changes

Cohort / File(s) Summary
Backend Configuration
community/voice-translation-assistance-backend/.gitignore, community/voice-translation-assistance-backend/README.md, community/voice-translation-assistance-backend/envSample
Standard project setup: ignore patterns, documentation, and environment variable template. No logic changes.
Backend Application
community/voice-translation-assistance-backend/index.js
Express server with CORS/JSON middleware, translation endpoint (POST /translate), retry logic (up to 3 attempts with 800ms delays), Lingo.dev SDK integration, and global error handling.
Backend Dependencies
community/voice-translation-assistance-backend/package.json
Node.js manifest declaring Express, Lingo.dev SDK, dotenv, cors, and nodemon as ES module project.
Frontend Configuration
community/voice-translation-assistance-frontend/.gitignore, community/voice-translation-assistance-frontend/README.md, community/voice-translation-assistance-frontend/eslint.config.js, community/voice-translation-assistance-frontend/index.html, community/voice-translation-assistance-frontend/vite.config.ts
Project scaffolding: git ignores, documentation, ESLint rules for React/TypeScript, HTML entry point, and Vite configuration with React plugin.
Frontend TypeScript Configuration
community/voice-translation-assistance-frontend/tsconfig.json, community/voice-translation-assistance-frontend/tsconfig.app.json, community/voice-translation-assistance-frontend/tsconfig.node.json
TypeScript compiler configuration with strict type-checking, JSX support (react-jsx), and separate configs for app and build tooling.
Frontend Dependencies
community/voice-translation-assistance-frontend/package.json
React/Vite manifest with dev server, build, lint, and preview scripts; includes React, Lingo.dev, ESLint, TypeScript, and Vite tooling.
Frontend Styling
community/voice-translation-assistance-frontend/src/index.css, community/voice-translation-assistance-frontend/src/App.css
Global typography, color scheme (dark/light theme), layout, and component styling (buttons, containers, controls).
Frontend Components
community/voice-translation-assistance-frontend/src/main.tsx, community/voice-translation-assistance-frontend/src/App.tsx, community/voice-translation-assistance-frontend/src/VoiceAssistant.tsx
React application entry, top-level App wrapper, and main VoiceAssistant component featuring state management (translatedText, targetLocale, loading), speech recognition/synthesis integration, debounced translation requests to backend, and UI for recording, language selection, translation, and playback.
Frontend Speech Hooks
community/voice-translation-assistance-frontend/src/speech/useSpeechRecognition.ts, community/voice-translation-assistance-frontend/src/speech/useSpeechSynthesis.ts
Custom React hooks: useSpeechRecognition wraps Web Speech API with transcript capture and state management; useSpeechSynthesis provides text-to-speech with locale-aware voice selection.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Browser as Browser/Frontend
    participant Backend as Express Backend
    participant LingoAPI as Lingo.dev API

    User->>Browser: Click "Start Recording"
    activate Browser
    Browser->>Browser: Capture audio & transcribe (Web Speech API)
    User->>Browser: Click "Translate"
    Browser->>Browser: Debounce & prepare request
    Browser->>Backend: POST /translate {text, targetLocale}
    activate Backend
    Backend->>Backend: Attempt translation (Retry 1/3)
    Backend->>LingoAPI: Translate text
    activate LingoAPI
    LingoAPI-->>Backend: Translated text
    deactivate LingoAPI
    Backend-->>Browser: {translated: "..."}
    deactivate Backend
    Browser->>Browser: Update UI with translation
    Browser->>Browser: Speak translation (Web Speech API)
    User->>Browser: Hear audio playback
    deactivate Browser
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hops through code with springy cheer
Backend sings, frontend's clear!
Voices dance from land to land,
Translation magic, by Lingo's hand! ✨🎙️

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description provides a clear summary, lists key features, shows project structure, and explains the purpose, but does not follow the repository's template structure including explicit Changes, Testing, Visuals, or Checklist sections. Consider restructuring the description to match the template: add a Changes section listing key additions, include a Testing section with test coverage details, and complete the Checklist section regarding changesets and breaking changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Community voice translation assistant' is directly related to and accurately describes the main change: adding a new community demo project for voice translation with frontend and backend components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In `@community/voice-translation-assistance-backend/index.js`:
- Around line 11-16: Set a sane default for PORT and fail fast on missing
required env vars: if process.env.PORT is undefined, default PORT constant (used
by app.listen) to a known value (e.g., 3000) and validate that
process.env.LINGO_API_KEY exists before instantiating LingoDotDevEngine; if
LINGO_API_KEY is missing log an error with context (including the env var name)
and exit process with non-zero status so the app doesn't start or create the SDK
in a partially configured state. Ensure you update the const PORT declaration
and add a pre-check before the new LingoDotDevEngine(...) call that uses
processLogger or console.error and process.exit(1) on failure.

In `@community/voice-translation-assistance-backend/README.md`:
- Around line 15-43: Update the README.md fenced code blocks to include language
identifiers to satisfy MD040: change the project structure block to ```text, the
installation and run-server blocks to ```bash, and the .env example block to
```dotenv; modify the three code fences around the "Project Structure",
"Installation", "Environment Variables" (the `.env` example), and "Run the
Server" sections accordingly so markdownlint passes and rendering improves.

In `@community/voice-translation-assistance-frontend/src/App.css`:
- Line 20: The box-shadow declaration `box-shadow: 5px 2px 5px 2px;` in App.css
is missing a color value; update that declaration to include an explicit color
(for example a hex, rgba()/hsla() with alpha, or a CSS variable like
var(--shadow-color)) so the shadow renders intentionally (e.g., add a color to
`box-shadow: 5px 2px 5px 2px <color>`), and ensure any theme variable exists if
you reference one.

In
`@community/voice-translation-assistance-frontend/src/speech/useSpeechRecognition.ts`:
- Around line 21-22: The inline comment for recognition.continuous is incorrect:
change or remove the misleading comment next to recognition.continuous = false
in useSpeechRecognition.ts so it accurately describes behavior (recognition will
stop automatically after the first final result when continuous is false, not
"stops only when user stops manually"); update the comment text to reflect that
or delete it entirely to avoid confusion.

In
`@community/voice-translation-assistance-frontend/src/speech/useSpeechSynthesis.ts`:
- Around line 5-6: getVoices() may return an empty array on first call; update
useSpeechSynthesis to load and cache voices asynchronously by adding a useEffect
that calls speechSynthesis.getVoices(), assigns them to state (e.g., voices),
and also registers a 'voiceschanged' event listener to update that state when
voices load; then compute voice via voices.find((v) =>
v.lang.startsWith(locale)) from the cached state (not a direct synchronous
getVoices() call), and clean up the event listener on unmount.

In `@community/voice-translation-assistance-frontend/src/VoiceAssistant.tsx`:
- Around line 23-24: translateTimeout and isTranslating are declared as local
lets in the VoiceAssistant component so they reset every render, breaking
debounce and concurrency guards; replace them with persistent refs by creating
const translateTimeoutRef = useRef<any>(null) and const isTranslatingRef =
useRef<boolean>(false) inside the component, update all reads/writes to use
translateTimeoutRef.current and isTranslatingRef.current, and clear/assign the
timeout and toggle the translating flag via those refs (and clean up the timeout
in useEffect return) to preserve state across renders.
🧹 Nitpick comments (11)
community/voice-translation-assistance-backend/envSample (1)

1-2: Consider adding example values to reduce setup friction.
This makes the sample immediately actionable for new users.

♻️ Suggested update
-LINGO_API_KEY=
-PORT=
+LINGO_API_KEY=your_lingodotdev_api_key_here
+PORT=3001
community/voice-translation-assistance-frontend/src/speech/useSpeechSynthesis.ts (1)

1-14: Consider adding browser support check.

Unlike the useSpeechRecognition hook which checks for browser support, this hook will throw if speechSynthesis is unavailable (e.g., during SSR or in unsupported browsers).

Add a guard check
   function speak(text: string, locale: string) {
+    if (typeof speechSynthesis === "undefined") {
+      console.warn("SpeechSynthesis not supported");
+      return;
+    }
     const msg = new SpeechSynthesisUtterance(text);
community/voice-translation-assistance-frontend/src/speech/useSpeechRecognition.ts (2)

9-11: SpeechRecognition detection runs on every render.

The browser API lookup runs on each render. While not a performance issue in practice, moving it outside the component or memoizing would be cleaner.

Move detection outside the hook
+const SpeechRecognition =
+  typeof window !== "undefined"
+    ? (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition
+    : null;
+
 export default function useSpeechRecognition() {
   const [listening, setListening] = useState(false);
   const [transcript, setTranscript] = useState("");

   const recognitionRef = useRef<any>(null);

-  const SpeechRecognition =
-    (window as any).SpeechRecognition ||
-    (window as any).webkitSpeechRecognition;

34-36: Error state not exposed to consumers.

The error handler logs to console but doesn't update any state. The calling component has no way to know if recognition failed and cannot display appropriate feedback to users.

Consider exposing error state
 export default function useSpeechRecognition() {
   const [listening, setListening] = useState(false);
   const [transcript, setTranscript] = useState("");
+  const [error, setError] = useState<string | null>(null);
   ...
   recognition.onerror = (e: any) => {
     console.error("SpeechRecognition error:", e);
+    setError(e.error || "Recognition error");
   };
   ...
-  return { startListening, stopListening, listening, transcript };
+  return { startListening, stopListening, listening, transcript, error };
 }
community/voice-translation-assistance-frontend/README.md (3)

14-25: Add language specifiers to fenced code blocks.

The project structure code block should have a language specifier for proper rendering. Additionally, the documented structure shows frontend/ but the actual path is community/voice-translation-assistance-frontend/.

📝 Suggested fix
 ## 📂 Project Structure
-```
+```text
 frontend/
   src/
     VoiceAssistant.tsx
     speech/
       useSpeechRecognition.ts
       useSpeechSynthesis.ts
   vite.config.ts
   package.json
   README.md
</details>

---

`31-39`: **Add language specifiers to command code blocks.**

Per static analysis, fenced code blocks should specify a language for proper syntax highlighting.



<details>
<summary>📝 Suggested fix</summary>

```diff
 ## 📦 Installation
-```
+```bash
 npm install

▶️ Start Development Server

- +bash
npm run dev


49-53: Screenshot filenames contain spaces.

Filenames with spaces can cause issues in some environments and markdown renderers. Consider renaming screenshots to use hyphens or underscores.

📝 Suggested naming
-![alt text](<Screenshot 2026-01-23 185408.png>) 
-![alt text](<Screenshot 2026-01-23 184635.png>) 
-![alt text](<Screenshot 2026-01-23 184733.png>)
+![Voice Assistant UI](screenshot-2026-01-23-185408.png)
+![Recording View](screenshot-2026-01-23-184635.png)
+![Translation View](screenshot-2026-01-23-184733.png)
community/voice-translation-assistance-frontend/src/App.tsx (1)

4-12: Minor formatting inconsistency.

Line 8 has an extra leading space before the <h1> tag compared to the <VoiceAssistant /> element. This is a nitpick but worth noting for consistency.

📝 Suggested fix
 function App() {
-
   return (
     <div className="app">
-       <h1>🎙️ Multilingual Voice Assistant</h1>
+      <h1>🎙️ Multilingual Voice Assistant</h1>
       <VoiceAssistant />
     </div>
   )
 }
community/voice-translation-assistance-backend/package.json (1)

6-9: Move nodemon to devDependencies and add a production start script.

nodemon is a development tool for auto-restarting the server during development. It should not be in dependencies as it's not needed in production. Additionally, there's no production-ready start script.

Suggested changes
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
-    "start": "nodemon index.js"
+    "start": "node index.js",
+    "dev": "nodemon index.js"
   },
   ...
   "dependencies": {
     "cors": "^2.8.6",
     "dotenv": "^17.2.3",
     "express": "^5.2.1",
-    "lingo.dev": "^0.125.0",
-    "nodemon": "^3.1.11"
-  }
+    "lingo.dev": "^0.125.0"
+  },
+  "devDependencies": {
+    "nodemon": "^3.1.11"
+  }

Also applies to: 14-20

community/voice-translation-assistance-frontend/src/VoiceAssistant.tsx (2)

37-37: Hardcoded backend URL limits deployment flexibility.

The URL http://localhost:3001/translate is hardcoded. For a community demo this is acceptable, but consider using an environment variable for easier configuration.

Suggested approach
-      const res = await fetch("http://localhost:3001/translate", {
+      const res = await fetch(`${import.meta.env.VITE_API_URL || 'http://localhost:3001'}/translate`, {

12-12: Minor: Inconsistent indentation.

The English language entry has an extra leading space compared to the other entries.

-   { code: "en", name: "English" },
+  { code: "en", name: "English" },

Comment on lines +11 to +16
const PORT = process.env.PORT;

const lingo = new LingoDotDevEngine({
apiKey: process.env.LINGO_API_KEY,
timeout:20000,
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add default PORT and validate required environment variables at startup.

If PORT is undefined, app.listen(PORT) behavior is unpredictable. If LINGO_API_KEY is missing, the SDK initialization may succeed but fail on first API call, making debugging harder.

Proposed fix
 dotenv.config();
+
+const LINGO_API_KEY = process.env.LINGO_API_KEY;
+if (!LINGO_API_KEY) {
+  console.error("❌ Missing required environment variable: LINGO_API_KEY");
+  process.exit(1);
+}
+
 const app = express();
 app.use(cors());
 app.use(express.json());

-const PORT = process.env.PORT;
+const PORT = process.env.PORT || 3001;

 const lingo = new LingoDotDevEngine({
-  apiKey: process.env.LINGO_API_KEY,
-  timeout:20000,
+  apiKey: LINGO_API_KEY,
+  timeout: 20000,
 });
🤖 Prompt for AI Agents
In `@community/voice-translation-assistance-backend/index.js` around lines 11 -
16, Set a sane default for PORT and fail fast on missing required env vars: if
process.env.PORT is undefined, default PORT constant (used by app.listen) to a
known value (e.g., 3000) and validate that process.env.LINGO_API_KEY exists
before instantiating LingoDotDevEngine; if LINGO_API_KEY is missing log an error
with context (including the env var name) and exit process with non-zero status
so the app doesn't start or create the SDK in a partially configured state.
Ensure you update the const PORT declaration and add a pre-check before the new
LingoDotDevEngine(...) call that uses processLogger or console.error and
process.exit(1) on failure.

Comment on lines +15 to +43
## 📂 Project Structure
```
backend/
index.js
package.json
.env
README.md
```

## 🔧 Requirements
- Node.js 18+
- Lingo.dev API Key

## 📦 Installation
```
npm install
```

## 🔐 Environment Variables
Create `.env`:
```
LINGO_API_KEY=your_lingodotdev_api_key_here
PORT=3001
```
Noted: use only 3001 port, otherwise in frontend.

## ▶️ Run the Server
```
npm start
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks (MD040).
This satisfies markdownlint and improves rendering.

✅ Suggested fix
-## 📂 Project Structure
-```
+## 📂 Project Structure
+```text
 backend/
   index.js
   package.json
   .env
   README.md

@@
-## 📦 Installation
- -npm install -
+## 📦 Installation
+bash +npm install +
@@
-Create .env:
- +Create `.env`: +dotenv
LINGO_API_KEY=your_lingodotdev_api_key_here
PORT=3001

@@
-## ▶️ Run the Server
-```
-npm start
-```
+## ▶️ Run the Server
+```bash
+npm start
+```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

16-16: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


29-29: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


35-35: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


42-42: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@community/voice-translation-assistance-backend/README.md` around lines 15 -
43, Update the README.md fenced code blocks to include language identifiers to
satisfy MD040: change the project structure block to ```text, the installation
and run-server blocks to ```bash, and the .env example block to ```dotenv;
modify the three code fences around the "Project Structure", "Installation",
"Environment Variables" (the `.env` example), and "Run the Server" sections
accordingly so markdownlint passes and rendering improves.

flex-direction: column;
border-radius: 10px;
padding: 20px;
box-shadow: 5px 2px 5px 2px;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Box-shadow missing color value.

The box-shadow: 5px 2px 5px 2px; declaration is missing a color. Browsers will default to currentColor (black), but this appears unintentional given the shadow syntax structure.

Suggested fix
-  box-shadow: 5px 2px 5px 2px;
+  box-shadow: 5px 2px 5px 2px rgba(0, 0, 0, 0.1);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
box-shadow: 5px 2px 5px 2px;
box-shadow: 5px 2px 5px 2px rgba(0, 0, 0, 0.1);
🤖 Prompt for AI Agents
In `@community/voice-translation-assistance-frontend/src/App.css` at line 20, The
box-shadow declaration `box-shadow: 5px 2px 5px 2px;` in App.css is missing a
color value; update that declaration to include an explicit color (for example a
hex, rgba()/hsla() with alpha, or a CSS variable like var(--shadow-color)) so
the shadow renders intentionally (e.g., add a color to `box-shadow: 5px 2px 5px
2px <color>`), and ensure any theme variable exists if you reference one.

Comment on lines +21 to +22
recognition.interimResults = false; // final results only
recognition.continuous = false; // stops only when user stops manually
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Misleading comment about continuous behavior.

The comment says "stops only when user stops manually" but continuous = false means recognition stops automatically after the first final result. The comment should be corrected or removed.

Suggested fix
     recognition.interimResults = false; // final results only
-    recognition.continuous = false;     // stops only when user stops manually
+    recognition.continuous = false;     // stops after first result
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
recognition.interimResults = false; // final results only
recognition.continuous = false; // stops only when user stops manually
recognition.interimResults = false; // final results only
recognition.continuous = false; // stops after first result
🤖 Prompt for AI Agents
In
`@community/voice-translation-assistance-frontend/src/speech/useSpeechRecognition.ts`
around lines 21 - 22, The inline comment for recognition.continuous is
incorrect: change or remove the misleading comment next to
recognition.continuous = false in useSpeechRecognition.ts so it accurately
describes behavior (recognition will stop automatically after the first final
result when continuous is false, not "stops only when user stops manually");
update the comment text to reflect that or delete it entirely to avoid
confusion.

Comment on lines +5 to +6
const voices = speechSynthesis.getVoices();
const voice = voices.find((v) => v.lang.startsWith(locale));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

getVoices() may return empty array on first call.

The Web Speech API loads voices asynchronously. Calling getVoices() synchronously often returns an empty array until the voiceschanged event fires. This can cause voice selection to silently fail.

Suggested fix using useEffect to cache voices
+import { useState, useEffect } from "react";
+
 export default function useSpeechSynthesis() {
+  const [voices, setVoices] = useState<SpeechSynthesisVoice[]>([]);
+
+  useEffect(() => {
+    const loadVoices = () => setVoices(speechSynthesis.getVoices());
+    loadVoices();
+    speechSynthesis.addEventListener("voiceschanged", loadVoices);
+    return () => speechSynthesis.removeEventListener("voiceschanged", loadVoices);
+  }, []);
+
   function speak(text: string, locale: string) {
     const msg = new SpeechSynthesisUtterance(text);
-
-    const voices = speechSynthesis.getVoices();
     const voice = voices.find((v) => v.lang.startsWith(locale));
-
     if (voice) msg.voice = voice;
-
     speechSynthesis.speak(msg);
   }
 
   return { speak };
 }
🤖 Prompt for AI Agents
In
`@community/voice-translation-assistance-frontend/src/speech/useSpeechSynthesis.ts`
around lines 5 - 6, getVoices() may return an empty array on first call; update
useSpeechSynthesis to load and cache voices asynchronously by adding a useEffect
that calls speechSynthesis.getVoices(), assigns them to state (e.g., voices),
and also registers a 'voiceschanged' event listener to update that state when
voices load; then compute voice via voices.find((v) =>
v.lang.startsWith(locale)) from the cached state (not a direct synchronous
getVoices() call), and clean up the event listener on unmount.

Comment on lines +23 to +24
let translateTimeout: any = null;
let isTranslating = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Variables reset on every render, breaking debounce and guard logic.

translateTimeout and isTranslating are declared with let inside the component body. They will be re-initialized to null and false on every render, defeating the purpose of debouncing and preventing concurrent calls.

Use useRef to persist these values across renders.

Proposed fix
+import { useState, useRef } from "react";
-import { useState } from "react";
 import useSpeechRecognition from "./speech/useSpeechRecognition";
 import useSpeechSynthesis from "./speech/useSpeechSynthesis";
 ...

 export default function VoiceAssistant() {
   const [translatedText, setTranslatedText] = useState("");
   const [targetLocale, setTargetLocale] = useState("es");
   const [loading, setLoading] = useState(false);

   const { startListening, listening, transcript, stopListening } = useSpeechRecognition();
   const { speak } = useSpeechSynthesis();

-  let translateTimeout: any = null;
-let isTranslating = false;
+  const translateTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
+  const isTranslatingRef = useRef(false);

 async function translate() {
-  if (isTranslating) return;
+  if (isTranslatingRef.current) return;
   if (!transcript) return;

-  clearTimeout(translateTimeout);
+  if (translateTimeoutRef.current) clearTimeout(translateTimeoutRef.current);

-  translateTimeout = setTimeout(async () => {
-    isTranslating = true;
+  translateTimeoutRef.current = setTimeout(async () => {
+    isTranslatingRef.current = true;
     setLoading(true);
     // ... rest of the function
     setLoading(false);
-    isTranslating = false;
+    isTranslatingRef.current = false;
   }, 300);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let translateTimeout: any = null;
let isTranslating = false;
const translateTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const isTranslatingRef = useRef(false);
🤖 Prompt for AI Agents
In `@community/voice-translation-assistance-frontend/src/VoiceAssistant.tsx`
around lines 23 - 24, translateTimeout and isTranslating are declared as local
lets in the VoiceAssistant component so they reset every render, breaking
debounce and concurrency guards; replace them with persistent refs by creating
const translateTimeoutRef = useRef<any>(null) and const isTranslatingRef =
useRef<boolean>(false) inside the component, update all reads/writes to use
translateTimeoutRef.current and isTranslatingRef.current, and clear/assign the
timeout and toggle the translating flag via those refs (and clean up the timeout
in useEffect return) to preserve state across renders.

@17prateek12
Copy link
Author

@17prateek12 looks like something bad happened!

I noticed that there were a few merge conflicts after the recent commits to main, so I pulled the latest changes and resolved all conflicts on my branch. Everything should now be clean, up-to-date, and working as expected

@ashutoshdebug
Copy link
Contributor

@17prateek12 looks like something bad happened!

I noticed that there were a few merge conflicts after the recent commits to main, so I pulled the latest changes and resolved all conflicts on my branch. Everything should now be clean, up-to-date, and working as expected

No I mean there are so many commits from other branches also. I got to know about this as this branch referenced my branch also. Then I got to know that there are about 190+ commits over this branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.