Skip to content

Conversation

@IRjSI
Copy link

@IRjSI IRjSI commented Jan 23, 2026

Summary

This PR adds a community demo showcasing the usage of the lingo.dev SDK with a minimal Next.js application.

The app demonstrates:

  • Automatic language detection
  • Server-side translation using the lingo.dev SDK
  • Proper server/client separation using Next.js Server Actions

Checklist

  • README.md added inside the project folder
  • PR targets main
  • Community submission label added

Summary by CodeRabbit

  • New Features

    • Demo app added with automatic language detection, translation, multi-language notes, and built-in search.
  • Documentation

    • Added a comprehensive README with setup and usage instructions for the demo.
  • Style

    • Added global styling with dark mode support and Tailwind integration.
  • Chores

    • Added lingo.dev dependency and a changeset documenting upcoming package patch bumps.

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

@sumitsaurabh927
Copy link
Contributor

hi your PR is missing changeset. 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:

  1. Join our discord here
  2. Go through the instructions to add changeset and add it to your PR

Please also sign your commits. Only one of your commits is verified.

@coderabbitai
Copy link

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

Adds a new Next.js demo app under community/auto-localized-notes/ implementing server-side language detection and translation via the lingo.dev SDK, plus project configuration and a repository changeset documenting multiple package patch bumps.

Changes

Cohort / File(s) Summary
Changeset & Root deps
.changeset/fair-shirts-work.md, package.json
Adds a changeset documenting patch bumps across many packages and adds lingo.dev@^0.122.1 to the root package.json.
New Next.js app scaffold
community/auto-localized-notes/package.json, community/auto-localized-notes/tsconfig.json, community/auto-localized-notes/next.config.ts, community/auto-localized-notes/postcss.config.mjs, community/auto-localized-notes/eslint.config.mjs
New project config files: Next.js/React versions, TypeScript strict config and path alias, PostCSS/Tailwind setup, and ESLint composition for Next.js.
Gitignore & README
community/auto-localized-notes/.gitignore, community/auto-localized-notes/README.md
Adds standard Node/Next.js ignores and a comprehensive README detailing SDK usage, env vars, and local run instructions.
App layout & styles
community/auto-localized-notes/app/layout.tsx, community/auto-localized-notes/app/globals.css
Adds RootLayout with Geist fonts and metadata, plus global Tailwind CSS with CSS variables and dark-mode support.
Server translation actions
community/auto-localized-notes/app/actions/translate.ts
New server-side module exporting translateText(text, fromLang, toLang) and recognizeText(text) that instantiate LingoDotDevEngine and call localizeText / recognizeLocale with error handling.
Client UI
community/auto-localized-notes/app/page.tsx
New client page component managing input, language selection, notes list, search, and uses server actions to detect language and translate text; renders original and translated notes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client as "Client (page.tsx)"
  participant Server as "Next.js Server Action\n(actions/translate.ts)"
  participant Lingo as "lingo.dev SDK / API"

  Client->>Server: recognizeText(text)
  Server->>Lingo: recognizeLocale(text)
  Lingo-->>Server: detectedLocale
  Server-->>Client: detectedLocale

  Client->>Server: translateText(text, from, to)
  Server->>Lingo: localizeText({ sourceLocale: from, targetLocale: to, text })
  Lingo-->>Server: translatedText
  Server-->>Client: translatedText

  Client->>Client: prepend note(original, translated, detectedLang)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I hopped through code and found some words to share,
I listened, I translated, I nibbled here and there,
Notes now speak many tongues with hardly any care,
A tiny rabbit cheers — translations in the air!

🚥 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 description provides a summary and key features but is incomplete. It lacks detailed sections for Testing, Visuals, and a proper Checklist with test coverage validation and breaking change assessment. Complete the missing sections: add Business logic tests and verify all tests pass, include Before/after screenshots or video demo if applicable, and expand the Checklist to confirm no breaking changes and test coverage beyond happy path.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a demo Next.js application to the community folder that showcases the lingo.dev SDK.

✏️ 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: 4

🤖 Fix all issues with AI agents
In `@community/auto-localized-notes/app/globals.css`:
- Around line 22-26: The body CSS currently hardcodes "Arial, Helvetica,
sans-serif" so the declared Geist font variables are ignored; update the body
selector's font-family to use the declared CSS variable (e.g., replace
font-family: Arial, Helvetica, sans-serif; with font-family: var(--font-sans,
Arial, Helvetica, sans-serif);) so the Geist font variable is applied while
keeping a fallback.

In `@community/auto-localized-notes/app/page.tsx`:
- Around line 147-152: The Translated label is using the current dropdown state
`{lang}` instead of the note's actual target language; update the Note type (or
whatever model holds notes) to include a targetLang field, set that field when
creating a note in handleSubmit (use the selected lang value at submit time),
and change the JSX to render the stored target language (e.g., use
note.targetLang instead of lang) so existing notes keep their original
translation language regardless of later dropdown changes.
- Around line 27-46: The handleSubmit function lacks error handling for the
async server actions recognizeText and translateText, so failures are swallowed
and users get no feedback; wrap the startTransition callback in a try/catch (or
place try/catch inside the async callback) to catch errors from
recognizeText/translateText, set an error state (e.g., setError or a local error
flag) and avoid mutating state on failure, and optionally call setText("") only
on success; update UI to render the error state. Reference handleSubmit,
recognizeText, translateText, setNotes, and setText when making the changes.

In `@community/auto-localized-notes/package.json`:
- Around line 11-15: The package.json is missing the lingo.dev SDK that
app/actions/translate.ts imports; add "lingo.dev" to the "dependencies" object
in package.json (using the appropriate SDK version your demo expects) and
reinstall deps so the demo is self-contained and builds correctly; update
package.json's "dependencies" to include "lingo.dev" and run npm/yarn install to
pick up the new dependency.
🧹 Nitpick comments (3)
community/auto-localized-notes/README.md (1)

55-77: Add language specifiers to fenced code blocks.

The shell command blocks are missing language identifiers, which affects syntax highlighting and accessibility.

Suggested fix
-```
+```bash
 git clone <repo-url>
 cd auto-localized-notes

```diff
-```
+```bash
 npm install
 # or
 pnpm install

```diff
-```
+```bash
 npm run dev

```diff
-```
+```text
 http://localhost:3000
</details>

</blockquote></details>
<details>
<summary>community/auto-localized-notes/app/layout.tsx (1)</summary><blockquote>

`26-28`: **Consider setting `<html lang>` from the detected locale.**  
If the page renders non‑English content, hardcoding `lang="en"` can confuse screen readers and SEO. You could derive it from `Accept-Language` or your detected locale and pass it into the layout.

</blockquote></details>
<details>
<summary>community/auto-localized-notes/app/page.tsx (1)</summary><blockquote>

`23-25`: **Avoid `any` type for event handlers.**

Use the proper React event type for better type safety.


<details>
<summary>✨ Suggested improvement</summary>

```diff
-  const handleChange = (e: any) => {
+  const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
     setLang(e.target.value);
   };

Comment on lines +22 to +26
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
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

Use the declared font variables instead of hardcoded Arial.
Right now the Geist font variables are set but never used, so the app renders with Arial/Helvetica. Switching to the variable makes the font import effective.

♻️ Suggested change
 body {
   background: var(--background);
   color: var(--foreground);
-  font-family: Arial, Helvetica, sans-serif;
+  font-family: var(--font-sans, Arial, Helvetica, sans-serif);
 }
🤖 Prompt for AI Agents
In `@community/auto-localized-notes/app/globals.css` around lines 22 - 26, The
body CSS currently hardcodes "Arial, Helvetica, sans-serif" so the declared
Geist font variables are ignored; update the body selector's font-family to use
the declared CSS variable (e.g., replace font-family: Arial, Helvetica,
sans-serif; with font-family: var(--font-sans, Arial, Helvetica, sans-serif);)
so the Geist font variable is applied while keeping a fallback.

Comment on lines +27 to +46
const handleSubmit = () => {
if (!text.trim()) return;

startTransition(async () => {
const detectedLang = await recognizeText(text);
const result = await translateText(text, detectedLang, lang);

setNotes((prev) => [
{
id: crypto.randomUUID(),
original: text,
translated: result,
detectedLang: detectedLang,
},
...prev,
]);

setText("");
});
};
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 error handling for server action calls.

If recognizeText or translateText fails (e.g., network error, service unavailable), the error will be silently ignored and the user receives no feedback. Consider wrapping in try/catch and displaying an error state.

🛡️ Suggested fix with error handling
+  const [error, setError] = useState<string | null>(null);
+
   const handleSubmit = () => {
     if (!text.trim()) return;
+    setError(null);
 
     startTransition(async () => {
-      const detectedLang = await recognizeText(text);
-      const result = await translateText(text, detectedLang, lang);
-
-      setNotes((prev) => [
-        {
-          id: crypto.randomUUID(),
-          original: text,
-          translated: result,
-          detectedLang: detectedLang,
-        },
-        ...prev,
-      ]);
-
-      setText("");
+      try {
+        const detectedLang = await recognizeText(text);
+        const result = await translateText(text, detectedLang, lang);
+
+        setNotes((prev) => [
+          {
+            id: crypto.randomUUID(),
+            original: text,
+            translated: result,
+            detectedLang: detectedLang,
+          },
+          ...prev,
+        ]);
+
+        setText("");
+      } catch (err) {
+        setError("Translation failed. Please try again.");
+      }
     });
   };
🤖 Prompt for AI Agents
In `@community/auto-localized-notes/app/page.tsx` around lines 27 - 46, The
handleSubmit function lacks error handling for the async server actions
recognizeText and translateText, so failures are swallowed and users get no
feedback; wrap the startTransition callback in a try/catch (or place try/catch
inside the async callback) to catch errors from recognizeText/translateText, set
an error state (e.g., setError or a local error flag) and avoid mutating state
on failure, and optionally call setText("") only on success; update UI to render
the error state. Reference handleSubmit, recognizeText, translateText, setNotes,
and setText when making the changes.

Comment on lines +147 to +152
<div className="space-y-1">
<p className="text-xs font-semibold text-gray-500 dark:text-gray-400">
Translated ({lang})
</p>
<p className="text-sm whitespace-pre-wrap">{note.translated}</p>
</div>
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

Bug: Translated language label shows current selection, not the actual target language.

Line 149 displays {lang} which is the currently selected language in the dropdown, not the language the note was actually translated to. If a user creates a note translated to French, then changes the dropdown to Spanish, the existing note will incorrectly show "Translated (es)" even though the text is in French.

🐛 Suggested fix: store target language per note

Update the Note type to include targetLang:

 type Note = {
   id: string;
   original: string;
   translated: string;
   detectedLang: string;
+  targetLang: string;
 };

Store it when creating the note in handleSubmit:

       setNotes((prev) => [
         {
           id: crypto.randomUUID(),
           original: text,
           translated: result,
           detectedLang: detectedLang,
+          targetLang: lang,
         },
         ...prev,
       ]);

Display the stored value in the JSX:

               <p className="text-xs font-semibold text-gray-500 dark:text-gray-400">
-                Translated ({lang})
+                Translated ({note.targetLang})
               </p>
🤖 Prompt for AI Agents
In `@community/auto-localized-notes/app/page.tsx` around lines 147 - 152, The
Translated label is using the current dropdown state `{lang}` instead of the
note's actual target language; update the Note type (or whatever model holds
notes) to include a targetLang field, set that field when creating a note in
handleSubmit (use the selected lang value at submit time), and change the JSX to
render the stored target language (e.g., use note.targetLang instead of lang) so
existing notes keep their original translation language regardless of later
dropdown changes.

Comment on lines +11 to +15
"dependencies": {
"next": "16.1.4",
"react": "19.2.3",
"react-dom": "19.2.3"
},
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

Missing lingo.dev dependency.

The demo uses lingo.dev SDK in app/actions/translate.ts but doesn't declare it as a dependency. Add it to ensure the demo is self-contained:

Suggested fix
   "dependencies": {
     "next": "16.1.4",
     "react": "19.2.3",
-    "react-dom": "19.2.3"
+    "react-dom": "19.2.3",
+    "lingo.dev": "^0.122.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
"dependencies": {
"next": "16.1.4",
"react": "19.2.3",
"react-dom": "19.2.3"
},
"dependencies": {
"next": "16.1.4",
"react": "19.2.3",
"react-dom": "19.2.3",
"lingo.dev": "^0.122.1"
},
🤖 Prompt for AI Agents
In `@community/auto-localized-notes/package.json` around lines 11 - 15, The
package.json is missing the lingo.dev SDK that app/actions/translate.ts imports;
add "lingo.dev" to the "dependencies" object in package.json (using the
appropriate SDK version your demo expects) and reinstall deps so the demo is
self-contained and builds correctly; update package.json's "dependencies" to
include "lingo.dev" and run npm/yarn install to pick up the new dependency.

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: 2

🤖 Fix all issues with AI agents
In `@community/auto-localized-notes/app/actions/translate.ts`:
- Around line 9-35: Both translateText and recognizeText currently return
sentinel error strings ("error translating the text"/"error detecting the
language") which can collide with valid outputs; change their error handling to
return null (or a structured error object) instead of strings and preserve
logging. Specifically, in translateText and recognizeText catch blocks
(functions named translateText and recognizeText) replace the string returns
with return null (or an Error-style result) and keep console.error(error) so
callers can detect failures explicitly and handle null results appropriately.
- Around line 5-7: Check for process.env.LINGODOTDEV_API_KEY and throw a clear
error before initializing LingoDotDevEngine to fail fast; if the env var is
missing, log/throw a descriptive message like "Missing LINGODOTDEV_API_KEY" and
abort initialization so you don't create lingoDotDev with undefined. Update the
initialization site where new LingoDotDevEngine({ apiKey:
process.env.LINGODOTDEV_API_KEY }) is called to validate the env var, then
create lingoDotDev only after the check passes.

Comment on lines +5 to +7
const lingoDotDev = new LingoDotDevEngine({
apiKey: process.env.LINGODOTDEV_API_KEY,
});
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

🧩 Analysis chain

🌐 Web query:

LingoDotDevEngine apiKey requirement undefined behavior

💡 Result:

LingoDotDevEngine requires an apiKey in its constructor config (it’s documented as “Required” / “The SDK requires an API key”). If you pass apiKey: undefined (or omit it), that’s not a supported/defined configuration—the SDK will still attempt to call the Lingo.dev Engine, but requests will fail authentication because there’s no valid key to send. Use a real key (commonly via process.env.LINGODOTDEV_API_KEY) and consider adding your own upfront validation to throw a clear error when it’s missing. [1], [2]

Sources:
[1] https://docs.lingo.dev/setup/sdk
[2] https://lingo.dev/en/sdk/javascript


🏁 Script executed:

find . -type f -name "translate.ts" | head -20

Repository: lingodotdev/lingo.dev

Length of output: 122


🏁 Script executed:

cat -n community/auto-localized-notes/app/actions/translate.ts

Repository: lingodotdev/lingo.dev

Length of output: 1063


Fail fast if LINGODOTDEV_API_KEY is missing.

The LingoDotDevEngine requires a valid API key (documented as required by Lingo.dev SDK). Passing undefined is not a supported configuration—the SDK will initialize but requests will fail at runtime with authentication errors, making misconfiguration hard to diagnose. Add an explicit guard with a clear error before SDK initialization.

✅ Suggested change
-const lingoDotDev = new LingoDotDevEngine({
-  apiKey: process.env.LINGODOTDEV_API_KEY,
-});
+const apiKey = process.env.LINGODOTDEV_API_KEY;
+if (!apiKey) {
+  throw new Error("Missing LINGODOTDEV_API_KEY");
+}
+const lingoDotDev = new LingoDotDevEngine({
+  apiKey,
+});
📝 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
const lingoDotDev = new LingoDotDevEngine({
apiKey: process.env.LINGODOTDEV_API_KEY,
});
const apiKey = process.env.LINGODOTDEV_API_KEY;
if (!apiKey) {
throw new Error("Missing LINGODOTDEV_API_KEY");
}
const lingoDotDev = new LingoDotDevEngine({
apiKey,
});
🤖 Prompt for AI Agents
In `@community/auto-localized-notes/app/actions/translate.ts` around lines 5 - 7,
Check for process.env.LINGODOTDEV_API_KEY and throw a clear error before
initializing LingoDotDevEngine to fail fast; if the env var is missing,
log/throw a descriptive message like "Missing LINGODOTDEV_API_KEY" and abort
initialization so you don't create lingoDotDev with undefined. Update the
initialization site where new LingoDotDevEngine({ apiKey:
process.env.LINGODOTDEV_API_KEY }) is called to validate the env var, then
create lingoDotDev only after the check passes.

Comment on lines +9 to +35
export async function translateText(
text: string,
fromLang: string,
toLang: string,
) {
try {
const result = await lingoDotDev.localizeText(text, {
sourceLocale: fromLang,
targetLocale: toLang,
});

return result;
} catch (error) {
console.error(error);
return "error translating the text";
}
}

export async function recognizeText(text: string) {
try {
const detectedLang = await lingoDotDev.recognizeLocale(text);

return detectedLang;
} catch (error) {
console.error(error);
return "error detecting the language";
}
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

Avoid returning sentinel error strings.

Returning "error …" makes failures indistinguishable from valid translations/locales. Prefer null (or a structured result) so callers can handle errors explicitly.

✅ Suggested change
-export async function translateText(
+export async function translateText(
   text: string,
   fromLang: string,
   toLang: string,
-) {
+): Promise<string | null> {
   try {
     const result = await lingoDotDev.localizeText(text, {
       sourceLocale: fromLang,
       targetLocale: toLang,
     });

     return result;
   } catch (error) {
     console.error(error);
-    return "error translating the text";
+    return null;
   }
 }

-export async function recognizeText(text: string) {
+export async function recognizeText(text: string): Promise<string | null> {
   try {
     const detectedLang = await lingoDotDev.recognizeLocale(text);

     return detectedLang;
   } catch (error) {
     console.error(error);
-    return "error detecting the language";
+    return null;
   }
 }
🤖 Prompt for AI Agents
In `@community/auto-localized-notes/app/actions/translate.ts` around lines 9 - 35,
Both translateText and recognizeText currently return sentinel error strings
("error translating the text"/"error detecting the language") which can collide
with valid outputs; change their error handling to return null (or a structured
error object) instead of strings and preserve logging. Specifically, in
translateText and recognizeText catch blocks (functions named translateText and
recognizeText) replace the string returns with return null (or an Error-style
result) and keep console.error(error) so callers can detect failures explicitly
and handle null results appropriately.

@github-actions
Copy link
Contributor

Hey @IRjSI! Just checking in - are you still working on this PR? We noticed there are some comments that may need addressing. If you need more time, no problem! Just let us know. If we don't hear back within a week, we'll close this to keep the repo tidy, but you can always reopen when ready.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants