-
Notifications
You must be signed in to change notification settings - Fork 824
Feat/zero config localizer demo #1878
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?
Feat/zero config localizer demo #1878
Conversation
📝 WalkthroughWalkthroughAdded a new zero-config localization demo: a Vite + React app that integrates the lingo.dev compiler, example components, visualizations, docs, and build tooling to demonstrate build-time translation and bundle generation. Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant Vite as Vite Build
participant Compiler as lingo.dev Compiler
participant Parser as JSX Parser
participant Detector as Content Detector
participant FP as Fingerprint Generator
participant API as Translation API
participant Injector as Lookup Injector
participant Bundler as Bundle Builder
Dev->>Vite: start build / dev
Vite->>Compiler: invoke compiler plugin
Compiler->>Parser: parse source (JSX -> AST)
Parser->>Detector: detect translatable nodes
Detector->>FP: generate fingerprints & extracted strings
FP->>API: request translations (per target locale)
API-->>FP: translations response
FP->>Injector: produce lookup code & optimized assets
Injector->>Bundler: emit locale-specific bundles
Bundler->>Dev: built artifacts (optimized language bundles)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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/zero-config-localizer/README.md`:
- Around line 104-110: Update README.md to satisfy markdownlint: add language
specifier "text" to the fenced code blocks for the "Original Text" block and the
"Pseudotranslation" block (both occurrences referenced as the pseudotranslation
and original text code blocks in README.md), replace the bare URL
"https://console.groq.com" with an inline-autolink <https://console.groq.com>,
and remove `.env.example` from the project tree listing under the
zero-config-localizer file tree so the listed files match the repository tree.
In `@community/zero-config-localizer/src/components/CodeInspector.jsx`:
- Around line 89-101: The selector buttons currently toggle visually but lack
ARIA state and a button type; update the JSX for the elements rendered in the
CodeInspector component (the button elements that call setSelectedExample and
read selectedExample) to include type="button" and aria-pressed={selectedExample
=== index} so assistive tech can observe the pressed state and to prevent
accidental form submissions.
In `@community/zero-config-localizer/vite.config.js`:
- Around line 6-21: The build currently forces real translations by calling
lingoCompiler.vite with models set to 'groq:llama-3.3-70b-versatile' and
buildMode: 'translate', which will fail when GROQ_API_KEY is not present; update
the lingoCompiler.vite invocation to detect process.env.GROQ_API_KEY (or read
from dotenv) and, if it's missing, switch to a safe fallback: set buildMode to
'cache-only' (or change models to a non-Groq/pseudotranslator entry) so
translations are not attempted, otherwise keep the Groq model and buildMode
'translate'; target the lingoCompiler.vite call and the models and buildMode
properties when implementing this conditional.
🧹 Nitpick comments (4)
community/zero-config-localizer/src/examples/FormComponent.jsx (1)
18-33: Add basic a11y wiring for the error state.
This improves screen-reader feedback with minimal change.♿️ Suggested update
<input id="email" type="email" placeholder="Enter your email" value={email} onChange={(e) => setEmail(e.target.value)} + aria-invalid={Boolean(error)} + aria-describedby={error ? 'email-error' : undefined} required /> - {error && <span style={{ color: 'red' }}>{error}</span>} + {error && ( + <span id="email-error" role="alert" style={{ color: 'red' }}> + {error} + </span> + )}community/zero-config-localizer/src/examples/DynamicComponent.jsx (1)
1-10: Stabilize the creation date to avoid render-time drift.
new Date()in render will change across re-renders (and after locale updates), which makes the “account created on” value shift. Consider memoizing the date or passing it as a prop so the output stays stable.♻️ Suggested update
-import { useLingoLocale } from 'lingo.dev/react/client'; +import { useMemo } from 'react'; +import { useLingoLocale } from 'lingo.dev/react/client'; export default function DynamicComponent({ userName, messageCount }) { const locale = useLingoLocale(); - const createdOn = new Date().toLocaleDateString(locale ?? undefined); + const createdOn = useMemo(() => new Date(), []); + const createdOnLabel = useMemo( + () => createdOn.toLocaleDateString(locale ?? undefined), + [createdOn, locale] + ); return ( <div> <h2>Hello, {userName}!</h2> <p>You have {messageCount} new messages</p> - <p>Your account was created on {createdOn}</p> + <p>Your account was created on {createdOnLabel}</p> </div> ); }community/zero-config-localizer/src/components/BundleComparison.jsx (1)
5-52: Derive card metrics fromdatato prevent drift.The stat cards (234 KB, 97 KB, 58.5%) are hard-coded while the chart uses
data. If the data changes, the cards can drift. Consider computing the numbers from the same source.♻️ Suggested update
export default function BundleComparison() { const data = [ { name: 'react-i18next', bundle: 145, dictionaries: 89, total: 234 }, @@ total: 97 } ]; + const traditionalTotal = + data.find((d) => d.name === 'react-i18next')?.total ?? data[0]?.total ?? 0; + const lingoTotal = + data.find((d) => d.name === 'Lingo.dev')?.total ?? data[data.length - 1]?.total ?? 0; + const sizeReduction = traditionalTotal + ? ((1 - lingoTotal / traditionalTotal) * 100).toFixed(1) + : '0.0'; return ( <div> @@ <StatCard icon={Package} title="Traditional i18n" - value="234 KB" + value={`${traditionalTotal} KB`} description="Runtime library + translation files" color="#ef4444" /> <StatCard icon={Package} title="Lingo.dev Compiler" - value="97 KB" + value={`${lingoTotal} KB`} description="No runtime overhead" color="#10b981" /> <StatCard icon={TrendingDown} title="Size Reduction" - value="58.5%" + value={`${sizeReduction}%`} description="Smaller bundles, faster loads" color="#667eea" />community/zero-config-localizer/src/main.jsx (1)
7-11: Consider adding a small Suspense fallback while dictionaries load.
Line 9 rendersLingoProviderWrapperwithout afallback, so the app can be blank during initial dictionary fetch. A lightweight fallback improves UX for the demo.♻️ Possible tweak
- <LingoProviderWrapper loadDictionary={(locale) => loadDictionary(locale)}> + <LingoProviderWrapper + loadDictionary={(locale) => loadDictionary(locale)} + fallback={<div style={{ padding: 24, color: '#94a3b8' }}>Loading translations…</div>} + >
| ``` | ||
| Welcome to our platform | ||
| ``` | ||
|
|
||
| **Pseudotranslation:** | ||
| ``` | ||
| [Ŵêƚçôɱê ţô ôûŕ þƚàţƒôŕɱ] |
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.
Fix markdownlint violations and sync the project tree.
Line 104/109/178 need fenced languages (MD040). Line 127 has a bare URL (MD034). Line 185 lists .env.example; if it was removed, the tree should be updated.
✅ Suggested doc fixes
-**Original Text:**
-```
+**Original Text:**
+```text
Welcome to our platform-Pseudotranslation:
- +**Pseudotranslation:** +text
[Ŵêƚçôɱê ţô ôûŕ þƚàţƒôŕɱ]
-1. Visit https://console.groq.com
+1. Visit <https://console.groq.com>
-```
+```text
zero-config-localizer/
├── README.md
├── package.json
├── vite.config.js
├── index.html
├── .gitignore
-├── .env.example
├── src/
│ ├── main.jsx
Also applies to: 127-127, 178-186
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
104-104: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
109-109: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In `@community/zero-config-localizer/README.md` around lines 104 - 110, Update
README.md to satisfy markdownlint: add language specifier "text" to the fenced
code blocks for the "Original Text" block and the "Pseudotranslation" block
(both occurrences referenced as the pseudotranslation and original text code
blocks in README.md), replace the bare URL "https://console.groq.com" with an
inline-autolink <https://console.groq.com>, and remove `.env.example` from the
project tree listing under the zero-config-localizer file tree so the listed
files match the repository tree.
| <button | ||
| key={index} | ||
| onClick={() => setSelectedExample(index)} | ||
| style={{ | ||
| padding: '12px 20px', | ||
| background: selectedExample === index ? '#667eea' : '#1e293b', | ||
| border: `1px solid ${selectedExample === index ? '#667eea' : '#334155'}`, | ||
| borderRadius: 8, | ||
| color: 'white', | ||
| cursor: 'pointer', | ||
| fontSize: 14, | ||
| fontWeight: 500 | ||
| }} |
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.
Expose selection state to assistive tech.
The selector buttons are visually toggled but lack ARIA state. Add aria-pressed (and type="button" to prevent accidental form submits when nested).
🧩 Suggested update
- <button
+ <button
+ type="button"
+ aria-pressed={selectedExample === index}
key={index}
onClick={() => setSelectedExample(index)}
style={{
padding: '12px 20px',
background: selectedExample === index ? '#667eea' : '#1e293b',📝 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.
| <button | |
| key={index} | |
| onClick={() => setSelectedExample(index)} | |
| style={{ | |
| padding: '12px 20px', | |
| background: selectedExample === index ? '#667eea' : '#1e293b', | |
| border: `1px solid ${selectedExample === index ? '#667eea' : '#334155'}`, | |
| borderRadius: 8, | |
| color: 'white', | |
| cursor: 'pointer', | |
| fontSize: 14, | |
| fontWeight: 500 | |
| }} | |
| <button | |
| type="button" | |
| aria-pressed={selectedExample === index} | |
| key={index} | |
| onClick={() => setSelectedExample(index)} | |
| style={{ | |
| padding: '12px 20px', | |
| background: selectedExample === index ? '#667eea' : '#1e293b', | |
| border: `1px solid ${selectedExample === index ? '#667eea' : '#334155'}`, | |
| borderRadius: 8, | |
| color: 'white', | |
| cursor: 'pointer', | |
| fontSize: 14, | |
| fontWeight: 500 | |
| }} |
🤖 Prompt for AI Agents
In `@community/zero-config-localizer/src/components/CodeInspector.jsx` around
lines 89 - 101, The selector buttons currently toggle visually but lack ARIA
state and a button type; update the JSX for the elements rendered in the
CodeInspector component (the button elements that call setSelectedExample and
read selectedExample) to include type="button" and aria-pressed={selectedExample
=== index} so assistive tech can observe the pressed state and to prevent
accidental form submissions.
|
Hi! I’ve addressed all feedback from CodeRabbit and updated the PR accordingly. Noted that remaining workflow approvals require maintainer permissions. |
Summary
This PR adds a zero-config React localizer demo under the
/communitydirectory.The demo showcases how lingo.dev automatically localizes UI text and formatting
at build time without translation keys, runtime libraries, or code changes.
What this demo shows
setLingoLocalet()functionsTesting
npm installandnpm run devVisuals
(Screenshots or demo video can be added if required)
Checklist
/communitySummary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.