feat(landing): add Russian locale routes and translations#600
feat(landing): add Russian locale routes and translations#600DrMaks22 wants to merge 3 commits intojamiepine:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds Russian locale support and runtime locale wiring: i18n utilities, a LocaleProvider, locale-aware layout and route handling, a Russian linux-install page, many components/pages split into EN/RU datasets and switched at render time, and localized routing helpers. ChangesLocale Infrastructure & Routing
Page & Component Localization
Sequence DiagramsequenceDiagram
participant Browser
participant Server as ServerLayout
participant Route as DownloadRoute
participant LocaleProv as LocaleProvider
participant Component as Page/Component
participant Intl as Intl
Browser->>Server: GET /ru/download
Server->>Server: validate locale (isSecondaryLocale)
Server->>Server: generateMetadata({locale: 'ru'})
Server->>LocaleProv: render layout with locale='ru'
Browser->>Route: GET /ru/download/linux
Route->>Route: parse forwarded headers, validate origin
Route-->>Browser: 307 redirect → locale-aware URL
LocaleProv->>Component: provide locale via context
Component->>Component: useLocale() → 'ru' → select *_RU datasets
Component->>Intl: Intl.NumberFormat(getLocaleTag('ru'))
Intl-->>Component: formatted numbers/text
Component-->>Browser: render localized UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
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. ✨ 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. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
landing/src/app/[locale]/layout.tsx (1)
37-39: ⚡ Quick winDerive static params from the shared locale list.
Hard-coding
ruhere duplicatesSECONDARY_LOCALESfromlanding/src/lib/i18n.ts. Pulling from the shared constant keeps this route manifest from drifting when another secondary locale is added.♻️ Proposed fix
import { LocaleProvider } from '@/components/LocaleProvider'; import { getLocalizedPath, isSecondaryLocale, + SECONDARY_LOCALES, type SecondaryLocale, } from '@/lib/i18n'; @@ export function generateStaticParams() { - return [{ locale: 'ru' }]; + return SECONDARY_LOCALES.map((locale) => ({ locale })); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@landing/src/app/`[locale]/layout.tsx around lines 37 - 39, Replace the hard-coded locale in generateStaticParams with the shared SECONDARY_LOCALES constant: import SECONDARY_LOCALES from the i18n module and return an array mapped from that constant (e.g., SECONDARY_LOCALES.map(locale => ({ locale }))) so the route manifest derives its params from the single source of truth; update the generateStaticParams function to use this import and mapping and remove the hard-coded 'ru'.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@landing/src/app/`[locale]/download/[platform]/route.ts:
- Around line 14-47: The getPublicOrigin function reads x-forwarded-host and
x-forwarded-proto unsafely; update it (or implement a centralized proxy.ts and
call it) to split comma-separated header values and use only the first trimmed
value, validate the protocol is exactly "http" or "https", validate the host
string (e.g., allow only hostnames/host:port characters or attempt to construct
a URL and catch exceptions), and fall back to new URL(request.url).origin on any
invalid/missing header; ensure GET continues to call getPublicOrigin(request) so
redirects use the sanitized origin.
In `@landing/src/app/download/page.tsx`:
- Around line 249-257: The platform metadata (PLATFORMS) is not localized,
causing meta.description to remain English; update the code to provide
locale-specific platform definitions (e.g., PLATFORMS_RU and PLATFORMS_EN or a
function getPlatforms(locale)) and use that localized list wherever PLATFORMS is
referenced (including the grid rendering in page.tsx that uses meta.description
and the post-download success component), adjust the logic that selects meta by
meta.key (used alongside isRussian) to instead choose the correct localized meta
object so macOS/linux descriptions and any reuse in the success state render in
Russian when isRussian is true.
In `@landing/src/components/CaptureSection.tsx`:
- Around line 266-283: The useEffect's step() schedules two setTimeouts that are
not cleared on unmount, so track their IDs (e.g., store timeout IDs in local
variables or an array inside the effect) when calling setTimeout in step(),
clear those timeouts with clearTimeout in the cleanup, and also clear any
pending timeouts before scheduling new ones inside step(); reference the
existing identifiers useEffect, step, setShowClean, setPairIdx, iv, and
pairs.length so you locate and update the timing logic.
In `@landing/src/components/CapturesMockup.tsx`:
- Around line 36-44: Update the Russian sidebar labels in SIDEBAR_ITEMS_RU so
all entries are localized: replace the label for the AudioLines item from
"Stories" to "Истории" and the label for the Mic item from "Captures" to
"Записи" (locate the array SIDEBAR_ITEMS_RU and edit the objects with icon
AudioLines and icon Mic accordingly).
---
Nitpick comments:
In `@landing/src/app/`[locale]/layout.tsx:
- Around line 37-39: Replace the hard-coded locale in generateStaticParams with
the shared SECONDARY_LOCALES constant: import SECONDARY_LOCALES from the i18n
module and return an array mapped from that constant (e.g.,
SECONDARY_LOCALES.map(locale => ({ locale }))) so the route manifest derives its
params from the single source of truth; update the generateStaticParams function
to use this import and mapping and remove the hard-coded 'ru'.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 48a2b9bd-2fc6-4931-bed3-5de4f2500b29
📒 Files selected for processing (27)
landing/src/app/[locale]/capture/page.tsxlanding/src/app/[locale]/download/[platform]/route.tslanding/src/app/[locale]/download/page.tsxlanding/src/app/[locale]/layout.tsxlanding/src/app/[locale]/linux-install/page.tsxlanding/src/app/[locale]/page.tsxlanding/src/app/[locale]/sponsors/page.tsxlanding/src/app/capture/page.tsxlanding/src/app/download/page.tsxlanding/src/app/page.tsxlanding/src/app/sponsors/page.tsxlanding/src/components/AgentIntegration.tsxlanding/src/components/ApiSection.tsxlanding/src/components/CaptureHero.tsxlanding/src/components/CaptureSection.tsxlanding/src/components/CapturesMockup.tsxlanding/src/components/ControlUI.tsxlanding/src/components/Features.tsxlanding/src/components/Footer.tsxlanding/src/components/LocaleProvider.tsxlanding/src/components/Navbar.tsxlanding/src/components/Personalities.tsxlanding/src/components/SponsorPromo.tsxlanding/src/components/SupportedModels.tsxlanding/src/components/TutorialsSection.tsxlanding/src/components/VoiceCreator.tsxlanding/src/lib/i18n.ts
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
landing/src/components/CapturesMockup.tsx (1)
541-541:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize the main section title for Russian locale.
Line 541 is still hardcoded to
Captures, so/rushows mixed-language UI in a primary heading.♻️ Proposed fix
- <h1 className="text-2xl px-4 font-bold">Captures</h1> + <h1 className="text-2xl px-4 font-bold"> + {isRussian ? 'Записи' : 'Captures'} + </h1>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@landing/src/components/CapturesMockup.tsx` at line 541, The main section title in the CapturesMockup component is hardcoded as "Captures"; update the component to use the app's localization API instead (e.g., replace the literal "Captures" in the <h1> inside CapturesMockup with a translated string like t('captures') or i18n.t('captures') / <Trans> wrapper as used elsewhere) so the title is localized for the Russian locale; ensure you import/use the same translation hook or helper that other components in the project use and use the key 'captures' (or add that key to the translation files) so /ru renders the translated heading.
♻️ Duplicate comments (1)
landing/src/app/download/page.tsx (1)
37-42:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFinish localizing the Russian platform metadata.
PLATFORMS_RUstill leaves the macOS descriptions in English, so Russian users will still see mixed-language copy in both the download grid and the post-click message.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@landing/src/app/download/page.tsx` around lines 37 - 42, PLATFORMS_RU contains English descriptions for the macOS entries; update the description fields for the objects with key 'macArm' and 'macIntel' in PLATFORMS_RU to their Russian equivalents (so the download grid and any post-click messages that read from PLATFORMS_RU show fully localized copy), and verify that any code reading PLATFORMS_RU (e.g., the download tile renderer and post-click message component) uses those description values rather than hardcoded English strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@landing/src/components/CaptureSection.tsx`:
- Around line 187-192: The interval cycling in the useEffect that updates
setActiveIdx uses only engines.length as a dependency, so when the app locale
changes but engines.length stays the same the animation keeps its previous
position; update the effect to also depend on the locale (e.g., the i18n
language or locale prop) and reset the animation state when locale changes by
calling setActiveIdx(0) (or otherwise reinitializing the index) before/when
starting the new interval; reference the existing useEffect, setActiveIdx, and
engines.length to locate and modify the hook.
- Around line 266-302: The effect that cycles examples (useEffect containing
step, clearPendingTimeouts, revealTimeout, advanceTimeout) currently only
depends on pairs.length, so switching locale can leave pairIdx and animations
mid-stream; include locale in the dependency array and reset the cycling state
when locale changes (e.g., clearPendingTimeouts, setPairIdx(0) or another
initial index, and let step restart) so the timer loop and reveal/advance
timeouts restart cleanly on locale switch.
---
Outside diff comments:
In `@landing/src/components/CapturesMockup.tsx`:
- Line 541: The main section title in the CapturesMockup component is hardcoded
as "Captures"; update the component to use the app's localization API instead
(e.g., replace the literal "Captures" in the <h1> inside CapturesMockup with a
translated string like t('captures') or i18n.t('captures') / <Trans> wrapper as
used elsewhere) so the title is localized for the Russian locale; ensure you
import/use the same translation hook or helper that other components in the
project use and use the key 'captures' (or add that key to the translation
files) so /ru renders the translated heading.
---
Duplicate comments:
In `@landing/src/app/download/page.tsx`:
- Around line 37-42: PLATFORMS_RU contains English descriptions for the macOS
entries; update the description fields for the objects with key 'macArm' and
'macIntel' in PLATFORMS_RU to their Russian equivalents (so the download grid
and any post-click messages that read from PLATFORMS_RU show fully localized
copy), and verify that any code reading PLATFORMS_RU (e.g., the download tile
renderer and post-click message component) uses those description values rather
than hardcoded English strings.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5fade26a-e206-4a15-8bbc-badb95c4dece
📒 Files selected for processing (5)
landing/src/app/[locale]/download/[platform]/route.tslanding/src/app/[locale]/layout.tsxlanding/src/app/download/page.tsxlanding/src/components/CaptureSection.tsxlanding/src/components/CapturesMockup.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- landing/src/app/[locale]/layout.tsx
- landing/src/app/[locale]/download/[platform]/route.ts
Summary
Adds a Russian (
/ru) route layer and Russian landing-page copy without changing the existing English URL structure.Scope
This PR is intentionally limited to the
landingapp:Routes added
/ru/ru/capture/ru/download/ru/sponsors/ru/linux-installFiles changed
landing/src/app/[locale]/...landing/src/app/...landing/src/components/...landing/src/lib/i18n.tsTesting
bun --bun next buildgit diff --checkBuild output confirms the new Russian static routes are generated successfully alongside the existing English routes.
Related PRs
Non-goals
Notes
Summary by CodeRabbit