Skip to content

feat: Implement next-intl for i18n with 4 locales and routing updates#259

Merged
DestroyCom merged 6 commits into
masterfrom
feat/i18n
May 21, 2026
Merged

feat: Implement next-intl for i18n with 4 locales and routing updates#259
DestroyCom merged 6 commits into
masterfrom
feat/i18n

Conversation

@DestroyCom
Copy link
Copy Markdown
Owner

@DestroyCom DestroyCom commented May 21, 2026

Summary by CodeRabbit

  • New Features
    • Full multi-language support (en, fr-FR, es-419, pt-BR) across the site
    • Language switcher added for easy locale selection
    • All UI, guides, legal pages, and error messages translated and localized
  • SEO / Content
    • Localized metadata, OpenGraph, hreflang/alternates, and sitemap entries per locale
    • Updates/changelog now includes a multilingual release entry
  • Documentation
    • Added guidance for adding and managing locales and translations

Review Change Stack

- Restructure app/ → app/[locale]/ with localePrefix: always
- Add next-intl v4: routing, request config, navigation helpers, middleware (proxy.ts)
- Migrate all pages to async generateMetadata with hreflang alternates + setRequestLocale
- Migrate client components (GetterInput, VideoSelect, SiteHeader, SiteFooter) to useTranslations
- Add LocaleSwitcher component integrated in SiteHeader (desktop + mobile)
- Update sitemap to generate 4× entries per URL (one per locale)
- Add messages/en.json with all strings; fr/es/pt are English placeholders pending translation
- Fix t.rich() messages to use XML tag syntax <tag>content</tag> instead of {param} placeholders
URLs are now /en/, /fr-FR/, /es-ES/, /pt-BR/ — precise locale codes
that Google understands directly without ambiguity. A new
buildAlternates(locale, path) helper in i18n/metadata.ts generates
hreflang alternates from routing.locales, so adding a future variant
(fr-CA, pt-PT, es-MX…) only requires adding it to routing.ts and
dropping a messages/fr-CA.json file.
…le conventions

es-419 (UN M.49 Latin America region) is Google's recommended hreflang
value for Spanish targeting the Americas. Also documents how to add new
locale variants in CLAUDE.md so future contributors only need to touch
routing.ts + messages/ + LocaleSwitcher labels.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (3)
  • app/opengraph-image.png is excluded by !**/*.png
  • public/og-image.png is excluded by !**/*.png
  • public/twitter-image.png is excluded by !**/*.png

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5affbc53-4ae3-4d9b-bf8a-fc86df2ca814

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds comprehensive internationalization (i18n) support to StroyGetter using the next-intl library, enabling the site to serve four locales (en, fr-FR, es-419, pt-BR). It introduces locale routing, request-time message loading, locale-aware metadata generation with hreflang alternates, async page components that resolve and apply locale parameters, a locale switcher component, and complete translated message catalogs covering all site content, UI labels, and legal text.

Changes

I18n Infrastructure and Configuration

Layer / File(s) Summary
Locale routing and request configuration
i18n/routing.ts, i18n/request.ts, i18n/metadata.ts, i18n/navigation.ts, next.config.ts, package.json
Defines supported locales, creates request-time message resolver via dynamic JSON imports, exports buildAlternates() for hreflang/canonical metadata, exports Next-Intl navigation helpers, integrates next-intl plugin into Next config, adds next-intl ^4.12.0 dependency.
Middleware and request routing
proxy.ts
Adds Next.js middleware to route and validate requests by locale, excludes API routes and static assets, wraps request with next-intl handling.
Documentation and settings
CLAUDE.md, .claude/settings.json
Documents i18n locale management (adding new locales, conventions), adds code-review plugin configuration.

Root and Page Layout Localization

Layer / File(s) Summary
Root layout with locale support
app/[locale]/layout.tsx
Makes RootLayout async, accepts promised locale params, calls setRequestLocale(), loads messages via getMessages(), sets html lang attribute, wraps all content in NextIntlClientProvider, adds generateStaticParams() to pre-generate supported locales.
Homepage with localized content
app/[locale]/page.tsx
Adds generateMetadata and generateStaticParams for locale-aware SEO, converts component to async, loads getTranslations("home"), builds localized HOW_STEPS/FORMATS/FAQS arrays from translation keys, replaces all hardcoded English copy with t(...) lookups throughout hero, sections, FAQ, and glossary.
Fetch and guide pages
app/[locale]/fetch/page.tsx, app/[locale]/how-to-download-youtube-videos/page.tsx, app/[locale]/how-to-use-library-ready/page.tsx
Converts fetch page and two guide pages to async locale-driven components, adds generateMetadata with buildAlternates() for alternates, calls setRequestLocale(), adjusts formatting/line-wrapping for consistency without changing content meaning.
Library Ready feature page
app/[locale]/library-ready/page.tsx
Adds generateMetadata for localized alternates, converts to async locale component, moves static feature/FAQ content into page scope, builds FEATURES/FAQS from translations, replaces all hero/feature/comparison/FAQ/CTA text with t(...) lookups, updates JSON-LD feature list with translated titles.
Updates section pages
app/[locale]/updates/page.tsx, app/[locale]/updates/[slug]/page.tsx
Updates list page: adds generateMetadata, converts to async, loads getTranslations("updates"), defines locale-specific formatDate, replaces section labels/headings with t(...). Detail page: adds generateMetadata/generateStaticParams returning locale+slug combinations, updates to use buildAlternates(locale, path), replaces back/kicker/CTA/nav labels with translations, uses toLocaleDateString(locale).

Legal Pages and Navigation

Layer / File(s) Summary
Legal section layout
app/[locale]/legal/layout.tsx
Makes LegalLayout async, accepts locale params, calls setRequestLocale(), loads legal translations via getTranslations("legal"), builds LEGAL_NAV from translation keys instead of hardcoded English, renders translated sidebar label and note.
Legal policy pages
app/[locale]/legal/acceptable-use/page.tsx, app/[locale]/legal/contact/page.tsx, app/[locale]/legal/cookies/page.tsx, app/[locale]/legal/dmca/page.tsx, app/[locale]/legal/privacy/page.tsx, app/[locale]/legal/terms/page.tsx
Each converts to async locale-driven component with generateMetadata that awaits locale params and builds alternates via buildAlternates(locale, path), calls setRequestLocale() before rendering policy content.

Component Localization and Locale Switching

Layer / File(s) Summary
Locale switcher component
components/custom/LocaleSwitcher.tsx
New client component that reads current locale via useLocale, reads pathname via usePathname, switches locales by calling router.replace with new locale parameter, renders one button per supported locale with labels from LOCALE_LABELS map, applies active-locale styling and aria-current.
Header and footer
components/custom/SiteHeader.tsx, components/custom/SiteFooter.tsx
Both now use useTranslations() to replace hardcoded navigation/link labels with t(...) lookups. Header: moves NAV_LINKS into component to use translations, adds LocaleSwitcher to desktop nav and mobile menu overlay, localizes home aria-label, hamburger aria-label. Footer: replaces tagline, section headings, copyright, and legal link labels with translations, normalizes link styling.
Input and video selection
components/custom/GetterInput.tsx, components/custom/VideoSelect.tsx
Both replace all hardcoded English UI copy with useTranslations() and t(...) lookups (placeholders, error messages, button labels, status text, disclaimer). Switch router import to i18n-aware navigation. VideoSelect: improves format selection with fallback logic, moves URL revocation to timed callback, adds t to effect dependencies.

Sitemap and SEO

Layer / File(s) Summary
Locale-aware sitemap
app/sitemap.ts
Introduces LOCALES constant from routing.locales, creates localeEntries() helper to generate per-locale sitemap entries with proper URL prefixing, replaces single non-localized URLs with locale-specific entries for homepage and legal pages, updates updates section to generate per-locale slug entries via flatMap, introduces Freq type for changeFrequency validation.

Translation Catalogs

Layer / File(s) Summary
English messages
messages/en.json
Complete English translation catalog covering meta tags, navigation, home page, downloader UI, footer, Library Ready page, guide sections, updates, and legal content.
Spanish, French, and Portuguese messages
messages/es-419.json, messages/fr-FR.json, messages/pt-BR.json
Complete translation catalogs for each locale covering all site sections, guides, and legal pages with interpolation placeholders where needed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • DestroyCom/StroyGetter#248: Introduces the initial acceptable-use policy page; this PR makes it locale-aware via generateMetadata and async component pattern.
  • DestroyCom/StroyGetter#247: Related header/footer and sitemap/SEO changes that this PR extends to be next-intl locale-aware.

Poem

🐰 From the burrow I translate and hop,
Four tongues now greet each desktop top.
Hreflang sewn and locales spun,
Hola, bonjour, olá — all in one.
Debug carrot? Done. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

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.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: implementing i18n using next-intl with 4 locales and routing updates, which aligns with the substantial locale configuration and page routing modifications throughout the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/i18n

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 21, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednext-intl@​4.12.01001009395100

View full report

Copy link
Copy Markdown

@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: 15

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
components/custom/SiteHeader.tsx (1)

58-59: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize remaining accessibility labels in header navigation.

aria-label values are still hardcoded in English ("Main navigation", "StroyGetter on GitHub", "Mobile navigation"), so screen-reader UX is only partially localized.

Suggested patch
-          <nav className="hidden items-center gap-8 md:flex" aria-label="Main navigation">
+          <nav className="hidden items-center gap-8 md:flex" aria-label={t("mainNavigationAria")}>
...
-              aria-label="StroyGetter on GitHub"
+              aria-label={t("githubAria")}
...
-              <nav className="flex flex-col gap-1" aria-label="Mobile navigation">
+              <nav className="flex flex-col gap-1" aria-label={t("mobileNavigationAria")}>

Also applies to: 73-74, 94-95

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/custom/SiteHeader.tsx` around lines 58 - 59, Replace the three
hardcoded aria-labels in SiteHeader.tsx with localized strings: call the app's
translation hook/function (e.g., useTranslations or t) at the top of the
SiteHeader component and use it to provide aria-label values for the main <nav>
(currently "Main navigation"), the GitHub external link (currently "StroyGetter
on GitHub"), and the mobile nav toggle/button (currently "Mobile navigation");
update the attributes where NAV_LINKS.map is rendered and the elements
referenced around the other occurrences (the strings at the other two locations)
to use the translation keys (e.g., t('header.mainNavigation'),
t('header.githubLink'), t('header.mobileNavigation')) so screen-reader labels
are fully localized.
app/[locale]/legal/terms/page.tsx (1)

62-67: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use i18n Link for internal legal navigation to preserve locale
app/[locale]/legal/terms/page.tsx line 63 uses <a href="/legal/acceptable-use">, which drops the current locale (with localePrefix: "always" this will fall back to the default locale). Use Link from @/i18n/navigation like the legal layout/footer do (app/[locale]/legal/layout.tsx, components/custom/SiteFooter.tsx). Also update the back-link in app/[locale]/legal/acceptable-use/page.tsx.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`[locale]/legal/terms/page.tsx around lines 62 - 67, Replace the plain
anchor in the Terms page with the i18n-aware Link from '`@/i18n/navigation`':
import Link and swap the <a href="/legal/acceptable-use"> element in
app/[locale]/legal/terms/page.tsx (preserve className and href value) so
navigation retains the current locale; likewise update the back-link in the
Acceptable Use page (app/[locale]/legal/acceptable-use/page.tsx) to use the same
Link import/usage. Ensure the Link preserves styling/attributes and remove the
old anchor import/usages.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/`[locale]/legal/acceptable-use/page.tsx:
- Around line 14-17: The page currently calls setRequestLocale(locale) but uses
hardcoded English title/description and policy text; replace those hardcoded
strings with locale-aware lookups (e.g., load messages/<locale>.json or use the
existing i18n message helper) so metadata and the policy copy are generated from
translations; update the metadata block (title/description) and the render
content (the policy text lines where the English copy is hardcoded) to read from
the messages object, ensure new locales are added to locales in i18n/routing.ts
and translated keys are present in messages/<locale>.json, and verify
LocaleSwitcher (components/custom/LocaleSwitcher.tsx) labels include the new
locales so users see translations for setRequestLocale(locale)-driven pages.

In `@app/`[locale]/legal/contact/page.tsx:
- Around line 16-18: The page metadata and on-page copy in the Contact page are
hardcoded in English; update the title, description, and all visible strings to
use localized messages from your i18n message bundle (messages/<locale>.json)
and the locale-aware message loader used in your app (e.g., the same translation
hook or helper used elsewhere). Replace the literal "Contact" and "Get in
touch..." values with calls to the translation loader used in this route (refer
to the page component and its exported metadata object and JSX render), pull
keys like contact.title/contact.description from messages/<locale>.json, and
ensure buildAlternates(locale, path) remains. Also update on-page copy between
lines ~22-66 to use the same translation keys so non-English locales render
correctly.

In `@app/`[locale]/legal/cookies/page.tsx:
- Around line 13-15: The page currently uses hardcoded English strings for
metadata (title, description) and the cookie policy body; replace those with
locale-aware lookups: load the locale messages (from messages/<locale>.json or
your existing i18n loader) inside the page component (using the route's locale
param), then set metadata.title and metadata.description from the message keys
(e.g., cookies.title, cookies.description) instead of the literal strings and
render the policy content from message keys (e.g., cookies.intro,
cookies.sections.*) rather than hardcoded text; keep buildAlternates(locale,
path) as-is so alternates still work and ensure the page’s default export reads
the same message object to render lines currently populated 19-70.

In `@app/`[locale]/legal/dmca/page.tsx:
- Around line 14-16: Metadata and page content in
app/[locale]/legal/dmca/page.tsx are still hardcoded in English; update the file
to load locale-specific messages using the resolved locale and replace literal
strings (e.g., the metadata title and description and the DMCA body between
lines ~20-64) with lookups from the messages object; ensure you use the existing
locale argument and the buildAlternates(locale, path) call, import/await the
appropriate messages/<locale>.json (or the project's getMessages helper) and
reference message keys (e.g., dmca.title, dmca.description, dmca.paragraph1,
etc.) for both metadata (title/description) and rendered content so each locale
route serves translated DMCA text.

In `@app/`[locale]/legal/layout.tsx:
- Around line 29-31: Replace the hardcoded aria-label on the nav element with a
localized string (use t("sidebarNavAriaLabel") instead of "Legal pages
navigation") in the layout where t(...) is already used; then add the new
"sidebarNavAriaLabel" key to each messages/<locale>.json with appropriate
translations and follow the project localization steps (add locale code to
locales in i18n/routing.ts and update LocaleSwitcher labels if adding new
locales) so screen readers receive the translated label.

In `@app/`[locale]/legal/privacy/page.tsx:
- Around line 14-16: Replace hardcoded English strings used in metadata (title,
description via buildAlternates) and the privacy policy body (lines ~20-67) with
locale-aware message lookups: add keys for title, description and each policy
section to messages/<locale>.json, load the correct messages file in page.tsx
using the existing locale param, and use those message values for the metadata
fields and rendered content; also ensure the new locale is added to the locales
list in i18n/routing.ts and the display label is added to
components/custom/LocaleSwitcher.tsx so the page can be translated and routed
correctly.

In `@app/`[locale]/legal/terms/page.tsx:
- Around line 14-17: The page currently hardcodes English metadata and legal
copy; instead load localized strings from the per-locale messages
(messages/<locale>.json) and use them for title, description and the terms
content and metadata; ensure the route respects the configured locales in
i18n/routing.ts and that the translated labels used by LocaleSwitcher
(components/custom/LocaleSwitcher.tsx) are present. Concretely: replace the
literal "Terms of use" and description and the body text in the Terms page with
lookups into the locale messages (using your app's translation loader /
useTranslations helper) and add the missing keys to each messages/<locale>.json
so non-English locales render translated metadata and copy (also update the same
pattern for the block around the existing content between the earlier and lines
~49-81).

In `@app/`[locale]/page.tsx:
- Line 4: The page imports Link from next/link and uses an absolute href which
loses the active locale; replace that import with the locale-aware Link from
"`@/i18n/navigation`" and update any usages of the Link component in
app/[locale]/page.tsx (e.g., the anchor linking to "/library-ready") to use the
imported locale-aware Link so the current locale is preserved during navigation.

In `@app/`[locale]/updates/page.tsx:
- Around line 16-27: The Open Graph and JSON-LD URLs are not localized: update
openGraph.url and any JsonLd URL construction to use the locale-aware path
instead of the hardcoded "/updates"; use the existing path variable and locale
(e.g., combine siteConfig.url with buildAlternates/locale or
`${siteConfig.url}/${locale}${path}` when locale is present) so openGraph.url
and the JsonLd output point to the locale-specific page; ensure the same
localization logic is applied wherever JsonLd or share URLs are generated
(referencing openGraph.url, path, buildAlternates, and siteConfig.url).

In `@app/sitemap.ts`:
- Line 31: The sitemap code currently assumes updates[0] exists when calling
localeEntries("/updates", new Date(updates[0].date), ...), which will throw if
updates is empty; modify the logic around the call to guard access to updates[0]
(e.g., check if updates && updates.length > 0) and either skip adding the
"/updates" locale entry when there are no updates or supply a safe fallback date
(like new Date() or a configured default) before calling localeEntries so
sitemap generation cannot crash; update the code paths that reference
updates[0].date and the localeEntries invocation to use this guard or fallback.

In `@components/custom/SiteFooter.tsx`:
- Around line 95-97: The footer entry in SiteFooter (the Link whose label is
t("learnLibraryReady") and currently has href="/#formats") points to the wrong
target; update that Link in the SiteFooter component to use the Library Ready
page route (replace href="/#formats" with the correct route for the Library
Ready page, e.g. "/library-ready") so the label and destination match.

In `@i18n/metadata.ts`:
- Around line 7-16: buildAlternates currently returns relative URLs; change it
to build absolute canonical and hreflang URLs using the SITE_URL base. In the
buildAlternates function replace relative constructions like `/${locale}${path}`
and `/${l}${path}` (and the x-default using routing.defaultLocale) with
concatenation against SITE_URL (ensure you read SITE_URL from env/config and
trim trailing slash to avoid double slashes) so canonical becomes
`${SITE_URL}/${locale}${path}` and each languages[l] and languages["x-default"]
use the same SITE_URL-based absolute form; keep using routing.locales and
routing.defaultLocale to choose locales.

In `@messages/pt-BR.json`:
- Around line 383-405: The Portuguese legal copy under the "legal" object (keys
like termsLastUpdated, termsH1, termsIntro, terms01Title..terms05Body,
termsAcceptableUseLink, dmcaEmail) is not a faithful/legal-equivalent
translation and contains ambiguous phrasing; replace these values with precise,
literal translations that preserve the original legal meaning and tone from the
source locale (clear dates format, unambiguous obligations/prohibitions, DMCA
contact placeholder {dmcaEmail} preserved, and exact phrasing for acceptable-use
reference {acceptableUseLink}); ensure titles (terms01Title..terms05Title) match
the source intent (use, redistribution, cookies/privacy, DMCA/reporting,
open-source & liability limits) and bodies (terms01Body..terms05Body) restate
legal restrictions, user rights, and liability disclaimers in formal Brazilian
Portuguese without introducing informal or misleading language.
- Around line 246-382: The Portuguese (pt-BR) copy for objects howToDownload,
howToLibrary and updates is unnatural and semantically broken; replace those
values with fluent, idiomatic Brazilian Portuguese while preserving placeholders
(e.g., {cmdC}, {ctrlC}, {siteUrl}, {mp4}, {mp3}, {libraryReady}, {searchVideo},
{download}, {addToLibrary}, {musicUrl}, {urlDesktop}, {urlMobile}) and metadata
(kicker, readTime, updated, authorTitle, etc.), correct grammar/terminology
(e.g., "drive"→"armazenamento", "mp3 kbps=190"→"MP3 a 190 kbps"), make
instructions concise and actionable (clear step bodies, troubleshooting, FAQ),
and ensure CTAs and headings in the keys howToDownload.* howToLibrary.* and
updates.* read naturally for Brazilian users.

In `@proxy.ts`:
- Around line 7-9: The middleware matcher in proxy.ts currently only lists a few
exact filenames/prefixes and misses general dotted asset routes; update the
matcher array (the matcher entry) to also exclude any request path that contains
a file extension or common static asset extensions (e.g., .png .jpg .jpeg
.webmanifest .ico .svg .css .js .json .map and similar), by extending the
negative lookahead to reject dotted filenames or those extensions so static
assets like /manifest.webmanifest or /apple-touch-icon.png are not matched by
the middleware.

---

Outside diff comments:
In `@app/`[locale]/legal/terms/page.tsx:
- Around line 62-67: Replace the plain anchor in the Terms page with the
i18n-aware Link from '`@/i18n/navigation`': import Link and swap the <a
href="/legal/acceptable-use"> element in app/[locale]/legal/terms/page.tsx
(preserve className and href value) so navigation retains the current locale;
likewise update the back-link in the Acceptable Use page
(app/[locale]/legal/acceptable-use/page.tsx) to use the same Link import/usage.
Ensure the Link preserves styling/attributes and remove the old anchor
import/usages.

In `@components/custom/SiteHeader.tsx`:
- Around line 58-59: Replace the three hardcoded aria-labels in SiteHeader.tsx
with localized strings: call the app's translation hook/function (e.g.,
useTranslations or t) at the top of the SiteHeader component and use it to
provide aria-label values for the main <nav> (currently "Main navigation"), the
GitHub external link (currently "StroyGetter on GitHub"), and the mobile nav
toggle/button (currently "Mobile navigation"); update the attributes where
NAV_LINKS.map is rendered and the elements referenced around the other
occurrences (the strings at the other two locations) to use the translation keys
(e.g., t('header.mainNavigation'), t('header.githubLink'),
t('header.mobileNavigation')) so screen-reader labels are fully localized.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d767db97-7b53-4c94-b9c3-7d85b4ec4d96

📥 Commits

Reviewing files that changed from the base of the PR and between 4c94ad6 and 2ec664d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (34)
  • .claude/settings.json
  • CLAUDE.md
  • app/[locale]/fetch/page.tsx
  • app/[locale]/how-to-download-youtube-videos/page.tsx
  • app/[locale]/how-to-use-library-ready/page.tsx
  • app/[locale]/layout.tsx
  • app/[locale]/legal/acceptable-use/page.tsx
  • app/[locale]/legal/contact/page.tsx
  • app/[locale]/legal/cookies/page.tsx
  • app/[locale]/legal/dmca/page.tsx
  • app/[locale]/legal/layout.tsx
  • app/[locale]/legal/privacy/page.tsx
  • app/[locale]/legal/terms/page.tsx
  • app/[locale]/library-ready/page.tsx
  • app/[locale]/page.tsx
  • app/[locale]/updates/[slug]/page.tsx
  • app/[locale]/updates/page.tsx
  • app/sitemap.ts
  • components/custom/GetterInput.tsx
  • components/custom/LocaleSwitcher.tsx
  • components/custom/SiteFooter.tsx
  • components/custom/SiteHeader.tsx
  • components/custom/VideoSelect.tsx
  • i18n/metadata.ts
  • i18n/navigation.ts
  • i18n/request.ts
  • i18n/routing.ts
  • messages/en.json
  • messages/es-419.json
  • messages/fr-FR.json
  • messages/pt-BR.json
  • next.config.ts
  • package.json
  • proxy.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use import { prisma } from "@/lib/prisma" for all database access — never instantiate with new PrismaClient()

Do not call prisma.$disconnect() on the shared singleton instance, as it breaks subsequent requests and cron runs

Use only server-only runtime environment variables with no NEXT_PUBLIC_* prefix; configure all vars in docker-compose, never rebuild the image to change them

Use SITE_URL environment variable for canonical base URL in sitemap, robots.txt, OpenGraph, and JSON-LD metadata

Configure the database path via DATABASE_URL environment variable pointing to SQLite file (required, no default)

Files:

  • i18n/navigation.ts
  • proxy.ts
  • app/[locale]/legal/privacy/page.tsx
  • app/[locale]/legal/acceptable-use/page.tsx
  • i18n/routing.ts
  • app/[locale]/legal/contact/page.tsx
  • app/[locale]/legal/cookies/page.tsx
  • app/[locale]/legal/layout.tsx
  • app/[locale]/legal/dmca/page.tsx
  • app/[locale]/legal/terms/page.tsx
  • components/custom/LocaleSwitcher.tsx
  • app/[locale]/how-to-download-youtube-videos/page.tsx
  • next.config.ts
  • i18n/metadata.ts
  • i18n/request.ts
  • app/[locale]/layout.tsx
  • app/[locale]/updates/page.tsx
  • components/custom/GetterInput.tsx
  • app/sitemap.ts
  • app/[locale]/fetch/page.tsx
  • components/custom/SiteHeader.tsx
  • components/custom/SiteFooter.tsx
  • app/[locale]/updates/[slug]/page.tsx
  • app/[locale]/library-ready/page.tsx
  • app/[locale]/how-to-use-library-ready/page.tsx
  • app/[locale]/page.tsx
  • components/custom/VideoSelect.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Fetch video metadata and format lists using getBasicInfo() from lib/innertube.ts (via youtubei.js library)

Download actual video streams using youtube-dl-exec (yt-dlp binary) via selectYtDlpPath(), not youtubei.js

Parse yt-dlp format information using the utilities in lib/ytdlp-info.ts

Cache merged MP4 files in temp/cached/ and index them in the File table by URL and quality combination

For audio-only streams (quality=audio), stream directly via ffmpeg to PassThrough to Response without persisting to disk

Fetch thumbnail to a temp file for album art embedding in audio streams, then delete the temp file after ffmpeg closes

Initialize temp directories via initializeConf() on the first request (dev: ./temp/{source,cached}, production: /temp/stroygetter/{source,cached})

Sanitize filenames using sanitizeFilename() from lib/serverUtils.ts

Validate YouTube URLs using yt_validate() from lib/serverUtils.ts

Pass MAX_FILESIZE environment variable directly to yt-dlp via the --max-filesize flag

Files:

  • i18n/navigation.ts
  • proxy.ts
  • app/[locale]/legal/privacy/page.tsx
  • app/[locale]/legal/acceptable-use/page.tsx
  • i18n/routing.ts
  • app/[locale]/legal/contact/page.tsx
  • app/[locale]/legal/cookies/page.tsx
  • app/[locale]/legal/layout.tsx
  • app/[locale]/legal/dmca/page.tsx
  • app/[locale]/legal/terms/page.tsx
  • components/custom/LocaleSwitcher.tsx
  • app/[locale]/how-to-download-youtube-videos/page.tsx
  • next.config.ts
  • i18n/metadata.ts
  • i18n/request.ts
  • app/[locale]/layout.tsx
  • app/[locale]/updates/page.tsx
  • components/custom/GetterInput.tsx
  • app/sitemap.ts
  • app/[locale]/fetch/page.tsx
  • components/custom/SiteHeader.tsx
  • components/custom/SiteFooter.tsx
  • app/[locale]/updates/[slug]/page.tsx
  • app/[locale]/library-ready/page.tsx
  • app/[locale]/how-to-use-library-ready/page.tsx
  • app/[locale]/page.tsx
  • components/custom/VideoSelect.tsx
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use the locale codes: generic English (en), French France (fr-FR), Latin American Spanish (es-419), Brazilian Portuguese (pt-BR)

Files:

  • i18n/navigation.ts
  • proxy.ts
  • app/[locale]/legal/privacy/page.tsx
  • app/[locale]/legal/acceptable-use/page.tsx
  • i18n/routing.ts
  • package.json
  • app/[locale]/legal/contact/page.tsx
  • app/[locale]/legal/cookies/page.tsx
  • app/[locale]/legal/layout.tsx
  • app/[locale]/legal/dmca/page.tsx
  • messages/es-419.json
  • app/[locale]/legal/terms/page.tsx
  • components/custom/LocaleSwitcher.tsx
  • app/[locale]/how-to-download-youtube-videos/page.tsx
  • next.config.ts
  • i18n/metadata.ts
  • i18n/request.ts
  • app/[locale]/layout.tsx
  • app/[locale]/updates/page.tsx
  • messages/fr-FR.json
  • components/custom/GetterInput.tsx
  • messages/pt-BR.json
  • app/sitemap.ts
  • messages/en.json
  • app/[locale]/fetch/page.tsx
  • components/custom/SiteHeader.tsx
  • components/custom/SiteFooter.tsx
  • app/[locale]/updates/[slug]/page.tsx
  • app/[locale]/library-ready/page.tsx
  • app/[locale]/how-to-use-library-ready/page.tsx
  • app/[locale]/page.tsx
  • components/custom/VideoSelect.tsx
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: DestroyCom/StroyGetter

Timestamp: 2026-05-21T09:48:38.992Z
Learning: Add new locales by: (1) adding locale code to `locales` in `i18n/routing.ts`, (2) creating `messages/<locale>.json`, (3) adding display label in `components/custom/LocaleSwitcher.tsx`, (4) translating messages
Learnt from: CR
Repo: DestroyCom/StroyGetter

Timestamp: 2026-05-21T09:48:38.992Z
Learning: Let `buildAlternates()` in `i18n/metadata.ts` and `routing.locales` automatically handle sitemap generation, hreflang alternates, and static params — do not maintain these manually
Learnt from: CR
Repo: DestroyCom/StroyGetter

Timestamp: 2026-05-21T09:48:38.992Z
Learning: Use `copy-binaries.js` postbuild script to copy the yt-dlp binary into `.next/standalone/` — this is required for standalone output to work in production
Learnt from: CR
Repo: DestroyCom/StroyGetter

Timestamp: 2026-05-21T09:48:38.992Z
Learning: Handle Files containing ytdl `.exec` calls carefully — these trigger a Write-tool security block; use the Edit tool for surgical changes to files like `route.ts`
Learnt from: CR
Repo: DestroyCom/StroyGetter

Timestamp: 2026-05-21T09:48:38.992Z
Learning: Push to the `prod` branch (not `master`) to trigger the CI release pipeline that creates git tags, builds Docker images, and publishes GitHub releases
Learnt from: CR
Repo: DestroyCom/StroyGetter

Timestamp: 2026-05-21T09:48:38.992Z
Learning: Ensure the `.env` file is never committed — inject it from the `ENVFILE` GitHub secret during Docker image builds
🔇 Additional comments (21)
messages/en.json (1)

1-406: LGTM!

messages/es-419.json (1)

1-406: LGTM!

messages/fr-FR.json (1)

1-406: LGTM!

i18n/routing.ts (1)

1-7: LGTM!

i18n/request.ts (1)

4-13: LGTM!

i18n/navigation.ts (1)

1-4: LGTM!

next.config.ts (1)

2-4: LGTM!

Also applies to: 36-36

package.json (1)

35-35: LGTM!

.claude/settings.json (1)

1-5: LGTM!

CLAUDE.md (1)

59-78: LGTM!

app/[locale]/how-to-download-youtube-videos/page.tsx (1)

3-3: Same locale-retention issue as other [locale] pages.

This route still uses next/link with absolute hrefs, which can bypass locale-prefixed navigation. Please switch to the i18n Link helper here too.

Also applies to: 233-238, 336-338

app/[locale]/how-to-use-library-ready/page.tsx (1)

3-3: Same locale-retention issue as other [locale] pages.

Please use the i18n navigation Link on this page as well; current absolute links can drop the active locale.

Also applies to: 261-266, 376-385

app/[locale]/library-ready/page.tsx (1)

12-12: Same locale-retention issue as other [locale] pages.

Please migrate these links to the i18n navigation helper to keep users on their current locale.

Also applies to: 343-353

app/[locale]/updates/[slug]/page.tsx (2)

24-34: Same localized metadata URL inconsistency as /updates.

buildAlternates(locale, path) is locale-aware, but openGraph.url omits locale. Please align OG URL with the active locale path.


3-3: Same locale-retention issue as other [locale] pages.

These links should use the i18n navigation helper to avoid dropping locale prefixes during navigation.

Also applies to: 91-92, 135-136, 147-148, 160-161

app/[locale]/layout.tsx (1)

31-33: LGTM!

Also applies to: 111-130

app/[locale]/fetch/page.tsx (1)

13-20: LGTM!

components/custom/LocaleSwitcher.tsx (1)

1-43: LGTM!

components/custom/GetterInput.tsx (1)

4-6: LGTM!

Also applies to: 8-8, 14-14, 29-29, 40-40, 66-66, 79-79, 85-85, 89-90, 101-101, 105-105

components/custom/VideoSelect.tsx (1)

4-6: LGTM!

Also applies to: 16-16, 27-27, 29-44, 80-80, 83-83, 122-122, 137-137, 150-150, 185-185, 188-206, 216-216, 220-220, 242-254, 264-264, 278-278, 288-288, 292-292

app/[locale]/legal/acceptable-use/page.tsx (1)

66-71: ⚡ Quick win

Missing input: Provide the original review comment (including the <review_comment> text and any relevant diff/snippet) so it can be rewritten correctly.

Comment thread app/[locale]/legal/acceptable-use/page.tsx Outdated
Comment thread app/[locale]/legal/contact/page.tsx Outdated
Comment thread app/[locale]/legal/cookies/page.tsx Outdated
Comment thread app/[locale]/legal/dmca/page.tsx Outdated
Comment thread app/[locale]/legal/layout.tsx Outdated
Comment thread components/custom/SiteFooter.tsx Outdated
Comment thread i18n/metadata.ts
Comment thread messages/pt-BR.json
Comment thread messages/pt-BR.json
Comment thread proxy.ts
Introduce i18n changes: use next-intl getTranslations for dynamic metadata and page text, include locale in OpenGraph URLs, and replace next/link with the project's i18n Link where appropriate. Localize UI strings (hero, glossary, buttons, compare rows, etc.), move static metadata into the "meta" namespace, and wire common translations (e.g. openDownloader). Add an "Acceptable use" nav item and link usage in legal pages, tighten some layout spacing classes, and add a new updates entry (v3-8-0-multilingual). Update translation JSONs (en, es-419, fr-FR, pt-BR) with new keys and copy adjustments.
Switch legal pages to next-intl translations (getTranslations/setRequestLocale), replacing hard-coded text with localized keys and t.rich for inline links/code. Add new translation keys in messages (en, es-419, fr-FR, pt-BR) for terms, privacy, cookies, DMCA, contact and sidebar labels. Update i18n metadata to build absolute alternates/canonical URLs using siteConfig.url, adjust sitemap and updates structured data to include locale in URLs and guard empty updates, and tweak header/footer navigation (aria labels and link to /library-ready) for accessibility and correct routing.
Relocate social preview images from app/ to public/: app/og-image.png -> public/og-image.png and app/twitter-image.png -> public/twitter-image.png (files unchanged). Remove redundant app/opengraph-image.png. This consolidates static assets into the public directory for serving and cleans up a legacy duplicate.
@DestroyCom DestroyCom merged commit bb6787c into master May 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant