-
Notifications
You must be signed in to change notification settings - Fork 0
fix: only load necessary translations #802
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
base: main
Are you sure you want to change the base?
Conversation
commit: |
WalkthroughThis PR reorganizes localization into a two-tier layout: Sequence Diagram(s)sequenceDiagram
participant Template as Template (main/locator/directory/dev)
participant Transform as transformProps
participant Inject as injectTranslations()
participant GetComp as getTranslations (components)
participant I18nComp as i18nComponentsInstance
Template->>Transform: receives TemplateProps
Transform->>Inject: call with templateProps
Inject->>Inject: extract document.locale
Inject->>GetComp: request component translations for locale
GetComp->>GetComp: dynamic import locales/components/<lng>/visual-editor.json
alt import succeeds
GetComp-->>Inject: return translations
else import fails
GetComp->>GetComp: retry with "en"
GetComp-->>Inject: return fallback translations
end
Inject->>I18nComp: loadComponentTranslations(locale, translations)
I18nComp->>I18nComp: merge resources
Inject-->>Transform: return augmented props
Transform-->>Template: enriched TemplateProps
sequenceDiagram
participant Editor as Editor.tsx
participant Meta as templateMetadata (platformLocale)
participant LoadPlat as loadPlatformTranslations()
participant I18nPlat as i18nPlatformInstance
Editor->>Meta: check platformLocale
alt platformLocale exists
Editor->>LoadPlat: call with platformLocale
LoadPlat->>LoadPlat: dynamic import locales/platform/<lng>/<ns>.json
LoadPlat->>I18nPlat: inject translations
LoadPlat-->>Editor: done
Editor->>I18nPlat: changeLanguage(platformLocale)
else platformLocale absent
Editor->>I18nPlat: changeLanguage(locale)
end
sequenceDiagram
participant Scanner as i18next-scanner
participant FS as Filesystem
note right of Scanner: scanner config updated to platform path
Scanner->>FS: loadPath/savePath -> locales/platform/{{lng}}/{{ns}}.json
FS-->>Scanner: read/write platform-scoped JSONs
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🔇 Additional comments (2)
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 18
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/visual-editor/src/utils/VisualEditorProvider.tsx (1)
44-52: Race condition: translations may not load before language change.
loadComponentTranslationsis async but not awaited (line 45). WhennormalizedTemplateProps?.translationsis undefined, the function will asynchronously fetch translations viagetTranslations(), buti18nComponentsInstance.changeLanguage()executes immediately on line 49 without waiting. This can cause the language to change before translations are available, resulting in missing or fallback text.Consider one of these solutions:
Option 1: Await inside useEffect
+ React.useEffect(() => { if (normalizedTemplateProps?.document?.locale) { - loadComponentTranslations( + loadComponentTranslations( normalizedTemplateProps.document.locale, normalizedTemplateProps?.translations - ); - i18nComponentsInstance.changeLanguage( - normalizedTemplateProps.document.locale - ); + ).then(() => { + i18nComponentsInstance.changeLanguage( + normalizedTemplateProps.document.locale + ); + }); } + }, [normalizedTemplateProps?.document?.locale]);Option 2: Make the provider async-aware with state
+ const [translationsLoaded, setTranslationsLoaded] = React.useState(false); + + React.useEffect(() => { if (normalizedTemplateProps?.document?.locale) { - loadComponentTranslations( + loadComponentTranslations( normalizedTemplateProps.document.locale, normalizedTemplateProps?.translations - ); - i18nComponentsInstance.changeLanguage( - normalizedTemplateProps.document.locale - ); + ).then(() => { + i18nComponentsInstance.changeLanguage( + normalizedTemplateProps.document.locale + ); + setTranslationsLoaded(true); + }); } + }, [normalizedTemplateProps?.document?.locale]);
🧹 Nitpick comments (5)
packages/visual-editor/src/utils/i18n/fallbacks.ts (1)
31-31: Good refactor: removed redundant double negation.The truthiness check is cleaner without
!!while preserving the same behavior.starter/src/templates/dev.tsx (1)
131-135: Consider stronger typing for transformProps.The use of
TemplateProps<any>loses type safety. While this works, consider constraining the type parameter if the document structure is known, or at minimum usingTemplateProps<unknown>to signal the uncertainty.Example improvement:
-export const transformProps: TransformProps<TemplateProps<any>> = async ( +export const transformProps: TransformProps<TemplateProps<unknown>> = async ( data ) => { return await injectTranslations(data); };packages/visual-editor/src/vite-plugin/templates/locator.tsx (1)
1-1: Autogenerated file - consider updating generator for type safety.Line 1 indicates this is autogenerated. If
TemplateProps<any>at lines 95-99 is a concern, the fix should be applied to the template generator rather than this file.packages/visual-editor/src/utils/i18n/platform.ts (1)
22-53: Consider documenting race condition potential.While the
hasResourceBundlecheck inloadPlatformTranslationsprevents duplicate loading, concurrent calls with the same locale before the first completes could still cause race conditions. The error handling correctly falls back to "en", but this behavior should be documented.Consider adding a loading state map to prevent concurrent loads:
const loadingLocales = new Set<string>(); const getTranslations = async ( locale: string, isRetry = false ): Promise<Record<string, string>> => { if (!locale) { return {}; } // Wait if already loading while (loadingLocales.has(locale)) { await new Promise(resolve => setTimeout(resolve, 50)); } loadingLocales.add(locale); try { const module = await import( `../../../locales/platform/${locale}/visual-editor.json` ); return module.default; } catch (e) { // existing error handling... } finally { loadingLocales.delete(locale); } };packages/visual-editor/src/utils/i18n/components.ts (1)
81-94: Allow refreshing an existing resource bundleOnce a bundle for a locale exists, this early return prevents us from merging any new or overridden keys that arrive later (e.g., when
transformPropsstarts supplying additional strings). Dropping the guard and usingaddResourceBundle(..., true, true)keeps the fast path but still lets us refresh data when needed.export const loadComponentTranslations = async ( locale: string, translations?: Record<string, string> ) => { - if (i18nComponentsInstance.hasResourceBundle(locale, NAMESPACE)) { - return; - } - - const translationsToInject = translations || (await getTranslations(locale)); - - if (translationsToInject && Object.keys(translationsToInject).length > 0) { - i18nComponentsInstance.addResourceBundle( - locale, - NAMESPACE, - translationsToInject - ); - } + const translationsToInject = + translations ?? (await getTranslations(locale)); + + if (!translationsToInject || Object.keys(translationsToInject).length === 0) { + return; + } + + i18nComponentsInstance.addResourceBundle( + locale, + NAMESPACE, + translationsToInject, + true, + i18nComponentsInstance.hasResourceBundle(locale, NAMESPACE) + ); };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (43)
packages/visual-editor/i18next-scanner.config.cjs(1 hunks)packages/visual-editor/locales/components/cs/visual-editor.json(1 hunks)packages/visual-editor/locales/components/da/visual-editor.json(1 hunks)packages/visual-editor/locales/components/de/visual-editor.json(1 hunks)packages/visual-editor/locales/components/en-GB/visual-editor.json(1 hunks)packages/visual-editor/locales/components/en/visual-editor.json(1 hunks)packages/visual-editor/locales/components/es/visual-editor.json(1 hunks)packages/visual-editor/locales/components/et/visual-editor.json(1 hunks)packages/visual-editor/locales/components/fi/visual-editor.json(1 hunks)packages/visual-editor/locales/components/fr/visual-editor.json(1 hunks)packages/visual-editor/locales/components/hr/visual-editor.json(1 hunks)packages/visual-editor/locales/components/hu/visual-editor.json(1 hunks)packages/visual-editor/locales/components/it/visual-editor.json(1 hunks)packages/visual-editor/locales/components/ja/visual-editor.json(1 hunks)packages/visual-editor/locales/components/lt/visual-editor.json(1 hunks)packages/visual-editor/locales/components/lv/visual-editor.json(1 hunks)packages/visual-editor/locales/components/nb/visual-editor.json(1 hunks)packages/visual-editor/locales/components/nl/visual-editor.json(1 hunks)packages/visual-editor/locales/components/pl/visual-editor.json(1 hunks)packages/visual-editor/locales/components/pt/visual-editor.json(1 hunks)packages/visual-editor/locales/components/ro/visual-editor.json(1 hunks)packages/visual-editor/locales/components/sk/visual-editor.json(1 hunks)packages/visual-editor/locales/components/sv/visual-editor.json(1 hunks)packages/visual-editor/locales/components/tr/visual-editor.json(1 hunks)packages/visual-editor/locales/components/zh-TW/visual-editor.json(1 hunks)packages/visual-editor/locales/components/zh/visual-editor.json(1 hunks)packages/visual-editor/scripts/checkEmptyTranslations.ts(1 hunks)packages/visual-editor/scripts/generateTranslations.ts(5 hunks)packages/visual-editor/scripts/sortTranslations.ts(2 hunks)packages/visual-editor/src/editor/Editor.tsx(2 hunks)packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx(3 hunks)packages/visual-editor/src/utils/VisualEditorProvider.tsx(2 hunks)packages/visual-editor/src/utils/i18n/components.ts(1 hunks)packages/visual-editor/src/utils/i18n/fallbacks.ts(1 hunks)packages/visual-editor/src/utils/i18n/index.ts(1 hunks)packages/visual-editor/src/utils/i18n/platform.ts(3 hunks)packages/visual-editor/src/utils/resolveComponentData.tsx(1 hunks)packages/visual-editor/src/utils/resolveYextEntityField.ts(1 hunks)packages/visual-editor/src/vite-plugin/plugin.ts(1 hunks)packages/visual-editor/src/vite-plugin/templates/directory.tsx(3 hunks)packages/visual-editor/src/vite-plugin/templates/locator.tsx(3 hunks)packages/visual-editor/src/vite-plugin/templates/main.tsx(3 hunks)starter/src/templates/dev.tsx(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (9)
packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx (2)
packages/visual-editor/src/utils/i18n/components.ts (2)
loadComponentTranslations(77-94)i18nComponentsInstance(6-6)packages/visual-editor/src/utils/i18n/platform.ts (2)
loadPlatformTranslations(58-73)i18nPlatformInstance(7-7)
packages/visual-editor/src/vite-plugin/templates/locator.tsx (4)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (1)
transformProps(96-100)packages/visual-editor/src/vite-plugin/templates/main.tsx (1)
transformProps(97-101)starter/src/templates/dev.tsx (1)
transformProps(131-135)packages/visual-editor/src/utils/i18n/components.ts (1)
injectTranslations(22-34)
packages/visual-editor/scripts/generateTranslations.ts (1)
scripts/releaseUtils.ts (1)
isDryRun(17-17)
starter/src/templates/dev.tsx (4)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (1)
transformProps(96-100)packages/visual-editor/src/vite-plugin/templates/locator.tsx (1)
transformProps(95-99)packages/visual-editor/src/vite-plugin/templates/main.tsx (1)
transformProps(97-101)packages/visual-editor/src/utils/i18n/components.ts (1)
injectTranslations(22-34)
packages/visual-editor/src/vite-plugin/templates/main.tsx (4)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (1)
transformProps(96-100)packages/visual-editor/src/vite-plugin/templates/locator.tsx (1)
transformProps(95-99)starter/src/templates/dev.tsx (1)
transformProps(131-135)packages/visual-editor/src/utils/i18n/components.ts (1)
injectTranslations(22-34)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (4)
packages/visual-editor/src/vite-plugin/templates/locator.tsx (1)
transformProps(95-99)packages/visual-editor/src/vite-plugin/templates/main.tsx (1)
transformProps(97-101)starter/src/templates/dev.tsx (1)
transformProps(131-135)packages/visual-editor/src/utils/i18n/components.ts (1)
injectTranslations(22-34)
packages/visual-editor/src/utils/VisualEditorProvider.tsx (1)
packages/visual-editor/src/utils/i18n/components.ts (1)
loadComponentTranslations(77-94)
packages/visual-editor/src/editor/Editor.tsx (1)
packages/visual-editor/src/utils/i18n/platform.ts (2)
loadPlatformTranslations(58-73)i18nPlatformInstance(7-7)
packages/visual-editor/src/utils/i18n/platform.ts (1)
packages/visual-editor/src/utils/i18n/fallbacks.ts (2)
applyI18nFallbacks(26-39)defaultI18nFallbacks(6-15)
🔇 Additional comments (30)
packages/visual-editor/locales/components/sk/visual-editor.json (1)
1-14: JSON structure and Slovak translations look good.The file is properly formatted and contains semantically appropriate translations for location/business hours status indicators and weekday names. The nested directory structure (
locales/components/sk/) aligns with the PR's goal of supporting granular, dynamic translation loading.Verify that this locale file is properly integrated into the new
loadComponentTranslations()runtime loading function so it's only bundled and loaded when the Slovak locale is needed.packages/visual-editor/locales/components/zh-TW/visual-editor.json (1)
1-14: Locale resource file looks good.The JSON structure is valid, all keys are present with non-empty translations, and the camelCase naming convention is consistent with typical i18n patterns. The translations cover status states and day-of-week labels as expected.
One minor observation:
"closed"and"closesAt"both map to the same translation"關閉". This is likely intentional, but if they should convey slightly different meanings in the UI, consider whether separate translations are needed.packages/visual-editor/locales/components/da/visual-editor.json (1)
1-14: JSON structure is valid and properly integrated into the new locale hierarchy.The file is well-formed, contains 12 UI translation keys for Danish, and correctly uses the new
locales/components/{locale}/visual-editor.jsonpath structure as part of the runtime translation loading system. Danish characters are properly encoded.packages/visual-editor/locales/components/nl/visual-editor.json (1)
1-14: JSON structure and formatting are valid.The translation file is properly formatted JSON with no syntax errors. However, I cannot verify the accuracy of Dutch translations or completeness of the key set without examining reference locale files or domain expertise.
Consider running the following to verify consistency with other locale files:
- Ensure all keys in this file match those in companion locale files (e.g.,
en/visual-editor.json)- Have Dutch translations reviewed by a native speaker or translation expert to confirm accuracy
- Verify that the key order is intentional or apply consistent alphabetical sorting across all locale files
packages/visual-editor/src/utils/resolveComponentData.tsx (1)
4-7: LGTM! Type-only imports correctly applied.Converting these imports to type-only is a good TypeScript practice that reduces the runtime bundle size. All four types (
RichText,TranslatableRichText,TranslatableString,YextEntityField) are used exclusively as type annotations throughout the file, making this change appropriate and aligned with the PR's goal of loading only necessary code.packages/visual-editor/src/utils/resolveYextEntityField.ts (1)
1-3: LGTM! Consistent type-only imports.The conversion to type-only imports is correct and follows the same pattern as the changes in
resolveComponentData.tsx. All three types (StreamDocument,YextEntityField,YextStructEntityField) are used exclusively for type annotations, making this refactor safe and beneficial for reducing the runtime bundle size.packages/visual-editor/locales/components/hu/visual-editor.json (1)
1-14: All required keys are present and consistent across locale files.The Hungarian locale file contains all required keys matching the English baseline (13 keys: location status and weekdays). The file is properly structured and integrated into the new two-tier locale hierarchy supporting granular component translation loading.
To complete validation, verify:
- Hungarian translations are accurate for the intended use context (location/hours display).
- The runtime
loadComponentTranslations()function properly loads and references this file.packages/visual-editor/locales/components/ro/visual-editor.json (1)
1-14: ✓ Translation key consistency verified.All 13 translation keys in the Romanian locale (closed, closesAt, friday, monday, open24Hours, openNow, saturday, sunday, temporarilyClosed, thursday, tuesday, wednesday) match exactly across all 25 locale files in the components namespace. The JSON structure is valid and properly formatted. No issues detected.
packages/visual-editor/locales/components/hr/visual-editor.json (1)
1-14: Translation content is accurate and properly integrated into the dynamic loading system.The Croatian locale file is correctly positioned at
packages/visual-editor/locales/components/hr/visual-editor.json, following the naming convention of all 24 other component translations. TheloadComponentTranslations()function dynamically imports component locales viaimport(\../../../locales/components/${locale}/visual-editor.json`)`, which correctly resolves to this file. The system uses runtime lazy loading—component translations are not processed by the i18next-scanner (which handles platform translations separately) but are loaded on-demand when the Croatian locale is selected, with automatic fallback to English if needed.packages/visual-editor/locales/components/nb/visual-editor.json (1)
1-14: Norwegian translations look reasonable.The translation keys and values are consistent with other locale files. The use of "Lukket" for closed status and "Åpent 24 timer" for 24-hour operation appears appropriate.
packages/visual-editor/locales/components/en/visual-editor.json (1)
1-14: English baseline translations are correct.All translations use appropriate grammatical forms for status indicators and are consistent across keys.
packages/visual-editor/src/vite-plugin/templates/directory.tsx (3)
12-12: LGTM: Required import added.The
TransformPropstype import is necessary for the newtransformPropsfunction.
27-27: LGTM: Translation injection utility imported.The
injectTranslationsimport enables runtime translation loading based on document locale.
96-100: LGTM: Translation injection follows established pattern.The
transformPropsimplementation correctly delegates toinjectTranslationsand matches the pattern used in other templates (locator.tsx, main.tsx). This enables dynamic loading of only the necessary translations for each locale, aligning with the PR objective.packages/visual-editor/locales/components/cs/visual-editor.json (1)
1-14: Czech translations look reasonable.The translations use appropriate grammatical forms. Note that "ZAVŘENO" (line 2) is in all caps, which may be intentional for emphasis on closed status.
packages/visual-editor/locales/components/et/visual-editor.json (1)
1-14: LGTM! Estonian translations are complete and properly localized.All required keys are translated and the structure is correct.
packages/visual-editor/locales/components/es/visual-editor.json (1)
1-14: LGTM! Spanish translations are complete and properly localized.All required keys are translated correctly.
packages/visual-editor/src/utils/i18n/index.ts (1)
1-1: LGTM! Export addition supports runtime translation injection.Adding
injectTranslationsto the public API aligns with the PR objective to load translations dynamically.packages/visual-editor/locales/components/pt/visual-editor.json (1)
1-14: LGTM! Portuguese translations are complete and properly localized.All required keys including weekdays are fully translated.
packages/visual-editor/locales/components/lv/visual-editor.json (1)
1-14: LGTM! Latvian translations are complete and properly localized.All required keys are fully translated.
packages/visual-editor/locales/components/en-GB/visual-editor.json (1)
1-14: LGTM!The UK English translations are correct and consistent with standard localization practices.
packages/visual-editor/src/vite-plugin/templates/main.tsx (1)
97-101: LGTM!The
transformPropsimplementation correctly awaits the asyncinjectTranslationscall and follows the same pattern used in other template files (directory.tsx, locator.tsx, dev.tsx). This ensures translations are loaded before template rendering.packages/visual-editor/locales/components/lt/visual-editor.json (1)
1-14: Structure looks good; verify translation accuracy.The JSON structure and formatting are correct. However, translation accuracy should be verified by a Lithuanian speaker to ensure the translations are natural and appropriate for the UI context.
packages/visual-editor/i18next-scanner.config.cjs (1)
55-56: LGTM! Path restructuring aligns with the two-tier locale hierarchy.The updated resource paths correctly scope translations under
locales/platform/, enabling separate handling of platform vs. component translations.packages/visual-editor/src/vite-plugin/plugin.ts (1)
154-158: LGTM! Cleanup now properly scoped to build mode.The conditional cleanup ensures generated files persist during dev mode while being cleaned up after builds. This aligns with the discussion in past review comments about
buildStartrunning for both server and build modes.packages/visual-editor/scripts/checkEmptyTranslations.ts (2)
15-50: LGTM! Improved resilience with two-tier structure support.The updated logic correctly handles the nested locale structure (
locales/<subfolder>/<locale>/visual-editor.json) and gracefully warns about missing files instead of failing. The two-tier traversal aligns with the PR's restructuring goals.
52-60: Good addition of explicit exit code handling.The post-processing check ensures the script exits with the correct code based on validation results, improving CI/CD integration.
packages/visual-editor/src/utils/i18n/platform.ts (2)
7-7: LGTM! Instance now exported for direct usage.Exporting
i18nPlatformInstanceenables components likeLayoutHeaderto directly control language changes after loading translations.
9-17: Good shift to runtime translation loading.Starting with empty resources and loading on-demand reduces bundle size and enables locale-specific loading, directly addressing the PR objective.
packages/visual-editor/scripts/sortTranslations.ts (1)
39-71: Add error handling around file I/O operations.The original review comment correctly identified missing error handling, but its structural assumptions do not match the actual directory layout. The locale structure is strictly
locales/{components,platform}/{language}/visual-editor.jsonwith no mixed-content directories or nested JSON files at intermediate levels. The algorithm handles this structure correctly.However, error handling is genuinely missing from file operations. Add try-catch blocks around
JSON.parse,fs.readFile, andfs.writeFile:if (file.isFile() && file.name.endsWith(".json")) { const filePath = path.join(fullPath, file.name); - const data = JSON.parse(await fs.readFile(filePath, "utf8")); - const sorted = sortObject(data); - await fs.writeFile( - filePath, - JSON.stringify(sorted, null, 2) + "\n" - ); + try { + const data = JSON.parse(await fs.readFile(filePath, "utf8")); + const sorted = sortObject(data); + await fs.writeFile( + filePath, + JSON.stringify(sorted, null, 2) + "\n" + ); + } catch (error) { + console.error(`Error processing ${filePath}:`, error); + throw error; + } }Likely an incorrect or invalid review comment.
| @@ -0,0 +1,14 @@ | |||
| { | |||
| "closed": "Geschlossen", | |||
| "closesAt": "Schließt bei", | |||
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.
Incorrect preposition for time expression.
"Schließt bei" uses "bei" (at a place), but for closing times in German, "um" (at a time) is the correct preposition.
Apply this diff:
- "closesAt": "Schließt bei",
+ "closesAt": "Schließt um",📝 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.
| "closesAt": "Schließt bei", | |
| "closesAt": "Schließt um", |
🤖 Prompt for AI Agents
In packages/visual-editor/locales/components/de/visual-editor.json around line
3, the German translation uses the incorrect preposition "Schließt bei" for a
time expression; replace the string value with "Schließt um" so the entry
becomes the correct time-based phrasing.
| @@ -0,0 +1,14 @@ | |||
| { | |||
| "closed": "Suljettu", | |||
| "closesAt": "Sulkeutuu jhk", | |||
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
Incomplete or incorrect translation.
"Sulkeutuu jhk" contains "jhk" which appears to be an abbreviation, placeholder, or typo rather than proper Finnish text. This needs to be verified and corrected with a complete translation.
Please verify this translation with a Finnish speaker or translation service.
I'll verify this translation issue by examining the file and researching the Finnish abbreviation.
🏁 Script executed:
#!/bin/bash
# Check if the file exists and examine its content
if [ -f "packages/visual-editor/locales/components/fi/visual-editor.json" ]; then
echo "=== File content (first 20 lines) ==="
head -20 "packages/visual-editor/locales/components/fi/visual-editor.json"
echo ""
echo "=== Full file content ==="
cat "packages/visual-editor/locales/components/fi/visual-editor.json"
else
echo "File not found"
fiLength of output: 772
🌐 Web query:
What does "jhk" mean in Finnish? Finnish abbreviations
💡 Result:
"jhk" is an informal/lexicographic abbreviation of johonkin ("to/to some place, to somewhere"). [1][2][3]
Fix incomplete Finnish translation for "closesAt".
The translation "Sulkeutuu jhk" uses the abbreviation "jhk" (short for "johonkin" meaning "to somewhere"), which is inappropriate in user-facing UI text and fails to convey the temporal meaning expected from a "closesAt" field. Replace with a complete, proper Finnish phrase that indicates closing time (e.g., "Sulkeutuu klo" or similar).
🤖 Prompt for AI Agents
In packages/visual-editor/locales/components/fi/visual-editor.json around line
3, the value for "closesAt" ("Sulkeutuu jhk") is an inappropriate abbreviation
and doesn't convey closing time; replace it with a proper Finnish phrase such as
"Sulkeutuu klo" (or "Päättyy klo") to clearly indicate a time, and ensure
spacing/punctuation matches the project's locale string style.
| "friday": "perjantai", | ||
| "monday": "maanantai", | ||
| "open24Hours": "Avoinna 24 tuntia", | ||
| "openNow": "Avoinna nyt", | ||
| "saturday": "Lauantai", | ||
| "sunday": "sunnuntai", | ||
| "temporarilyClosed": "Väliaikaisesti suljettu", | ||
| "thursday": "torstai", | ||
| "tuesday": "tiistai", | ||
| "wednesday": "keskiviikko" |
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.
Inconsistent capitalization in weekday names.
"Lauantai" (Saturday, line 8) is capitalized while all other weekday names are lowercase. Ensure consistent capitalization across all weekdays—either all lowercase or all capitalized, depending on Finnish localization conventions.
🤖 Prompt for AI Agents
In packages/visual-editor/locales/components/fi/visual-editor.json around lines
4 to 13, the weekday translations are inconsistent: "Lauantai" (line 8) is
capitalized while other weekdays are lowercase; update "Lauantai" to "lauantai"
(or normalize all weekday values to the chosen capitalization) so all weekday
strings follow the same lowercase convention.
| "open24Hours": "Ouvrir 24 heures", | ||
| "openNow": "Ouvrir maintenant", |
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.
Use adjective form for status indicators, not infinitive verbs.
Lines 6-7 use infinitive verb forms ("Ouvrir") which read as commands ("Open 24 hours", "Open now") rather than status descriptions. For UI status indicators, the adjective form "Ouvert" should be used instead.
Apply this diff:
- "open24Hours": "Ouvrir 24 heures",
- "openNow": "Ouvrir maintenant",
+ "open24Hours": "Ouvert 24h/24",
+ "openNow": "Ouvert actuellement",📝 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.
| "open24Hours": "Ouvrir 24 heures", | |
| "openNow": "Ouvrir maintenant", | |
| "open24Hours": "Ouvert 24h/24", | |
| "openNow": "Ouvert actuellement", |
🤖 Prompt for AI Agents
In packages/visual-editor/locales/components/fr/visual-editor.json around lines
6-7, the values use infinitive verbs ("Ouvrir 24 heures", "Ouvrir maintenant")
but should be adjective status labels; update those string values to "Ouvert 24
heures" and "Ouvert maintenant" respectively so the UI shows status descriptions
rather than commands.
| "closed": "Chiuso", | ||
| "closesAt": "Chiude a", | ||
| "friday": "Venerdì", | ||
| "monday": "Lunedi", |
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.
Missing accent in Italian weekday.
"Lunedi" should be "Lunedì" (with accent grave on the i).
Apply this diff:
- "monday": "Lunedi",
+ "monday": "Lunedì",🤖 Prompt for AI Agents
In packages/visual-editor/locales/components/it/visual-editor.json around line
5, the Italian weekday value is misspelled as "Lunedi"; replace it with the
correct accented form "Lunedì" (use grave accent on the i), ensure the JSON
string is properly quoted and the file saved with UTF-8 encoding so the accent
is preserved and the JSON remains valid.
| "friday": "Friday", | ||
| "monday": "Monday", |
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.
Complete the weekday translations.
The weekday names ("Friday", "Monday", "Saturday", "Sunday", "Thursday", "Tuesday", "Wednesday") are in English instead of Chinese. This creates an inconsistent localization experience compared to the properly translated status terms and other complete locale files (Estonian, Spanish, Portuguese, Latvian).
Consider translating the weekdays to Chinese:
- friday → "星期五"
- monday → "星期一"
- saturday → "星期六"
- sunday → "星期日"
- thursday → "星期四"
- tuesday → "星期二"
- wednesday → "星期三"
Also applies to: 8-9, 11-13
🤖 Prompt for AI Agents
In packages/visual-editor/locales/components/zh/visual-editor.json around lines
4–5 (and similarly lines 8–9 and 11–13), the weekday values are still in
English; replace them with the Chinese translations provided (friday → "星期五",
monday → "星期一", saturday → "星期六", sunday → "星期日", thursday → "星期四", tuesday →
"星期二", wednesday → "星期三") so the locale file is consistent; update each
corresponding key's value to the matching Chinese string and save the JSON
ensuring valid syntax.
packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx
Outdated
Show resolved
Hide resolved
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: 0
🧹 Nitpick comments (1)
packages/visual-editor/src/vite-plugin/plugin.ts (1)
151-158: Update the comment to reflect the new cleanup behavior.The comment at lines 95-96 states "Created files will be marked for deletion on buildEnd," but with the new conditional logic, files are only cleaned up on
buildEndduring build mode. In dev mode, cleanup is deferred to the SIGINT/SIGTERM handlers (lines 136-144).Apply this diff to update the comment:
/** * generateFiles generates the template files and .temlpate-manifest.json file * * Does not overwrite files that already exists * - * Created files will be marked for deletion on buildEnd + * Created files will be marked for deletion on buildEnd (build mode) or process termination (dev mode) */
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/visual-editor/src/utils/resolveYextEntityField.ts(1 hunks)packages/visual-editor/src/vite-plugin/plugin.ts(1 hunks)packages/visual-editor/src/vite-plugin/templates/directory.tsx(3 hunks)packages/visual-editor/src/vite-plugin/templates/locator.tsx(3 hunks)packages/visual-editor/src/vite-plugin/templates/main.tsx(3 hunks)starter/src/templates/dev.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- starter/src/templates/dev.tsx
- packages/visual-editor/src/vite-plugin/templates/main.tsx
- packages/visual-editor/src/utils/resolveYextEntityField.ts
- packages/visual-editor/src/vite-plugin/templates/locator.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (4)
packages/visual-editor/src/vite-plugin/templates/main.tsx (1)
transformProps(97-101)starter/src/templates/dev.tsx (1)
transformProps(133-137)packages/visual-editor/src/vite-plugin/templates/locator.tsx (1)
transformProps(95-99)packages/visual-editor/src/utils/i18n/components.ts (1)
injectTranslations(22-34)
🔇 Additional comments (1)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (1)
96-100: LGTM! Translation injection is correctly implemented.The
transformPropsimplementation correctly delegates toinjectTranslationsand is consistent with the pattern used in other template files (main.tsx, locator.tsx). This aligns with the PR objective to load only necessary translations based on the document locale.
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: 1
🧹 Nitpick comments (5)
packages/visual-editor/scripts/generateTranslations.ts (4)
64-84: Update TSDoc to document thetypeparameter.The ENOENT handling from the previous review has been correctly implemented. However, the function documentation doesn't describe the new
typeparameter.Apply this diff to complete the documentation:
/** - * Reads all directories under localesDir and returns them as target languages. + * Reads all directories under localesDir/{type} and returns them as target languages. + * @param type - The translation type to get languages for ("components" or "platform") + * @returns Array of language directory names, or empty array if type directory doesn't exist */ async function getTargetLanguages( type: "components" | "platform" ): Promise<string[]> {
194-198: Update TSDoc to document thetypeparameter.The function documentation doesn't describe the new
typeparameter.Apply this diff:
/** * Loads the base English translation file, compares it to each target language file, * translates missing or empty keys using Google Translate, and optionally writes them back. + * @param type - The translation type to process ("components" or "platform") */ async function translateFile(type: "components" | "platform"): Promise<void> {
256-256: Make error logging consistent with other log messages.All other log messages in this function use the
[${type}/${lng}]format, but this error log uses only[${lng}].Apply this diff:
} catch (e) { failCount++; - console.error(`[${lng}] ❌ Failed to translate key "${key}":`, e); + console.error(`[${type}/${lng}] ❌ Failed to translate key "${key}":`, e); }
273-274: Await translation promises to ensure proper completion and error handling.The script invokes both
translateFilecalls without awaiting them. While Node.js keeps the process alive for pending async operations, this pattern has drawbacks: if either translation fails, the error is logged but the process may exit with code 0, causing CI/CD pipelines to incorrectly report success.Apply this diff to run both in parallel with proper exit code handling:
-// Kick off the translation process -translateFile("components").catch(console.error); -translateFile("platform").catch(console.error); +(async () => { + try { + await Promise.all([ + translateFile("components"), + translateFile("platform") + ]); + } catch (error) { + console.error(error); + process.exit(1); + } +})();Or, if you prefer sequential execution:
-// Kick off the translation process -translateFile("components").catch(console.error); -translateFile("platform").catch(console.error); +(async () => { + try { + await translateFile("components"); + await translateFile("platform"); + } catch (error) { + console.error(error); + process.exit(1); + } +})();packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx (1)
224-239: Consider adding error handling for translation loading.The race conditions from previous reviews have been correctly addressed by making the handlers async and awaiting the translation loaders. However, for improved developer experience in local dev mode, consider adding error handling:
<Button onClick={async () => { const locale = prompt("Enter components locale:") || "en"; - await loadComponentTranslations(locale); - i18nComponentsInstance.changeLanguage(locale); + try { + await loadComponentTranslations(locale); + i18nComponentsInstance.changeLanguage(locale); + } catch (error) { + console.error('Failed to load component translations:', error); + alert(`Failed to load translations for locale: ${locale}`); + } }} variant="outline" className="ve-ml-4" > Set Components Locale </Button> <Button onClick={async () => { const locale = prompt("Enter platform locale:") || "en"; - await loadPlatformTranslations(locale); - i18nPlatformInstance.changeLanguage(locale); + try { + await loadPlatformTranslations(locale); + i18nPlatformInstance.changeLanguage(locale); + } catch (error) { + console.error('Failed to load platform translations:', error); + alert(`Failed to load translations for locale: ${locale}`); + } }} variant="outline" className="ve-ml-4" >
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/visual-editor/scripts/generateTranslations.ts(5 hunks)packages/visual-editor/src/editor/Editor.tsx(2 hunks)packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/visual-editor/src/editor/Editor.tsx (1)
packages/visual-editor/src/utils/i18n/platform.ts (2)
loadPlatformTranslations(58-73)i18nPlatformInstance(7-7)
packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx (2)
packages/visual-editor/src/utils/i18n/components.ts (2)
loadComponentTranslations(77-94)i18nComponentsInstance(6-6)packages/visual-editor/src/utils/i18n/platform.ts (2)
loadPlatformTranslations(58-73)i18nPlatformInstance(7-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: call_unit_test / unit_tests (18.x)
- GitHub Check: call_unit_test / unit_tests (20.x)
- GitHub Check: semgrep/ci
- GitHub Check: create-dev-release
🔇 Additional comments (2)
packages/visual-editor/src/editor/Editor.tsx (1)
19-22: LGTM! Imports correctly support the new translation loading flow.The addition of
loadPlatformTranslationsenables the pre-loading of platform translations before language changes.packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx (1)
16-19: LGTM! Imports correctly support the dev override buttons.The translation loading utilities are properly imported and enable the locale-switching functionality in
LocalDevOverrideButtons.Also applies to: 24-24
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.
Might want to update the .gitattributes so this isn't auto-collapsed in PRs
| "thursday": "Thursday", | ||
| "tuesday": "Tuesday", | ||
| "wednesday": "Wednesday" | ||
| } |
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.
I think this is missing some of component translations: searchThisArea for example from locator, openMenu from ExpandedHeader, etc.
Before this change all translations were bundled and ultimately loaded on the frontend even though only a single locale is ever needed at a time.