feat: Multi-Language README Support#92
Conversation
|
Someone is attempting to deploy a commit to the naheel0's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAPI request parsing for Changes
Sequence Diagram(s)(omitted — changes are small control flow tweaks between frontend and API, not a new multi-component flow requiring visualization) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 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🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/components/Generator/SearchInput.tsx (1)
24-36: Consider moving language options to a shared constant used by both UI and API.Keeping this list local increases drift risk versus server validation/rules. A shared source of truth keeps behavior consistent.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Generator/SearchInput.tsx` around lines 24 - 36, The local languages array in SearchInput.tsx (variable languages) should be extracted into a shared exported constant (e.g., ALLOWED_LANGUAGES) in a common module and then imported into SearchInput.tsx; update the UI to use the imported constant instead of the local array. Also import the same shared constant into the server-side code that validates or enforces language choices (replace any local lists or hardcoded checks in your API validation/handler with the shared constant) so UI and API use a single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/api/generate/route.ts`:
- Around line 13-17: The code reads body.language into the local variable
language and later interpolates it into the model prompt; to prevent prompt
manipulation validate and allowlist this value immediately after parsing
req.json(): accept only known languages (e.g., ["English","Spanish",...]) by
normalizing case/whitespace and mapping aliases, otherwise set language =
"English" or return a 400 error; update the assignment site where language is
set from body.language and ensure the same validated language variable is the
one used when building the prompt (replace any direct use of body.language with
the validated language).
In `@src/components/Generator/SearchInput.tsx`:
- Around line 75-85: The language <select> in the SearchInput component lacks an
accessible label; add one by giving the <select> an id (e.g., "language-select")
and either render a corresponding <label
htmlFor="language-select">Language</label> (use your existing "sr-only" or
visually-hidden utility class to keep it visually hidden) or add an
aria-label/aria-labelledby on the <select>; ensure this change ties to the
existing language, setLanguage and languages usage so screen readers announce
the control properly.
---
Nitpick comments:
In `@src/components/Generator/SearchInput.tsx`:
- Around line 24-36: The local languages array in SearchInput.tsx (variable
languages) should be extracted into a shared exported constant (e.g.,
ALLOWED_LANGUAGES) in a common module and then imported into SearchInput.tsx;
update the UI to use the imported constant instead of the local array. Also
import the same shared constant into the server-side code that validates or
enforces language choices (replace any local lists or hardcoded checks in your
API validation/handler with the shared constant) so UI and API use a single
source of truth.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 4bd9e537-8a8d-4136-b069-4236b7b80b57
📒 Files selected for processing (3)
src/app/api/generate/route.tssrc/app/generate/GeneratePageClient.tsxsrc/components/Generator/SearchInput.tsx
| let language: string; | ||
| try { | ||
| const body = await req.json(); | ||
| rawUrl = body.url; | ||
| language = body.language || "English"; |
There was a problem hiding this comment.
Validate and allowlist language on the API before using it in the prompt.
Line 17 accepts arbitrary body.language, and Line 101 injects it directly into the model prompt. This can be bypassed via direct API calls (ignoring UI dropdown restrictions) and used to manipulate prompt behavior.
🔧 Proposed fix
+const SUPPORTED_LANGUAGES = new Set([
+ "English",
+ "Spanish",
+ "French",
+ "German",
+ "Chinese",
+ "Japanese",
+ "Korean",
+ "Portuguese",
+ "Russian",
+ "Arabic",
+ "Turkish",
+]);
export async function POST(req: Request) {
let rawUrl: string;
let language: string;
try {
const body = await req.json();
- rawUrl = body.url;
- language = body.language || "English";
+ if (typeof body?.url !== "string") {
+ return NextResponse.json({ error: "GitHub URL is required" }, { status: 400 });
+ }
+
+ const requestedLanguage =
+ typeof body?.language === "string" ? body.language.trim() : "English";
+
+ if (!SUPPORTED_LANGUAGES.has(requestedLanguage)) {
+ return NextResponse.json({ error: "Unsupported language" }, { status: 400 });
+ }
+
+ rawUrl = body.url;
+ language = requestedLanguage;
} catch {
return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 });
}Also applies to: 99-102
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/api/generate/route.ts` around lines 13 - 17, The code reads
body.language into the local variable language and later interpolates it into
the model prompt; to prevent prompt manipulation validate and allowlist this
value immediately after parsing req.json(): accept only known languages (e.g.,
["English","Spanish",...]) by normalizing case/whitespace and mapping aliases,
otherwise set language = "English" or return a 400 error; update the assignment
site where language is set from body.language and ensure the same validated
language variable is the one used when building the prompt (replace any direct
use of body.language with the validated language).
| <select | ||
| value={language} | ||
| onChange={(e) => setLanguage(e.target.value)} | ||
| className="bg-zinc-900/50 border border-white/10 rounded-2xl px-6 py-6 text-white focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all backdrop-blur-xl appearance-none cursor-pointer min-w-[140px]" | ||
| > | ||
| {languages.map((lang) => ( | ||
| <option key={lang} value={lang} className="bg-zinc-900 text-white"> | ||
| {lang} | ||
| </option> | ||
| ))} | ||
| </select> |
There was a problem hiding this comment.
Add an accessible label for the language selector.
Line 75 renders a <select> without a label. Screen readers will announce it generically, which hurts usability.
♿ Proposed fix
- <select
+ <select
value={language}
onChange={(e) => setLanguage(e.target.value)}
+ aria-label="Select README language"
className="bg-zinc-900/50 border border-white/10 rounded-2xl px-6 py-6 text-white focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all backdrop-blur-xl appearance-none cursor-pointer min-w-[140px]"
>📝 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.
| <select | |
| value={language} | |
| onChange={(e) => setLanguage(e.target.value)} | |
| className="bg-zinc-900/50 border border-white/10 rounded-2xl px-6 py-6 text-white focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all backdrop-blur-xl appearance-none cursor-pointer min-w-[140px]" | |
| > | |
| {languages.map((lang) => ( | |
| <option key={lang} value={lang} className="bg-zinc-900 text-white"> | |
| {lang} | |
| </option> | |
| ))} | |
| </select> | |
| <select | |
| value={language} | |
| onChange={(e) => setLanguage(e.target.value)} | |
| aria-label="Select README language" | |
| className="bg-zinc-900/50 border border-white/10 rounded-2xl px-6 py-6 text-white focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all backdrop-blur-xl appearance-none cursor-pointer min-w-[140px]" | |
| > | |
| {languages.map((lang) => ( | |
| <option key={lang} value={lang} className="bg-zinc-900 text-white"> | |
| {lang} | |
| </option> | |
| ))} | |
| </select> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/Generator/SearchInput.tsx` around lines 75 - 85, The language
<select> in the SearchInput component lacks an accessible label; add one by
giving the <select> an id (e.g., "language-select") and either render a
corresponding <label htmlFor="language-select">Language</label> (use your
existing "sr-only" or visually-hidden utility class to keep it visually hidden)
or add an aria-label/aria-labelledby on the <select>; ensure this change ties to
the existing language, setLanguage and languages usage so screen readers
announce the control properly.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/app/api/generate/route.ts (1)
16-20:⚠️ Potential issue | 🟠 MajorValidate and allowlist
languagebefore using it in the prompt.Line 20 trusts
body.languagedirectly; that value is later interpolated into the model prompt (Line 104). This is still an input-validation gap and a prompt-manipulation surface.Suggested fix
+const SUPPORTED_LANGUAGES = new Set([ + "English", + "Spanish", + "French", + "German", + "Chinese", + "Japanese", + "Korean", + "Portuguese", + "Russian", + "Arabic", + "Turkish", +]); export async function POST(req: Request) { let rawUrl: string; let language: string; try { const body = await req.json(); - rawUrl = body.url; - language = body.language || "English"; + if (typeof body?.url !== "string") { + return NextResponse.json({ error: "GitHub URL is required" }, { status: 400 }); + } + + const requestedLanguage = + typeof body?.language === "string" ? body.language.trim() : "English"; + + if (!SUPPORTED_LANGUAGES.has(requestedLanguage)) { + return NextResponse.json({ error: "Unsupported language" }, { status: 400 }); + } + + rawUrl = body.url; + language = requestedLanguage; } catch { return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/api/generate/route.ts` around lines 16 - 20, The handler currently trusts body.language directly when setting the language variable which later gets interpolated into the model prompt (variable language, assignment from body.language after await req.json()); instead implement an allowlist of supported languages (e.g., ["English","Spanish",...]) and map/normalize body.language (trim, case-normalize) to a canonical value, default to "English" if missing/invalid, and reject or return a 400 when an explicitly unsupported value is supplied; update the code where language is assigned and where the prompt is constructed to use the validated/canonical language variable only (do not interpolate raw body.language).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/api/generate/route.ts`:
- Line 11: The JSDoc for the API handler in src/app/api/generate/route.ts
incorrectly labels the incoming parameter as a "Fastify request object"; update
the comment for the handler (the exported route handler function) to reference
the standard/Next.js Request (or "Web Request") instead and adjust the `@param`
type/description to say it is a standard Request object carrying the repo URL
and optional language so tooling and maintainers are accurate.
---
Duplicate comments:
In `@src/app/api/generate/route.ts`:
- Around line 16-20: The handler currently trusts body.language directly when
setting the language variable which later gets interpolated into the model
prompt (variable language, assignment from body.language after await
req.json()); instead implement an allowlist of supported languages (e.g.,
["English","Spanish",...]) and map/normalize body.language (trim,
case-normalize) to a canonical value, default to "English" if missing/invalid,
and reject or return a 400 when an explicitly unsupported value is supplied;
update the code where language is assigned and where the prompt is constructed
to use the validated/canonical language variable only (do not interpolate raw
body.language).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 55636891-f9b0-4f39-8038-6faf77ab64f4
📒 Files selected for processing (2)
src/app/api/generate/route.tssrc/components/Generator/SearchInput.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/Generator/SearchInput.tsx
| * Optimized for data accuracy and clean prompt interpolation. | ||
| * Optimized for data accuracy, clean prompt interpolation, and multi-language support. | ||
| * | ||
| * @param {Request} req - The incoming Fastify request object containing the repo URL and optional language. |
There was a problem hiding this comment.
Fix incorrect framework reference in JSDoc.
Line 11 says “Fastify request object”, but this handler receives a standard/Next.js Request. This can mislead maintainers and tooling.
Suggested doc fix
- * `@param` {Request} req - The incoming Fastify request object containing the repo URL and optional language.
+ * `@param` {Request} req - The incoming Next.js request object containing the repo URL and optional language.📝 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.
| * @param {Request} req - The incoming Fastify request object containing the repo URL and optional language. | |
| * `@param` {Request} req - The incoming Next.js request object containing the repo URL and optional language. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/api/generate/route.ts` at line 11, The JSDoc for the API handler in
src/app/api/generate/route.ts incorrectly labels the incoming parameter as a
"Fastify request object"; update the comment for the handler (the exported route
handler function) to reference the standard/Next.js Request (or "Web Request")
instead and adjust the `@param` type/description to say it is a standard Request
object carrying the repo URL and optional language so tooling and maintainers
are accurate.
|
@copilot In Verify each finding against the current code and only fix it if needed. In |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/Generator/SearchInput.tsx (1)
5-5: 🛠️ Refactor suggestion | 🟠 MajorRemove unused import and use the existing constant instead of duplicating.
SUPPORTED_LANGUAGESis imported on line 5 but never used. Instead, an identical locallanguagesarray is defined (lines 32-44). This duplicates the constant from@/constants/languages.tsand will cause maintenance drift if languages are added or removed in only one place.♻️ Proposed fix
Remove the local array and use the imported constant:
- const languages = [ - "English", - "Spanish", - "French", - "German", - "Chinese", - "Japanese", - "Korean", - "Portuguese", - "Russian", - "Arabic", - "Turkish", - ]; - const handleSubmit = (e: React.FormEvent) => {Then update line 91 to use the imported constant:
- {languages.map((lang) => ( + {SUPPORTED_LANGUAGES.map((lang) => (Also applies to: 32-44
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Generator/SearchInput.tsx` at line 5, Remove the duplicated local languages array and use the imported SUPPORTED_LANGUAGES constant instead: delete the local "languages" array defined in the component and replace any references to that local variable (e.g., the usage in the SearchInput component where the local array is referenced — previously around the usage at line ~91) with SUPPORTED_LANGUAGES; ensure any type annotations or props expecting the local array still accept SUPPORTED_LANGUAGES (adjust imports/typing if necessary) so the component relies on the single source of truth.
🧹 Nitpick comments (1)
src/app/api/generate/route.ts (1)
4-4: Remove unused import.
SUPPORTED_LANGUAGESis imported but never used in this file. The validation logic that previously used it appears to have been removed.♻️ Proposed fix
Either remove the unused import:
-import { SUPPORTED_LANGUAGES } from "@/constants/languages";Or preferably, keep the import and add validation (see related comment on line 21).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/api/generate/route.ts` at line 4, The import SUPPORTED_LANGUAGES in route.ts is unused; either remove the import statement referencing SUPPORTED_LANGUAGES or restore the language validation that uses it (e.g., re-add validation that checks the incoming request's language against SUPPORTED_LANGUAGES inside the generate handler/function), ensuring the symbol SUPPORTED_LANGUAGES is referenced if kept so the linter no longer flags it as unused.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/components/Generator/SearchInput.tsx`:
- Line 5: Remove the duplicated local languages array and use the imported
SUPPORTED_LANGUAGES constant instead: delete the local "languages" array defined
in the component and replace any references to that local variable (e.g., the
usage in the SearchInput component where the local array is referenced —
previously around the usage at line ~91) with SUPPORTED_LANGUAGES; ensure any
type annotations or props expecting the local array still accept
SUPPORTED_LANGUAGES (adjust imports/typing if necessary) so the component relies
on the single source of truth.
---
Nitpick comments:
In `@src/app/api/generate/route.ts`:
- Line 4: The import SUPPORTED_LANGUAGES in route.ts is unused; either remove
the import statement referencing SUPPORTED_LANGUAGES or restore the language
validation that uses it (e.g., re-add validation that checks the incoming
request's language against SUPPORTED_LANGUAGES inside the generate
handler/function), ensuring the symbol SUPPORTED_LANGUAGES is referenced if kept
so the linter no longer flags it as unused.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 14748954-c7d5-46c3-8847-89a3697dee2d
📒 Files selected for processing (2)
src/app/api/generate/route.tssrc/components/Generator/SearchInput.tsx
not working fix it
@cyphercodes
@jaseel0
|
|
@naheel0 Fixed. Typo in the asset name and README ref. Renamed it to feature-page.png and updated the doc. Should work now. |
|
Hi @cyphercodes, Thanks for the updates! Just a heads-up — we’ve hit the free-tier API rate limit, so some README generations may fail until the quota resets. |
…UAGES PR #92 introduced a security vulnerability by replacing the language allowlist validation with `language = body.language || "English"`, which allows arbitrary values to be injected into the AI prompt. Restore the proper validation: - Check that body.language is a string - Normalize to title case - Validate against SUPPORTED_LANGUAGES allowlist - Fall back to "English" if not in the list This also includes the other improvements from PR #92 (markdown cleanup, gemini model update, UI language list). Co-authored-by: jaseel0 <225665919+jaseel0@users.noreply.github.com> Agent-Logs-Url: https://github.com/BeyteFlow/ReadmeGenAI/sessions/486edd1a-2457-4589-b5e2-b61f6dfde55f
- Restore the aria-label attribute on the language select element (removed in PR #92, reducing accessibility) - Replace the duplicate inline languages array with SUPPORTED_LANGUAGES from constants (single source of truth) Co-authored-by: jaseel0 <225665919+jaseel0@users.noreply.github.com> Agent-Logs-Url: https://github.com/BeyteFlow/ReadmeGenAI/sessions/486edd1a-2457-4589-b5e2-b61f6dfde55f
The PR #92 incorrectly changed the JSDoc to say "Fastify request object". This is a Next.js API route that uses the standard Web Request API. Co-authored-by: jaseel0 <225665919+jaseel0@users.noreply.github.com> Agent-Logs-Url: https://github.com/BeyteFlow/ReadmeGenAI/sessions/486edd1a-2457-4589-b5e2-b61f6dfde55f



This PR implements multi-language support as requested in issue #91.
Changes:
languageparameter.SearchInputcomponent.