-
Notifications
You must be signed in to change notification settings - Fork 15
🤖 Sync Crowdin Translations #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Render primaryName and secondaryName
Updated dependencies to fix Next.js CVE vulnerabilities. The fix-react2shell-next tool automatically updated the following packages to their secure versions: - next - react-server-dom-webpack - react-server-dom-parcel - react-server-dom-turbopack All package.json files have been scanned and vulnerable versions have been patched to the correct fixed versions based on the official React advisory. Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
…ce-ad-viud10 Fix React Server Components RCE vulnerability
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note
|
| Cohort / File(s) | Summary |
|---|---|
Localization: Common (expand/collapse) locales/ar/common.json, locales/bn/common.json, locales/es/common.json, locales/fa/common.json, locales/fr/common.json, locales/ha/common.json, locales/hi/common.json, locales/ms/common.json, locales/ps/common.json, locales/ru/common.json, locales/so/common.json, locales/tr/common.json, locales/ur/common.json |
Added top-level keys expand-all and collapse-all with translations. |
Localization: Home sections locales/*/home.json (ar, bn, en, es, fa, fr, ha, hi, ms, ps, ru, so, tr, ur) |
Replaced sections.collections with sections.genres, sections.special-collections, and sections.individual-collections. |
Genre API & homepage genres src/lib/api/genres.ts, src/app/[locale]/page.tsx |
Added getHomepageAdvancedGenres; switched homepage to fetch advanced genres and updated UI/navigation to use genres links. |
URLs / Navigation src/lib/urls.ts |
Removed fromHomepage parameter from navigation.genres.bySlug(); URL now always /genre/{slug}. |
Genre page & OG route src/app/[locale]/(entityPages)/genre/[genreSlug]/page.tsx, src/app/[locale]/(entityPages)/genre/[genreSlug]/routeType.ts, src/app/api/og/genre/[slug]/route.tsx |
Consolidated genre retrieval to always use getAdvancedGenre; removed fromHomepage route param and related fallback logic. |
Author page & search filters src/app/[locale]/(entityPages)/author/[authorSlug]/page.tsx, src/hooks/use-global-chat.ts |
Switched filter field from genres to advancedGenres (renamed local variable genreIds → advancedGenreIds in hook). |
Genre components & types src/types/genre.ts, src/components/genres-filter/client.tsx, src/components/genres-tree-chart/client.tsx |
Added exported GenreNode type (id, slug, primaryName, secondaryName, numberOfBooks, children[]); components updated to use GenreNode, display primaryName/secondaryName, and adjusted tree-chart layout, wrapping, and sizing. |
UI hydration fixes src/components/cloudflare-image.tsx, src/components/navbar/locale-switcher.tsx, src/components/navbar/profile-dropdown.tsx, src/components/ui/command/index.tsx, src/components/ui/dropdown-menu/index.tsx, src/components/ui/navigation-menu.tsx, src/components/ui/select/index.tsx |
Added suppressHydrationWarning to various UI components and wrappers to suppress hydration warnings. |
Other adjustments src/components/genres-filter/client.tsx |
Replaced local GenreNode interface with imported GenreNode; render labels use primaryName. |
Deps package.json |
Bumped Next.js version from 16.0.1 to 16.0.7. |
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~50 minutes
Areas requiring extra attention:
- src/components/genres-tree-chart/client.tsx — text-wrapping, sizing, and layout changes (high-density visual logic).
- src/app/(entityPages)/genre/* and src/app/api/og/genre/* — ensure getAdvancedGenre covers prior fallback cases.
- src/lib/urls.ts and navigation call sites — verify removal of
fromHomepagedidn't leave stale callers. - Localization files — confirm new keys present and syntactically valid in all locale JSON files.
- UI hydration changes — ensure suppressHydrationWarning usage is intentional and doesn't mask real hydration mismatches.
Poem
🐰 I hopped through locales, one by one,
Primary names shining bright as sun.
FromHomepage gone — the path is neat,
Tree nodes stretch on nimble feet.
Hydration eased, the UI hums — a cozy bun.
Pre-merge checks and finishing touches
❌ Failed checks (1 warning, 1 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
|
| Title check | ❓ Inconclusive | The title uses an emoji and generic phrasing ('Sync Crowdin Translations') that lacks specificity about the actual changes in the pull request. | Consider a more descriptive title that specifies the key changes, such as 'Update locale files with genre-based navigation restructuring' or 'Refactor genre navigation and add expand/collapse translations'. |
✅ Passed checks (1 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
✨ Finishing touches
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
l10n_crowdin_translations
📜 Recent review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
locales/ar/home.json(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- locales/ar/home.json
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 @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/genres-filter/client.tsx (1)
163-168: Fuse search index references non-existentnamefield.The
GenreNodetype (fromsrc/types/genre.ts) hasprimaryNameandsecondaryNamefields, but the Fuse index is configured to search on["id", "name"]. Thenamekey won't match any field, causing genre name searches to fail silently.const index = useMemo(() => { return new Fuse(allGenres, { - keys: ["id", "name"], + keys: ["id", "primaryName", "secondaryName"], threshold: 0.3, }); }, [allGenres]);
🧹 Nitpick comments (2)
src/components/genres-tree-chart/client.tsx (1)
7-7: Prefer type-only import forGenreNode.Since
GenreNodeis only used as a type annotation, use a type-only import for better tree-shaking and clearer intent.-import { GenreNode } from "@/types/genre"; +import type { GenreNode } from "@/types/genre";src/app/[locale]/(entityPages)/genre/[genreSlug]/page.tsx (1)
9-9: Remove duplicategetAdvancedGenrefunction fromadvanced-genres.ts.Identical implementations of
getAdvancedGenreexist in bothsrc/lib/api/genres.tsandsrc/lib/api/advanced-genres.ts. Only the version ingenres.tsis imported and used throughout the codebase; the version inadvanced-genres.tsis dead code. Remove the duplicate fromadvanced-genres.tsto eliminate confusion and maintenance burden.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (46)
locales/ar/common.json(1 hunks)locales/ar/home.json(1 hunks)locales/bn/common.json(1 hunks)locales/bn/home.json(1 hunks)locales/en/home.json(1 hunks)locales/es/common.json(1 hunks)locales/es/home.json(1 hunks)locales/fa/common.json(1 hunks)locales/fa/home.json(1 hunks)locales/fr/common.json(1 hunks)locales/fr/home.json(1 hunks)locales/ha/common.json(1 hunks)locales/ha/home.json(1 hunks)locales/hi/common.json(1 hunks)locales/hi/home.json(1 hunks)locales/ms/common.json(1 hunks)locales/ms/home.json(1 hunks)locales/ps/common.json(1 hunks)locales/ps/home.json(1 hunks)locales/ru/common.json(1 hunks)locales/ru/home.json(1 hunks)locales/so/common.json(1 hunks)locales/so/home.json(1 hunks)locales/tr/common.json(1 hunks)locales/tr/home.json(1 hunks)locales/ur/common.json(1 hunks)locales/ur/home.json(1 hunks)package.json(1 hunks)src/app/[locale]/(entityPages)/author/[authorSlug]/page.tsx(1 hunks)src/app/[locale]/(entityPages)/genre/[genreSlug]/page.tsx(4 hunks)src/app/[locale]/(entityPages)/genre/[genreSlug]/routeType.ts(0 hunks)src/app/[locale]/page.tsx(3 hunks)src/app/api/og/genre/[slug]/route.tsx(3 hunks)src/components/cloudflare-image.tsx(1 hunks)src/components/genres-filter/client.tsx(2 hunks)src/components/genres-tree-chart/client.tsx(8 hunks)src/components/navbar/locale-switcher.tsx(1 hunks)src/components/navbar/profile-dropdown.tsx(1 hunks)src/components/ui/command/index.tsx(3 hunks)src/components/ui/dropdown-menu/index.tsx(2 hunks)src/components/ui/navigation-menu.tsx(2 hunks)src/components/ui/select/index.tsx(4 hunks)src/hooks/use-global-chat.ts(1 hunks)src/lib/api/genres.ts(1 hunks)src/lib/urls.ts(1 hunks)src/types/genre.ts(1 hunks)
💤 Files with no reviewable changes (1)
- src/app/[locale]/(entityPages)/genre/[genreSlug]/routeType.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/localization.mdc)
If you're using a translation key in the codebase, use the
useTranslationshook fromnext-intlas shown:import { useTranslations } from "next-intl"; const t = useTranslations(); t("common.delete");
Files:
src/components/navbar/profile-dropdown.tsxsrc/components/ui/command/index.tsxsrc/components/ui/navigation-menu.tsxsrc/components/genres-filter/client.tsxsrc/app/api/og/genre/[slug]/route.tsxsrc/app/[locale]/(entityPages)/author/[authorSlug]/page.tsxsrc/app/[locale]/(entityPages)/genre/[genreSlug]/page.tsxsrc/components/genres-tree-chart/client.tsxsrc/components/cloudflare-image.tsxsrc/components/navbar/locale-switcher.tsxsrc/components/ui/dropdown-menu/index.tsxsrc/components/ui/select/index.tsxsrc/app/[locale]/page.tsx
locales/en/**/*
📄 CodeRabbit inference engine (.cursor/rules/localization.mdc)
Whenever you're adding a new string to the codebase, make sure to add it to a translation file in
locales/en.
Files:
locales/en/home.json
🧠 Learnings (1)
📚 Learning: 2025-08-06T11:58:32.752Z
Learnt from: CR
Repo: seemorg/usul PR: 0
File: .cursor/rules/localization.mdc:0-0
Timestamp: 2025-08-06T11:58:32.752Z
Learning: Applies to **/*.tsx : If you're using a translation key in the codebase, use the `useTranslations` hook from `next-intl` as shown: `import { useTranslations } from "next-intl"; const t = useTranslations(); t("common.delete");`
Applied to files:
src/components/genres-tree-chart/client.tsx
🧬 Code graph analysis (6)
src/lib/api/genres.ts (3)
src/lib/locale/utils.ts (1)
PathLocale(13-13)src/lib/api/utils.ts (1)
apiFetch(37-69)src/types/api/genre.ts (1)
ApiGenreCollection(11-14)
src/hooks/use-global-chat.ts (1)
src/stores/chat-filters.ts (1)
useChatFilters(26-79)
src/app/api/og/genre/[slug]/route.tsx (2)
src/lib/api/genres.ts (1)
getAdvancedGenre(7-14)src/lib/api/advanced-genres.ts (1)
getAdvancedGenre(7-14)
src/app/[locale]/(entityPages)/genre/[genreSlug]/page.tsx (2)
src/lib/api/genres.ts (1)
getAdvancedGenre(7-14)src/lib/api/advanced-genres.ts (1)
getAdvancedGenre(7-14)
src/components/genres-tree-chart/client.tsx (1)
src/types/genre.ts (1)
GenreNode(13-20)
src/app/[locale]/page.tsx (2)
src/lib/api/genres.ts (1)
getHomepageAdvancedGenres(16-23)src/lib/urls.ts (1)
navigation(4-61)
🔇 Additional comments (44)
locales/ha/home.json (1)
6-8: Valid JSON structure with consistent key naming across all language files.The additions follow the established kebab-case convention and maintain proper JSON syntax. The structural change from a single
collectionskey to three granular collection types (genres,special-collections,individual-collections) has been consistently applied across all 14 language files.Verification confirms that all 14 language translations (ar, bn, en, es, fa, fr, ha, hi, ms, ps, ru, so, tr, ur) include the same three new keys with appropriate semantic alignment. Note: the PR summary mentions 12 languages, but the repository actually contains 14 language files, all of which have been updated consistently.
src/components/cloudflare-image.tsx (1)
22-24: LGTM! Hydration warning suppression applied.The addition of
suppressHydrationWarningis consistent with the broader pattern in this PR to address SSR/hydration mismatches. This is a valid React 19 feature for cases where hydration differences are expected and acceptable (e.g., timestamps, client-specific content).locales/ms/common.json (1)
245-247: LGTM! Localization keys added correctly.The new
expand-allandcollapse-allkeys are properly structured and translated for the Malay locale, consistent with the pattern across other locale files in this PR.src/components/navbar/profile-dropdown.tsx (1)
74-79: LGTM! Hydration warning suppression applied to dropdown trigger.The addition of
suppressHydrationWarningto the dropdown trigger Button is consistent with the broader pattern in this PR for addressing SSR/hydration mismatches in interactive UI components.locales/bn/common.json (1)
245-247: LGTM! Localization keys added correctly.The new
expand-allandcollapse-allkeys are properly structured and translated for the Bengali locale, consistent with the pattern across other locale files in this PR.locales/so/home.json (1)
6-8: LGTM! Sections refactored to support new genre structure.The replacement of the
collectionskey with three more specific keys (genres,special-collections,individual-collections) aligns with the broader genre-centric refactoring described in the PR summary. The Somali translations are properly structured.locales/ur/common.json (1)
245-247: LGTM! Localization keys added correctly.The new
expand-allandcollapse-allkeys are properly structured and translated for the Urdu locale, consistent with the pattern across other locale files in this PR.src/hooks/use-global-chat.ts (2)
99-101: Variable renamed to align with advanced genres refactoring.The renaming from
genreIdstoadvancedGenreIdsis consistent with the broader genre refactoring mentioned in the PR summary.
102-109: Ensure backend API endpoint has been updated to acceptadvancedGenreIds.The frontend correctly sends
advancedGenreIdsin the request body to/chat/multi. However, backend compatibility cannot be verified from this frontend-only repository. Coordinate with the backend team to confirm the external API service accepts this field name.locales/ps/common.json (1)
246-247: Locale addition looks good.The new "expand-all" and "collapse-all" keys follow the consistent pattern across other locales and are properly formatted with valid JSON syntax.
locales/ha/common.json (1)
246-247: Locale addition looks good.The new "expand-all" and "collapse-all" keys are properly formatted with correct Hausa translations and valid JSON syntax.
locales/ps/home.json (1)
6-8: Verify UI components have been updated for section restructuring.The "collections" key has been split into three granular keys ("genres", "special-collections", "individual-collections"), which represents a structural change. Please verify that all components referencing the old "collections" key in the home section have been updated to use the appropriate new keys.
locales/fa/common.json (1)
246-247: Locale addition looks good, but verify existing control characters.The new "expand-all" and "collapse-all" keys are properly formatted. However, the file contains suspicious escape sequences at lines 88 and 130 (
\u0006and\f), which appear to be unintended control characters. These should be verified and corrected before merge.locales/hi/common.json (1)
246-247: Locale addition looks good.The new "expand-all" and "collapse-all" keys are properly formatted with correct Hindi translations and valid JSON syntax.
locales/fr/common.json (1)
246-247: Locale addition looks good.The new "expand-all" and "collapse-all" keys are properly formatted with correct French translations and valid JSON syntax.
locales/so/common.json (1)
246-247: Locale addition looks good.The new "expand-all" and "collapse-all" keys are properly formatted with correct Somali translations and valid JSON syntax.
locales/es/common.json (1)
246-247: Locale addition looks good.The new "expand-all" and "collapse-all" keys are properly formatted with correct Spanish translations and valid JSON syntax.
locales/bn/home.json (1)
5-8: Bengali sections now aligned with new genres/collections structureKeys
genres,special-collections, andindividual-collectionslook consistent with the English source and maintain the existing JSON structure. No issues from an i18n/structure perspective.locales/tr/common.json (1)
245-247: Turkish expand/collapse strings look good; ensure base English keys exist
"expand-all": "Tümünü genişlet"and"collapse-all": "Tümünü daralt"are clear and placed correctly. Just double‑check that the same keys exist inlocales/en/common.jsonso English remains the canonical source, per the i18n guideline for new strings.locales/ru/common.json (1)
245-247: Russian expand/collapse translations are clear and well‑placed
"Развернуть все"/"Свернуть все"match the intended UI behavior and the JSON object remains valid. No further changes needed here.locales/en/home.json (1)
5-8: Base English home sections updated correctly for genresReplacing the old
sections.collectionswithsections.genres: "Featured Genres"keeps the structure consistent with other locales and with the new genre‑focused UI. No structural or wording issues from this change.src/components/ui/select/index.tsx (1)
10-11: Targeted hydration warnings suppression for Radix Select looks reasonableAdding
suppressHydrationWarningtoSelectPrimitive.TriggerandSelectPrimitive.Contentshould help mask known SSR/client mismatches around the Radix portal without changing Select behavior, and the icon fallback refactor is a no‑op logically. Assuming this was driven by concrete hydration warnings, the changes look good.Also applies to: 33-41, 44-51, 93-120
locales/tr/home.json (1)
5-8: Turkish home sections updated to new genres/collections splitThe new
genres,special-collections, andindividual-collectionskeys mirror the English structure and the wording is appropriate for the UI. No issues spotted.locales/hi/home.json (1)
5-8: Hindi home sections follow the new genres/collections patternThe added
genres,special-collections, andindividual-collectionsentries match the new homepage sections schema and keep the JSON well‑formed. Looks good.locales/es/home.json (1)
5-8: Spanish home sections correctly split into genres and collections
"Géneros Destacados","Colecciones especiales", and"Colecciones individuales"align with the updated sections model and fit naturally in the existing copy. No changes requested.locales/ur/home.json (1)
6-8: LGTM! Translation keys are well-structured.The expansion from a single "collections" key to three distinct section keys (genres, special-collections, individual-collections) aligns with the broader refactoring visible across all locale files in this PR.
src/lib/api/genres.ts (1)
16-23: LGTM! New API function follows established patterns.The
getHomepageAdvancedGenresfunction correctly mirrors the existinggetHomepageGenresimplementation, uses the cache wrapper, and has proper typing.src/components/ui/command/index.tsx (1)
20-20: Verify hydration warnings before suppressing them.Three
suppressHydrationWarningprops have been added to Command components. This is part of a broader pattern across the PR affecting multiple UI components. Ensure these address actual, documented hydration mismatches rather than masking underlying problems.Consider documenting why these components experience hydration mismatches in a comment or ADR.
Also applies to: 61-61, 73-73
src/components/ui/navigation-menu.tsx (2)
21-21: Verify hydration warnings before suppressing them.Similar to other UI components in this PR,
suppressHydrationWarninghas been added to navigation menu primitives. Ensure these address actual, documented hydration mismatches.Also applies to: 62-62
12-12: LGTM! Active state management looks good.The active state tracking and conditional viewport translation based on menu position is well-implemented.
Also applies to: 25-31
src/components/navbar/locale-switcher.tsx (1)
28-32: RemovesuppressHydrationWarningunless a confirmed hydration mismatch has been verified.The locale name displayed by
getLocaleFullName(selectedLocale)should be deterministic based onuseLocale(), which returns the same value on server and client (derived from the URL segment[locale]). Other components in the codebase useuseLocale()without suppressing hydration warnings—for example,src/components/footer/index.tsxandsrc/app/[locale]/t/[bookId]/_components/coming-soon-alert.tsxapplyuseLocale()values to attributes likedirwithout the suppression flag.If there is a genuine hydration mismatch, add a comment explaining why and what the actual mismatch is. If no mismatch exists, remove the suppression.
src/app/[locale]/(entityPages)/author/[authorSlug]/page.tsx (1)
86-97: Advanced genres filter wiring looks consistent; just confirm backend expectsadvancedGenresMapping
genresfromsearchParamsintofilters.advancedGenresaligns with the rest of the advanced genres refactor and keepsGenresFilterin sync viacurrentGenres={genres}. Please just confirm thatsearchBooksand the underlying search API now readadvancedGenresrather than the oldgenresfield so filters are actually applied.locales/ms/home.json (1)
5-8: New section keys align with the updated homepage structureThe added
genres,special-collections, andindividual-collectionskeys match the new homepage sections used in code and keep the JSON structure consistent. No issues from an i18n/structure standpoint.locales/ar/common.json (1)
245-247: Expand/collapse labels are correctly added and namedThe new
expand-all/collapse-allkeys match the expected UI control names and integrate cleanly at the root ofcommon.jsonwithout affecting existing structure.locales/ar/home.json (1)
5-8: Sections JSON matches the new genres-based homepage layoutSwitching from a single
collectionslabel togenres,special-collections, andindividual-collectionsmirrors the new UI structure and keeps Arabic home translations in sync with code and other locales.src/app/[locale]/page.tsx (1)
133-147: Homepage genres now correctly use the advanced genres API and genres navigationUsing
getHomepageAdvancedGenres({ locale: pathLocale })and wiring the section throughtitle={t("home.sections.genres")},href={navigation.genres.all()}, andhref={navigation.genres.bySlug(genre.slug)}keeps the homepage fully aligned with the new advanced genres flow and URL contract. The(genres || []).map(...)pattern safely handles missing data as well.Also applies to: 185-203
src/lib/urls.ts (1)
28-34: Simplifiedgenres.bySlugis verified—all call sites use the new signatureThe updated
navigation.genres.bySlug(genreSlug)implementation returning/genre/${genreSlug}is correct. All 10 call sites across the codebase (global-search.ts, genre-search-result.tsx, book-search-result/info-dialog.tsx, genres-tree-chart/client.tsx, sitemap route, homepage, book-info, search results, and genre page) correctly pass only the slug parameter with no options object orfromHomepageparameter. The simplification is complete and consistent.src/app/[locale]/(entityPages)/genre/[genreSlug]/page.tsx (1)
30-34: LGTM! Clean simplification to single API call.The refactor consolidates genre fetching to use
getAdvancedGenreconsistently, removing the previous conditional logic and fallback patterns. The filters now correctly useadvancedGenres: [genre.id].Also applies to: 55-59, 71-71
src/components/genres-filter/client.tsx (2)
361-370: LGTM! Display logic correctly usesprimaryName.The rendering now properly accesses
genre.primaryNamewhich aligns with the importedGenreNodetype definition.
3-3: Type import and interface update look correct.The
GenreNodetype import and its usage inGenresFilterProps.hierarchyproperly centralizes the type definition.Also applies to: 16-19
src/components/genres-tree-chart/client.tsx (3)
15-17: LGTM! Strong typing improvement.Replacing
any[]withGenreNode[]improves type safety. The root node structure correctly usesprimaryNameto match theGenreNodetype.Also applies to: 82-86
353-368: LGTM! Multi-line label rendering correctly implemented.The
data-labeluses double newlines (\n\n) for visual separation in the wrapped output, while the initialtextuses single newlines. ThewrapTextfunction properly handles both cases.
159-161: Box dimensions and font sizing adjustments look reasonable.The increased
boxHeight(100) and adjusted padding accommodate the new multi-line primary/secondary name display. The minimum font size of 6px is small but acceptable as a fallback for long names.Also applies to: 376-378
src/app/api/og/genre/[slug]/route.tsx (1)
5-5: LGTM! Simplified to single API call.The refactor cleanly removes conditional logic, using
getAdvancedGenreas the single source. The unused_requestparameter is correctly prefixed with underscore. Thegenre.nameproperty at line 50 is valid—ApiGenreis explicitly typed with aname: stringfield.
| "lucide-react": "^0.503.0", | ||
| "nanoid": "^5.0.9", | ||
| "next": "16.0.1", | ||
| "next": "16.0.7", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
npm view [email protected] version 2>&1 || npm view next versions --json | jq '.[] | select(startswith("16.0"))'Repository: seemorg/usul
Length of output: 62
🌐 Web query:
Next.js 16.0.7 release stable version
💡 Result:
Yes — Next.js 16.0.7 is a stable security patch released on December 3, 2025 (it fixes CVE-2025-66478). Upgrade to [email protected] as recommended. [1][2][3]
Sources:
[1] Next.js security advisory (CVE-2025-66478) — nextjs.org/blog/CVE-2025-66478.
[2] Next.js GitHub security issue/discussion confirming patched versions.
[3] Release/patch listings (endoflife.date / third‑party advisories noting 16.0.7).
🌐 Web query:
Next.js version 16 release date breaking changes
💡 Result:
Release date
- Next.js 16 was released October 21, 2025. [1]
Key breaking changes (most important)
- Async Request APIs: synchronous access removed — cookies(), headers(), draftMode(), params and searchParams are now async (must be awaited / used in async components). [2][1]
- Node / TypeScript minimums: Node.js >= 20.9.0 and TypeScript >= 5.x required. [1][2]
- middleware.ts → proxy.ts: edge middleware renamed to clarify network boundary. [1][2]
- Cache/Rendering model changes: new Cache Components / "use cache" and default dynamic-at-request-time behavior that changes caching semantics (may require opt-in / migration). [1][3]
- Removed/deprecated features: AMP support removed; some legacy imports/APIs (legacy image import, publicRuntimeConfig/serverRuntimeConfig, etc.) removed. [1][5]
- CLI/config changes: next lint removed as a built-in command; flat config defaults and other config/CLI changes. [6][1]
- API changes: revalidateTag() signature updated (now requires cacheLife profile for SWR behavior) and other stabilized APIs removed "unstable_" prefixes. [2][1]
Migration help
- Official upgrade guide and automated codemod: npx @next/codemod@canary upgrade latest; see the Next.js upgrade docs for step-by-step changes and typegen helpers. [2][1]
Sources
- Next.js blog — “Next.js 16” (Oct 21, 2025). [1]
- Next.js docs — “Upgrading: Version 16” (upgrade guide / breaking changes). [2]
- InfoQ summary of Next.js 16 release. [3]
Update Next.js to 16.0.7 requires addressing breaking changes.
Next.js 16.0.7 is a stable security patch (released December 3, 2025, fixing CVE-2025-66478). However, the upgrade from Next.js 15.x introduces major breaking changes that require code migration:
- Request APIs (
cookies(),headers(),draftMode(),params,searchParams) are now async and must be awaited - Requires Node.js >= 20.9.0 and TypeScript >= 5.x
middleware.tsrenamed toproxy.ts- Cache/rendering model changes with "use cache" directive
- Various legacy APIs removed (AMP support,
publicRuntimeConfig/serverRuntimeConfig, etc.) revalidateTag()signature updated
Verify the codebase handles these changes. Use npx @next/codemod@canary upgrade latest to assist with migration, and review the official Next.js upgrade guide for step-by-step migration details.
🤖 Prompt for AI Agents
In package.json around line 55 (the Next.js version bump to "next": "16.0.7"),
update the repo to be compatible with Next.js 16 by: bumping engines to Node
>=20.9.0 and TypeScript >=5.x in package.json; running npx @next/codemod@canary
upgrade latest to auto-apply migration transforms; search and update all uses of
request APIs (cookies(), headers(), draftMode(), params, searchParams) to await
the async versions; rename any middleware.ts to proxy.ts and adjust
imports/exports; audit rendering/cache directives and add "use cache" or other
new directives where needed; update calls to revalidateTag() to the new
signature; remove or replace deprecated legacy APIs (AMP,
publicRuntimeConfig/serverRuntimeConfig, etc.); then reinstall deps, run
typechecks and full test suite, and fix any remaining type or runtime errors
reported.
| const DropdownMenuTrigger = ({ | ||
| ...props | ||
| }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) => ( | ||
| <DropdownMenuPrimitive.Trigger suppressHydrationWarning {...props} /> | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n src/components/ui/dropdown-menu/index.tsxRepository: seemorg/usul
Length of output: 7473
🏁 Script executed:
rg "DropdownMenuTrigger" -A 3 -B 1 --type tsx --type tsRepository: seemorg/usul
Length of output: 83
🏁 Script executed:
rg "DropdownMenuTrigger" -A 3 -B 1 --type typescriptRepository: seemorg/usul
Length of output: 90
🏁 Script executed:
rg "DropdownMenuTrigger" -A 3 -B 1Repository: seemorg/usul
Length of output: 10045
🏁 Script executed:
cd src/components/ui/dropdown-menu && git log --oneline -20 index.tsxRepository: seemorg/usul
Length of output: 105
🏁 Script executed:
git log --all --oneline -- src/components/ui/dropdown-menu/index.tsx | head -20Repository: seemorg/usul
Length of output: 583
🏁 Script executed:
git show 5c7ce64:src/components/ui/dropdown-menu/index.tsx | head -50Repository: seemorg/usul
Length of output: 1835
🏁 Script executed:
git show 5c7ce64:src/components/ui/dropdown-menu/index.tsx | grep -A 15 "DropdownMenuContent"Repository: seemorg/usul
Length of output: 1173
Wrap DropdownMenuTrigger and DropdownMenuContent with forwardRef to preserve ref forwarding
The change from a direct alias (const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;) to a plain function component breaks ref forwarding. While current usages in the codebase use asChild (which bypasses this), converting to a plain function component removes the ability for consumers to pass refs directly to these components, which is a breaking API change.
To maintain backward compatibility and preserve the public API:
-const DropdownMenuTrigger = ({
- ...props
-}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) => (
- <DropdownMenuPrimitive.Trigger suppressHydrationWarning {...props} />
-);
+const DropdownMenuTrigger = React.forwardRef<
+ React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>
+>((props, ref) => (
+ <DropdownMenuPrimitive.Trigger
+ ref={ref}
+ suppressHydrationWarning
+ {...props}
+ />
+));
+
+DropdownMenuTrigger.displayName =
+ DropdownMenuPrimitive.Trigger.displayName ?? "DropdownMenuTrigger";Apply the same pattern to DropdownMenuContent (lines 57–74) to ensure consistent ref forwarding behavior across all exported components.
📝 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.
| const DropdownMenuTrigger = ({ | |
| ...props | |
| }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) => ( | |
| <DropdownMenuPrimitive.Trigger suppressHydrationWarning {...props} /> | |
| ); | |
| const DropdownMenuTrigger = React.forwardRef< | |
| React.ElementRef<typeof DropdownMenuPrimitive.Trigger>, | |
| React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger> | |
| >((props, ref) => ( | |
| <DropdownMenuPrimitive.Trigger | |
| ref={ref} | |
| suppressHydrationWarning | |
| {...props} | |
| /> | |
| )); | |
| DropdownMenuTrigger.displayName = | |
| DropdownMenuPrimitive.Trigger.displayName ?? "DropdownMenuTrigger"; |
| "relative z-10 flex max-w-max flex-1 items-center justify-center", | ||
| className, | ||
| )} | ||
| onValueChange={(value) => (value ? setActive(Number(value)) : null)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the onValueChange handler logic.
The callback returns null instead of calling setActive(null) when the value is falsy. This means the active state won't be cleared when the menu closes.
Apply this diff:
- onValueChange={(value) => (value ? setActive(Number(value)) : null)}
+ onValueChange={(value) => setActive(value ? Number(value) : null)}📝 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.
| onValueChange={(value) => (value ? setActive(Number(value)) : null)} | |
| onValueChange={(value) => setActive(value ? Number(value) : null)} |
🤖 Prompt for AI Agents
In src/components/ui/navigation-menu.tsx around line 20, the onValueChange
handler currently returns null when value is falsy, so it never clears the
active state; change the handler to call setActive(null) when value is falsy and
call setActive(Number(value)) when truthy (or parse accordingly) so the active
state is cleared when the menu closes.
| export type GenreNode = { | ||
| id: string; | ||
| slug: string; | ||
| primaryName: string; | ||
| secondaryName: string; | ||
| numberOfBooks: number; | ||
| children?: GenreNode[]; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relax secondaryName and consider aligning count field naming
GenreNode.secondaryName is required here, whereas GenreDocument.secondaryName is optional. Unless the advanced genres API truly guarantees a secondary name for every node, this will either force callers to manufacture placeholder strings or fight the existing data model.
Also, GenreDocument uses booksCount while GenreNode uses numberOfBooks. The semantic difference may be intentional (e.g., total vs. direct children), but if they refer to the same concept it’s worth unifying to avoid confusion when mapping between the two.
Suggested minimal change:
-export type GenreNode = {
- id: string;
- slug: string;
- primaryName: string;
- secondaryName: string;
- numberOfBooks: number;
- children?: GenreNode[];
-};
+export type GenreNode = {
+ id: string;
+ slug: string;
+ primaryName: string;
+ secondaryName?: string;
+ numberOfBooks: number;
+ children?: GenreNode[];
+};📝 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.
| export type GenreNode = { | |
| id: string; | |
| slug: string; | |
| primaryName: string; | |
| secondaryName: string; | |
| numberOfBooks: number; | |
| children?: GenreNode[]; | |
| }; | |
| export type GenreNode = { | |
| id: string; | |
| slug: string; | |
| primaryName: string; | |
| secondaryName?: string; | |
| numberOfBooks: number; | |
| children?: GenreNode[]; | |
| }; |
🤖 Prompt for AI Agents
In src/types/genre.ts around lines 13 to 20, make GenreNode.secondaryName
optional to match GenreDocument and rename numberOfBooks to booksCount (and keep
its type) so the two types align; update the children type accordingly
(children?: GenreNode[]) and ensure any call sites mapping between GenreDocument
and GenreNode use booksCount consistently.
Auto-generated from by github action
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.