-
Notifications
You must be signed in to change notification settings - Fork 818
Add Lingo Live Page Translator Chrome extension #1850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Lingo Live Page Translator Chrome extension #1850
Conversation
|
hi @Rishiraj-Yadav great project! Your PR is missing changeset though. It is required for demo apps as well. Please add the changeset by following instructions here. Make sure you've joined our discord to see this message. If you haven't you need to:
Please also sign your commits |
📝 WalkthroughWalkthroughAdds a new "Lingo Live Page Translator" Chrome extension demo: MV3 manifest, content script, background service worker using Lingo.dev SDK, popup UI (HTML/CSS/JS), Vite build config, package manifest, README, and changeset entries. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Popup as Popup UI
participant Content as Content Script
participant Background as Background Service Worker
participant LingoSDK as Lingo.dev SDK
User->>Popup: select language, click Translate
Popup->>Content: chrome.tabs.sendMessage { action: "translatePage", targetLocale }
Content->>Content: extractTextNodes() & batch texts (≤20)
Content->>Background: chrome.runtime.sendMessage { action: "translateBatch", texts, sourceLocale, targetLocale }
Background->>Background: check cache for each text
Background->>LingoSDK: localizeObject(contentObject, { sourceLocale, targetLocale })
LingoSDK-->>Background: return translated contentObject
Background->>Background: map translations to original indices, update cache
Background-->>Content: return translations array
Content->>Content: apply translations to DOM & store originals
Content-->>Popup: optional completion/status
Popup->>User: show status/progress
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@community/lingo-live-page-translator/public/popup.css`:
- Around line 134-148: The .btn rule currently removes the default focus
indicator (outline: none) which breaks keyboard accessibility; add explicit
focus styles for keyboard users by defining .btn:focus and/or .btn:focus-visible
rules that provide a visible, high-contrast focus indicator (for example a
visible outline or box-shadow ring) while keeping the existing visual design,
and ensure the selector targets keyboard focus (use :focus-visible if available)
so mouse clicks don't always show the ring.
In `@community/lingo-live-page-translator/README.md`:
- Around line 42-80: The README has an unclosed fenced code block (the opening
"```bash" near the top) causing subsequent sections to render as code; close
that initial fence immediately after the npm install line and then fence the
subsequent inline examples properly (wrap "src/background.js" and the code
snippets for const LINGO_API_KEY and the replacement key in appropriate
triple-backtick blocks with language tags, and fence "npm run build" and "dist/"
as bash/text blocks), and optionally add section separators (---) between steps
so steps 2–4 render as normal markdown and the file paths/commands show as
intended.
- Around line 36-37: Update the README line that lists the Lingo.dev API key so
the bare URL is converted to proper Markdown link syntax; replace the plain "Get
it from: https://lingo.dev" text with a Markdown link such as "Get it from:
[https://lingo.dev](https://lingo.dev)" (locate the line with "A Lingo.dev API
key" and the following URL text to make the change).
🧹 Nitpick comments (4)
community/lingo-live-page-translator/public/popup.css (1)
14-17: Duplicate.containerselector with conflicting styles.The
.containerrule appears twice with differentborder-radiusvalues:
- Line 16:
border-radius: 0;- Line 261:
border-radius: 18px;The second declaration wins due to CSS cascade, but this creates confusion. Consider consolidating into a single rule.
♻️ Suggested consolidation
.container { background: white; - border-radius: 0; + border-radius: 18px; + overflow: hidden; + box-shadow: 0 10px 30px rgba(0,0,0,0.18); } - -/* ... later in file ... */ - -.container { - border-radius: 18px; - overflow: hidden; - box-shadow: 0 10px 30px rgba(0,0,0,0.18); -}Also applies to: 260-264
community/lingo-live-page-translator/src/background.js (1)
31-32: Cache key delimiter could cause collisions.The cache key
${texts[i]}__${sourceLocale}__${targetLocale}uses__as a delimiter, which could exist in the original text, potentially causing key collisions.Consider using JSON or a safer delimiter
- const key = `${texts[i]}__${sourceLocale}__${targetLocale}`; + const key = JSON.stringify([texts[i], sourceLocale, targetLocale]);community/lingo-live-page-translator/public/popup.js (1)
80-102: Restore handler doesn't disable buttons during operation.Unlike the translate handler, the restore operation doesn't call
setButtonsDisabled(true)at the start, allowing users to potentially trigger multiple operations simultaneously.Add button disable/enable for restore
restoreBtn.addEventListener("click", async () => { try { + setButtonsDisabled(true); showStatus("Restoring original content...", "info"); showProgress(50, "Restoring..."); const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); chrome.tabs.sendMessage(tab.id, { action: "restoreOriginal" }, (res) => { if (chrome.runtime.lastError) { showStatus("Error: Could not restore. Try refreshing.", "error"); hideProgress(); + setButtonsDisabled(false); return; } showProgress(100, "Restored!"); showStatus("↩️ Original text restored!", "success"); hideProgress(); + setButtonsDisabled(false); }); } catch (err) { showStatus(`❌ ${err.message}`, "error"); hideProgress(); + setButtonsDisabled(false); } });community/lingo-live-page-translator/public/content-script.js (1)
50-55: Source locale is hardcoded to "en".The
sourceLocaleis always"en"regardless of the actual page language. This limits the extension's usefulness on non-English pages.Consider detecting the page language or allowing user selection:
Option: Detect from HTML lang attribute
+function detectSourceLocale() { + const htmlLang = document.documentElement.lang; + return htmlLang?.split('-')[0] || 'en'; +} + async function translatePage(targetLocale) { if (isTranslating) throw new Error("Translation already running"); isTranslating = true; + const sourceLocale = detectSourceLocale(); // ... in the sendMessage call: const res = await chrome.runtime.sendMessage({ action: "translateBatch", texts: batch, - sourceLocale: "en", + sourceLocale, targetLocale });
| .btn { | ||
| flex: 1; | ||
| padding: 12px 16px; | ||
| border: none; | ||
| border-radius: 8px; | ||
| font-size: 14px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| transition: all 0.2s; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 6px; | ||
| outline: none; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding focus styles for keyboard accessibility.
The button has outline: none (line 147) but no :focus or :focus-visible styles are defined. This removes the default focus indicator, making keyboard navigation difficult for users who don't use a mouse.
♿ Suggested fix
.btn-primary:active {
transform: translateY(0);
}
+.btn-primary:focus-visible {
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.4);
+}
+
.btn-primary:disabled {
opacity: 0.6;🤖 Prompt for AI Agents
In `@community/lingo-live-page-translator/public/popup.css` around lines 134 -
148, The .btn rule currently removes the default focus indicator (outline: none)
which breaks keyboard accessibility; add explicit focus styles for keyboard
users by defining .btn:focus and/or .btn:focus-visible rules that provide a
visible, high-contrast focus indicator (for example a visible outline or
box-shadow ring) while keeping the existing visual design, and ensure the
selector targets keyboard focus (use :focus-visible if available) so mouse
clicks don't always show the ring.
| - A Lingo.dev API key | ||
| Get it from: https://lingo.dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use proper markdown link syntax for URL.
The bare URL should be wrapped in markdown link syntax for better rendering and accessibility.
- A Lingo.dev API key
- Get it from: https://lingo.dev
+ Get it from: [https://lingo.dev](https://lingo.dev)📝 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.
| - A Lingo.dev API key | |
| Get it from: https://lingo.dev | |
| - A Lingo.dev API key | |
| Get it from: [https://lingo.dev](https://lingo.dev) |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
37-37: Bare URL used
(MD034, no-bare-urls)
🤖 Prompt for AI Agents
In `@community/lingo-live-page-translator/README.md` around lines 36 - 37, Update
the README line that lists the Lingo.dev API key so the bare URL is converted to
proper Markdown link syntax; replace the plain "Get it from: https://lingo.dev"
text with a Markdown link such as "Get it from:
[https://lingo.dev](https://lingo.dev)" (locate the line with "A Lingo.dev API
key" and the following URL text to make the change).
| ```bash | ||
| npm install | ||
|
|
||
|
|
||
| 🔑 2) Add Your Lingo.dev API Key | ||
|
|
||
| Open: | ||
|
|
||
| src/background.js | ||
|
|
||
|
|
||
| Find: | ||
|
|
||
| const LINGO_API_KEY = "YOUR_LINGO_API_KEY"; | ||
|
|
||
|
|
||
| Replace it with your real key: | ||
|
|
||
| const LINGO_API_KEY = "lingo_xxxxxxxxxxxxxxxxxxxxx"; | ||
|
|
||
|
|
||
|
|
||
| 🏗️ 3) Build the Extension | ||
| npm run build | ||
|
|
||
|
|
||
| After building, a new folder will be created: | ||
|
|
||
| dist/ | ||
|
|
||
|
|
||
| 🧩 4) Load into Chrome | ||
|
|
||
| Open: chrome://extensions | ||
|
|
||
| Enable Developer Mode (top right) | ||
|
|
||
| Click Load unpacked | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclosed code block breaks README formatting.
The code block opened at line 42 (```bash) is never closed. This causes sections 2, 3, and 4 to render as code instead of formatted markdown. The closing ``` is missing after npm install.
📝 Suggested fix
### 📦 1) Install Dependencies
```bash
npm install
+```
+---
🔑 2) Add Your Lingo.dev API Key
Open:
-
-src/background.js
-
+```
+src/background.js
+```
Find:
-
-const LINGO_API_KEY = "YOUR_LINGO_API_KEY";
-
+```js
+const LINGO_API_KEY = "YOUR_LINGO_API_KEY";
+```
Replace it with your real key:
-
-const LINGO_API_KEY = "lingo_xxxxxxxxxxxxxxxxxxxxx";
-
+```js
+const LINGO_API_KEY = "lingo_xxxxxxxxxxxxxxxxxxxxx";
+```
+---
🏗️ 3) Build the Extension
+```bash
npm run build
-
+```
After building, a new folder will be created:
-
-dist/
-
+```
+dist/
+```
+---
+
🧩 4) Load into Chrome
-Open: chrome://extensions
+1. Open: `chrome://extensions`
+2. Enable **Developer Mode** (top right)
+3. Click **Load unpacked**
+4. Select the `dist/` folder🤖 Prompt for AI Agents
In `@community/lingo-live-page-translator/README.md` around lines 42 - 80, The
README has an unclosed fenced code block (the opening "```bash" near the top)
causing subsequent sections to render as code; close that initial fence
immediately after the npm install line and then fence the subsequent inline
examples properly (wrap "src/background.js" and the code snippets for const
LINGO_API_KEY and the replacement key in appropriate triple-backtick blocks with
language tags, and fence "npm run build" and "dist/" as bash/text blocks), and
optionally add section separators (---) between steps so steps 2–4 render as
normal markdown and the file paths/commands show as intended.
|
@sumitsaurabh927 done with changeset and also with sign commits |
Updated README to clarify API key replacement instructions.
Summary
Adds a Chrome Extension demo that translates webpages in-place using the Lingo.dev SDK with batch translation, caching, and restore functionality.
Changes
Implemented in-page translation workflow using LingoDotDevEngine (localizeObject) from Lingo.dev SDK
Added Chrome MV3 extension architecture (popup UI + content script + background service worker)
Added batch translation support for faster translation on large pages
Added restore feature to revert translated text back to original without page reload
Added improved modern popup UI with status + progress feedback
Included README with setup and local run instructions
Testing
Business logic tests added:
Visuals
Required for UI/UX changes:
Before :

After
Checklist
Closes #1761
Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.