fix: only load necessary translations#802
Conversation
commit: |
WalkthroughMoves i18next scanner resource paths to locales/platform/{{lng}}/{{ns}}.json and splits translations into component and platform scopes (locales/components/ and locales/platform/). Adds many locale JSON resources. Introduces runtime translation loading and injection APIs (loadComponentTranslations, loadPlatformTranslations, injectTranslations) and updates consumers (Editor, VisualEditorProvider, LayoutHeader, Vite templates, starter) to preload/inject translations before changing language. Updates i18n tooling and scripts (generateTranslations, sortTranslations, fixPlurals, copy/delete scripts), adjusts Vite plugin hooks, and updates CI to run i18n:update. Sequence Diagram(s)sequenceDiagram
autonumber
participant Template as Vite template (transformProps)
participant Injector as injectTranslations
participant CompLoader as loadComponentTranslations
participant PlatLoader as loadPlatformTranslations
participant FS as File System (locales/components/, locales/platform/)
participant i18nC as i18nComponentsInstance
participant i18nP as i18nPlatformInstance
participant Editor as Editor / VisualEditorProvider
participant Renderer as Page Renderer
Template->>Injector: invoke injectTranslations(data, locale)
Injector->>CompLoader: request component translations for locale
CompLoader->>FS: read locales/components/<locale>/visual-editor.json
FS-->>CompLoader: return JSON (or fallback)
CompLoader->>i18nC: addResourceBundle("components", locale, translations)
Injector->>PlatLoader: request platform translations for locale
PlatLoader->>FS: read locales/platform/<locale>/visual-editor.json
FS-->>PlatLoader: return JSON (or fallback)
PlatLoader->>i18nP: addResourceBundle("platform", locale, translations)
Injector-->>Template: return augmented data with translations injected
Template->>Editor: provide augmented templateProps (preloaded translations)
Editor->>i18nC: changeLanguage(locale) / i18nP: changeLanguage(locale)
Editor->>Renderer: render localized UI using i18nComponentsInstance & i18nPlatformInstance
Possibly related PRs
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📜 Recent review detailsConfiguration used: Repository UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
⏰ 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). (5)
🔇 Additional comments (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 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.
packages/visual-editor/locales/components/it/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/zh/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
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.
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.
Actionable comments posted: 16
🤖 Fix all issues with AI agents
In @packages/visual-editor/locales/components/cs/visual-editor.json:
- Line 22: The "heroHeader" localization value is still in English; update the
"heroHeader" key in the Czech locale to a proper Czech translation (e.g.,
"Hlavní záhlaví") to match the translated style of sibling keys like
"heroBanner" and "heroImage" so the UI is consistent for Czech users.
- Around line 60-61: Update the Czech translations for the arrow keys: change
the value for "arrowRight" from "Šipka správně" to "Šipka vpravo" and change the
value for "arrowUp" from "Šipky" to "Šipka nahoru" so both keys ("arrowRight"
and "arrowUp") use the correct singular directional phrases consistent with
other arrow entries.
In @packages/visual-editor/locales/components/hr/visual-editor.json:
- Line 73: Replace the incorrect restaurant-related translation for the JSON key
"menu" (currently "Jelovnik") with the UI-consistent term used elsewhere
("izbornik") so the "menu" entry matches other menu translations in this locale
file.
In @packages/visual-editor/locales/components/it/visual-editor.json:
- Around line 35-36: The Italian pluralization for "mile" is incorrect: the key
"mile_other" currently maps to "miglio" but should be "miglia"; update the
translation so "mile_one" stays "miglio" and "mile_other" becomes "miglia" to
reflect correct singular/plural forms for the "mile" translation keys.
- Line 7: The translation for the key "buttonWithIcon" mixes English and
Italian; update its value to fully Italian by replacing "Button con icon
{{presetImageType}}" with "Pulsante con icona {{presetImageType}}" so the
localization string is consistent.
In @packages/visual-editor/locales/components/lt/visual-editor.json:
- Around line 31-36: The translation entries use inconsistent quotation marks
and one inconsistent word: update the keys locationsNear_one and
locationsWithinDistanceOf_{one,few,other} to use Lithuanian quotation marks
(„{{name}}“) to match locationsNear_few/other, and change locationsNear_one and
locationsWithinDistanceOf_one to use "šalia" instead of "prie" so all lines
consistently read e.g. "{{count}} vieta šalia „{{name}}“" and "{{count}} vieta
per {{distance}} {{mile}} nuo „{{name}}“" respectively.
- Around line 39-41: Add the missing Lithuanian plural key "mile_many" so the
plural set for "mile" includes mile_one, mile_few, mile_many, and mile_other;
add "mile_many": "mylių" to the JSON near the other mile_* entries and ensure
the surrounding commas keep the file valid JSON.
- Around line 31-33: Add the missing Lithuanian plural form key
"locationsNear_many" alongside the existing "locationsNear_one",
"locationsNear_few", and "locationsNear_other"; implement "locationsNear_many"
with the correct Lithuanian phrasing for counts ending in 0 or 10–19 (e.g., a
string like "{{count}} vietų šalia „{{name}}“") so all four plural variants are
present for the locationsNear message.
- Around line 34-36: Add the missing Lithuanian plural form key
"locationsWithinDistanceOf_many" to the JSON and set its value to the
appropriate string for numbers ending in 0 or 10–19 (use the same plural noun
form as in "locationsWithinDistanceOf_few/other"), e.g. "{{count}} vietovių per
{{distance}} {{mile}} nuo \"{{name}}\""; update the object to include this key
so all pluralization cases (one, few, many, other) are covered.
- Around line 112-114: Add the missing plural form by adding a
"totalReviews_many" key alongside the existing "totalReviews_one",
"totalReviews_few", and "totalReviews_other" entries; set its value to the same
Lithuanian pluralization string as "totalReviews_other" (i.e., use the same
"{{count}} atsiliepimų" text) so all required plural categories are present.
In @packages/visual-editor/locales/components/nb/visual-editor.json:
- Line 59: The JSON value for the "email" key contains an incorrect space ("E
-post"); update the value for the "email" key in visual-editor.json to the
correct Norwegian convention "e-post" (all lowercase, no space before the
hyphen) to fix the spacing and casing.
In @packages/visual-editor/locales/components/pt/visual-editor.json:
- Line 24: Update the three loading-state translation values to use the gerund
form for consistency: change the value for "loadingMap" from "Mapa de
carregamento ..." to a gerund phrase like "Carregando mapa...", ensure
"loadingNearby" remains or is changed to "Carregando locais próximos" (if not
already), and change "loadingRevs" / "loadingRevisions" from "Revisões de
carregamento" to "Carregando revisões" (use the actual key present in the file),
preserving punctuation and ellipses as used elsewhere.
In @packages/visual-editor/locales/platform/es/visual-editor.json:
- Around line 747-748: The singular translation key totalReviews_one uses the
wrong noun "revisión"; update totalReviews_one to use "reseña" to match
totalReviews_other (i.e., make it "{{count}} reseña") so singular and plural use
consistent terminology for user reviews; verify the plural form
totalReviews_other remains "{{count}} reseñas".
In @packages/visual-editor/locales/platform/hr/visual-editor.json:
- Line 598: Replace the incorrect Croatian translation for the "menu" key in the
visual-editor locale JSON (the "menu" entry currently set to "Jelovnik") with
the UI-appropriate term "Izbornik" so it matches other menu-related translations
in this locale file (e.g., the same "menu" concept used elsewhere on lines
referenced in the review).
In @packages/visual-editor/locales/platform/it/visual-editor.json:
- Around line 541-542: The Italian plural is incorrect: update the localization
entry for the keys "mile_one" and "mile_other" in visual-editor.json so that
"mile_one" remains "miglio" (singular) and "mile_other" is changed from "miglio"
to the correct plural "miglia".
In @packages/visual-editor/locales/platform/sv/visual-editor.json:
- Around line 536-537: The Swedish translation keys
locationsWithinDistanceOf_one and locationsWithinDistanceOf_other currently use
"mil" which in Swedish denotes 10 km; update these strings to either use "miles"
or "engelska mil" (e.g., replace "{{mile}}" with "miles" or "engelska mil") to
avoid ambiguity, or switch to metric wording (e.g., "{{distance}} km") and if
choosing metric update the distance unit conversion in the code paths that
populate the {{distance}}/{{mile}} variables (where these keys are used) so the
displayed number matches the unit change; apply the same change to the other
affected keys called out in the comment.
🧹 Nitpick comments (5)
packages/visual-editor/locales/components/cs/visual-editor.json (1)
14-14: Consider refining these translations for native fluency.A few translations could be more natural in Czech:
- Line 14: "Uzavírá" is incomplete for "closesAt"; consider "Uzavírá v" (closes at)
- Line 51: "Otevírá se na" is awkward; "Otevírá v" reads more naturally
- Line 97: "Rozbalovací vstup pro vyhledávání" doesn't quite match "Search dropdown here"; consider "Hledejte v rozbalovacím seznamu"
Also applies to: 51-51, 97-97
packages/visual-editor/locales/platform/ro/visual-editor.json (1)
655-663: Social media translations look good.The new
socialLinksobject provides Romanian translations for social media platform CTAs. The imperative mood ("Urmărește-ne pe..." / "Follow us on...") is appropriate, and the YouTube translation correctly uses "Abonați-vă" (Subscribe) rather than "Follow."Optional: Consider verification by a native Romanian speaker
Since these are new public-facing translations for social media CTAs, consider having them reviewed by a native Romanian speaker to ensure they align with your brand voice and local conventions, though they appear grammatically correct.
packages/visual-editor/locales/components/nb/visual-editor.json (1)
46-46: Consider reviewing "disposisjon" translation with a native speaker.The term "disposisjon" (used for "outline") typically means "disposition" or "arrangement" in Norwegian. In the context of icon variants, "kontur" or "omriss" might be more idiomatic. Consider having a native Norwegian speaker verify this translation choice.
Also applies to: 48-48, 63-63, 66-66
packages/visual-editor/src/components/footer/Footer.tsx (1)
126-131: Consider aligning the property name with the translation key.The
nameproperty is"twitter"but the translation key is"socialLinks.xLink". While this may reflect the platform's rebrand to X, the inconsistency could cause confusion. Consider either:
- Updating the name to
"x"to match the key, or- Using
"socialLinks.twitter"as the key to match the property namepackages/visual-editor/src/utils/i18n/components.ts (1)
18-24: Consider tightening the TemplateProps interface type.The
translationsproperty allows bothRecord<string, string>andRecord<string, any>. If nested translation objects (likesocialLinksorpresetImages) are expected, the type is appropriate. Otherwise, narrowing toRecord<string, string>would provide better type safety.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (40)
packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] default props with data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] default props with data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] default props with data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] latest version default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] latest version non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] version 10 default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] version 10 non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] version 21 default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] version 21 non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] version 22 default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] version 22 non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[desktop] version 24 default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[tablet] latest version non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[tablet] version 10 non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[tablet] version 21 non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[tablet] version 22 default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/Locator/[tablet] version 22 non-default props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] default props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with French locale.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 39 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 39 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] default props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with French locale (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with French locale.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 39 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 39 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] default props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with French locale (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with French locale.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 39 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 39 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**
📒 Files selected for processing (57)
packages/visual-editor/locales/components/cs/visual-editor.jsonpackages/visual-editor/locales/components/da/visual-editor.jsonpackages/visual-editor/locales/components/de/visual-editor.jsonpackages/visual-editor/locales/components/en-GB/visual-editor.jsonpackages/visual-editor/locales/components/en/visual-editor.jsonpackages/visual-editor/locales/components/es/visual-editor.jsonpackages/visual-editor/locales/components/et/visual-editor.jsonpackages/visual-editor/locales/components/fi/visual-editor.jsonpackages/visual-editor/locales/components/fr/visual-editor.jsonpackages/visual-editor/locales/components/hr/visual-editor.jsonpackages/visual-editor/locales/components/hu/visual-editor.jsonpackages/visual-editor/locales/components/it/visual-editor.jsonpackages/visual-editor/locales/components/ja/visual-editor.jsonpackages/visual-editor/locales/components/lt/visual-editor.jsonpackages/visual-editor/locales/components/lv/visual-editor.jsonpackages/visual-editor/locales/components/nb/visual-editor.jsonpackages/visual-editor/locales/components/nl/visual-editor.jsonpackages/visual-editor/locales/components/pl/visual-editor.jsonpackages/visual-editor/locales/components/pt/visual-editor.jsonpackages/visual-editor/locales/components/ro/visual-editor.jsonpackages/visual-editor/locales/components/sk/visual-editor.jsonpackages/visual-editor/locales/components/sv/visual-editor.jsonpackages/visual-editor/locales/components/tr/visual-editor.jsonpackages/visual-editor/locales/components/zh-TW/visual-editor.jsonpackages/visual-editor/locales/components/zh/visual-editor.jsonpackages/visual-editor/locales/platform/cs/visual-editor.jsonpackages/visual-editor/locales/platform/da/visual-editor.jsonpackages/visual-editor/locales/platform/de/visual-editor.jsonpackages/visual-editor/locales/platform/en-GB/visual-editor.jsonpackages/visual-editor/locales/platform/en/visual-editor.jsonpackages/visual-editor/locales/platform/es/visual-editor.jsonpackages/visual-editor/locales/platform/et/visual-editor.jsonpackages/visual-editor/locales/platform/fi/visual-editor.jsonpackages/visual-editor/locales/platform/fr/visual-editor.jsonpackages/visual-editor/locales/platform/hr/visual-editor.jsonpackages/visual-editor/locales/platform/hu/visual-editor.jsonpackages/visual-editor/locales/platform/it/visual-editor.jsonpackages/visual-editor/locales/platform/ja/visual-editor.jsonpackages/visual-editor/locales/platform/lt/visual-editor.jsonpackages/visual-editor/locales/platform/lv/visual-editor.jsonpackages/visual-editor/locales/platform/nb/visual-editor.jsonpackages/visual-editor/locales/platform/nl/visual-editor.jsonpackages/visual-editor/locales/platform/pl/visual-editor.jsonpackages/visual-editor/locales/platform/pt/visual-editor.jsonpackages/visual-editor/locales/platform/ro/visual-editor.jsonpackages/visual-editor/locales/platform/sk/visual-editor.jsonpackages/visual-editor/locales/platform/sv/visual-editor.jsonpackages/visual-editor/locales/platform/tr/visual-editor.jsonpackages/visual-editor/locales/platform/zh-TW/visual-editor.jsonpackages/visual-editor/locales/platform/zh/visual-editor.jsonpackages/visual-editor/scripts/sortTranslations.tspackages/visual-editor/src/components/Locator.tsxpackages/visual-editor/src/components/atoms/reviewStars.tsxpackages/visual-editor/src/components/footer/Footer.tsxpackages/visual-editor/src/components/pageSections/NearbyLocations/NearbyLocationsCardsWrapper.tsxpackages/visual-editor/src/editor/Editor.tsxpackages/visual-editor/src/utils/i18n/components.ts
✅ Files skipped from review due to trivial changes (2)
- packages/visual-editor/locales/components/ja/visual-editor.json
- packages/visual-editor/locales/components/nl/visual-editor.json
🚧 Files skipped from review as they are similar to previous changes (19)
- packages/visual-editor/locales/components/sk/visual-editor.json
- packages/visual-editor/locales/components/fi/visual-editor.json
- packages/visual-editor/locales/components/pl/visual-editor.json
- packages/visual-editor/scripts/sortTranslations.ts
- packages/visual-editor/locales/components/en-GB/visual-editor.json
- packages/visual-editor/src/components/atoms/reviewStars.tsx
- packages/visual-editor/src/components/pageSections/NearbyLocations/NearbyLocationsCardsWrapper.tsx
- packages/visual-editor/locales/components/ro/visual-editor.json
- packages/visual-editor/locales/components/da/visual-editor.json
- packages/visual-editor/locales/components/es/visual-editor.json
- packages/visual-editor/locales/platform/nl/visual-editor.json
- packages/visual-editor/locales/components/lv/visual-editor.json
- packages/visual-editor/locales/platform/da/visual-editor.json
- packages/visual-editor/locales/components/sv/visual-editor.json
- packages/visual-editor/locales/components/fr/visual-editor.json
- packages/visual-editor/locales/components/et/visual-editor.json
- packages/visual-editor/locales/platform/pt/visual-editor.json
- packages/visual-editor/locales/components/zh/visual-editor.json
- packages/visual-editor/locales/components/zh-TW/visual-editor.json
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-12-23T16:36:42.670Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 958
File: packages/visual-editor/locales/ro/visual-editor.json:394-394
Timestamp: 2025-12-23T16:36:42.670Z
Learning: In Romanian locale files (ro), "Top" is an acceptable translation for directional terms like "top_direction" rather than the native Romanian "Sus". The maintainer benlife5 confirmed this is the preferred translation in packages/visual-editor/locales/ro/visual-editor.json.
Applied to files:
packages/visual-editor/locales/components/tr/visual-editor.jsonpackages/visual-editor/locales/components/lt/visual-editor.jsonpackages/visual-editor/locales/components/hr/visual-editor.jsonpackages/visual-editor/locales/components/hu/visual-editor.jsonpackages/visual-editor/locales/platform/hr/visual-editor.jsonpackages/visual-editor/locales/platform/cs/visual-editor.jsonpackages/visual-editor/locales/platform/ro/visual-editor.json
📚 Learning: 2025-12-15T20:59:25.571Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 943
File: packages/visual-editor/src/components/contentBlocks/image/Image.tsx:175-191
Timestamp: 2025-12-15T20:59:25.571Z
Learning: In the ImageWrapper component at packages/visual-editor/src/components/contentBlocks/image/Image.tsx, when an Image is wrapped in a MaybeLink, the aria-label should be omitted because the image's alt text serves as the accessible name for the link. Adding an aria-label would override the image's alt text.
Applied to files:
packages/visual-editor/src/components/footer/Footer.tsxpackages/visual-editor/locales/platform/en/visual-editor.json
📚 Learning: 2025-10-29T22:00:03.843Z
Learnt from: mkouzel-yext
Repo: yext/visual-editor PR: 833
File: packages/visual-editor/src/components/Locator.tsx:1050-1057
Timestamp: 2025-10-29T22:00:03.843Z
Learning: In packages/visual-editor/src/components/Locator.tsx, the AppliedFilters component is intentionally rendered in two locations (inside the filter modal and outside it) as per the design requirements. This dual rendering should not be flagged as a duplicate issue.
Applied to files:
packages/visual-editor/src/components/Locator.tsx
📚 Learning: 2025-12-23T16:30:55.497Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 958
File: packages/visual-editor/src/components/pageSections/heroVariants/CompactHero.tsx:38-41
Timestamp: 2025-12-23T16:30:55.497Z
Learning: In CompactHero and CompactPromo components, duplicate IDs on image elements are intentional: conditional visibility classes (hidden/sm:block/sm:hidden) ensure only one image renders at a time based on responsive breakpoints and desktopImagePosition/mobileImagePosition settings.
Applied to files:
packages/visual-editor/locales/platform/en/visual-editor.json
📚 Learning: 2025-12-12T20:17:37.033Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 946
File: packages/visual-editor/src/components/migrations/migrationRegistry.ts:47-48
Timestamp: 2025-12-12T20:17:37.033Z
Learning: In the yext/visual-editor repository, empty object placeholders (`{}`) in the migrationRegistry array are sometimes intentionally used to reserve migration slots for parallel PRs to prevent merge conflicts and maintain consistent migration indices.
Applied to files:
packages/visual-editor/locales/platform/en-GB/visual-editor.json
🧬 Code graph analysis (1)
packages/visual-editor/src/utils/i18n/components.ts (1)
packages/visual-editor/src/utils/i18n/index.ts (2)
i18nComponentsInstance(1-1)injectTranslations(1-1)
⏰ 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). (5)
- GitHub Check: call_unit_test / unit_tests (24.x)
- GitHub Check: call_unit_test / unit_tests (22.x)
- GitHub Check: call_unit_test / unit_tests (20.x)
- GitHub Check: create-dev-release
- GitHub Check: semgrep/ci
packages/visual-editor/locales/components/cs/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/cs/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/hr/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/it/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/it/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/pt/visual-editor.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In @packages/visual-editor/locales/components/nb/visual-editor.json:
- Around line 35-36: The Norwegian locale has inconsistent plural keys
"mile_one" and "mile_other" using different terms; make them consistent by
setting both values to the same Norwegian unit ("mil") to match the Swedish
pattern, and add/update the corresponding translation keys "mile_one" and
"mile_other" so both read "mil"; if the backend actually uses English miles,
instead choose the Anglicized term for both keys ("mile") and coordinate with
the backend to clarify unit conversion to avoid user confusion.
In @packages/visual-editor/locales/platform/cs/visual-editor.json:
- Line 311: The JSON key "base_text size" contains a space; rename it to a
consistent identifier (e.g., "base_text_size" or "baseTextSize") in this locale
file and update every other locale file and any code references that access this
key (lookup, i18n keys, tests) to use the new name so usages remain consistent
across the app; ensure pluralization/namespace patterns remain intact and run
the i18n/lint/tests to verify no missing-key errors.
In @packages/visual-editor/locales/platform/es/visual-editor.json:
- Around line 747-748: The Spanish translations mix "revisión/revisiones" and
"reseña/reseñas"; standardize to "reseña" for user reviews by replacing any
occurrences of "revisión" with "reseña" and "revisiones" with "reseñas"
throughout the file, and ensure pluralized keys (e.g., "totalReviews_one" and
"totalReviews_other") use "{{count}} reseña" and "{{count}} reseñas"
respectively while preserving existing ICU/placeholder syntax.
In @packages/visual-editor/locales/platform/nb/visual-editor.json:
- Around line 541-542: The pluralization keys "mile_one" and "mile_other" are
inconsistent; update them so both use the same Norwegian term—change the value
for "mile_other" to "mil" to match "mile_one" (i.e., set both "mile_one" and
"mile_other" to "mil") so the UI shows a consistent unit for miles in Norwegian
Bokmål.
🧹 Nitpick comments (2)
packages/visual-editor/locales/components/pt/visual-editor.json (1)
1-113: LGTM! Translation file structure is correct.The JSON structure, i18next interpolation syntax, and pluralization patterns are all technically correct. The file provides comprehensive Portuguese translations for the visual-editor component.
One minor observation: there's a capitalization variation between "Banner do Herói" (line 21) and "Cabeçalho do herói" (line 22). This may be intentional based on Portuguese grammar or UI component naming conventions, but you may want to verify consistency if it wasn't deliberate.
packages/visual-editor/package.json (1)
57-57: Consider consolidating the sort calls for efficiency.The current setup causes
i18n:sortto run multiple times when executingi18n:update(once afteri18n:copy-platform-translationsand again afteri18n:fix-plurals). While sorting is typically fast and this doesn't break functionality, you could optimize by havingi18n:updatecall sort just once at the end:-"i18n:update": "pnpm run i18n:scan && pnpm run i18n:translate && pnpm run i18n:copy-platform-translations && pnpm run i18n:fix-plurals", +"i18n:update": "pnpm run i18n:scan && pnpm run i18n:translate && pnpm exec tsx scripts/copyPlatformTranslations.ts && pnpm exec tsx scripts/fixPlurals.ts && pnpm run i18n:sort",This would require
i18n:copy-platform-translationsandi18n:fix-pluralsto be used both standalone (when they need to sort) and as part of the larger workflow (when they don't). The current approach is simpler and more maintainable, so this optimization is entirely optional.Also applies to: 59-59, 61-61
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (69)
packages/visual-editor/src/components/testing/screenshots/BreadcrumbsSection/[tablet] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/BreadcrumbsSection/[tablet] version 4 props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/BreadcrumbsSection/[tablet] version 8 with non-default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [classic] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [classic] version 17 props using entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [classic] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [classic] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [compact] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [compact] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [compact] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [immersive] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [immersive] version 31 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [immersive] version 31 props using entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [spotlight] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [spotlight] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] default props with data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] version 16 props using entity values with old CTA structure.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] version 16 props with missing ctaType.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] version 16 props with old CTA structure.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] version 9 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [classic] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [classic] version 17 props using entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [classic] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [classic] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [compact] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [compact] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [compact] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [immersive] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [immersive] version 31 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [immersive] version 31 props using entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [spotlight] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] [spotlight] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] default props with data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] version 16 props using entity values with old CTA structure.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] version 16 props with missing ctaType.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] version 16 props with old CTA structure.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[mobile] version 9 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [classic] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [classic] version 17 props using entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [classic] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [classic] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [compact] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [compact] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [compact] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [immersive] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [immersive] version 31 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [immersive] version 31 props using entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [spotlight] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] [spotlight] version 31 props with entity values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] default props with data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] version 16 props using entity values with old CTA structure.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] version 16 props with missing ctaType.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] version 16 props with old CTA structure.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[tablet] version 9 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[xl] [compact] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] default props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with French locale.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 39 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] default props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with French locale.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 39 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with French locale.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 39 props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**
📒 Files selected for processing (15)
packages/visual-editor/locales/components/cs/visual-editor.jsonpackages/visual-editor/locales/components/es/visual-editor.jsonpackages/visual-editor/locales/components/hr/visual-editor.jsonpackages/visual-editor/locales/components/it/visual-editor.jsonpackages/visual-editor/locales/components/lt/visual-editor.jsonpackages/visual-editor/locales/components/nb/visual-editor.jsonpackages/visual-editor/locales/components/pt/visual-editor.jsonpackages/visual-editor/locales/platform/cs/visual-editor.jsonpackages/visual-editor/locales/platform/es/visual-editor.jsonpackages/visual-editor/locales/platform/hr/visual-editor.jsonpackages/visual-editor/locales/platform/it/visual-editor.jsonpackages/visual-editor/locales/platform/lt/visual-editor.jsonpackages/visual-editor/locales/platform/nb/visual-editor.jsonpackages/visual-editor/locales/platform/pt/visual-editor.jsonpackages/visual-editor/package.json
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/visual-editor/locales/components/es/visual-editor.json
- packages/visual-editor/locales/components/it/visual-editor.json
- packages/visual-editor/locales/components/lt/visual-editor.json
- packages/visual-editor/locales/components/hr/visual-editor.json
- packages/visual-editor/locales/components/cs/visual-editor.json
- packages/visual-editor/locales/platform/hr/visual-editor.json
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-23T16:36:42.670Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 958
File: packages/visual-editor/locales/ro/visual-editor.json:394-394
Timestamp: 2025-12-23T16:36:42.670Z
Learning: In Romanian locale files (ro), "Top" is an acceptable translation for directional terms like "top_direction" rather than the native Romanian "Sus". The maintainer benlife5 confirmed this is the preferred translation in packages/visual-editor/locales/ro/visual-editor.json.
Applied to files:
packages/visual-editor/locales/platform/cs/visual-editor.json
⏰ 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). (5)
- GitHub Check: call_unit_test / unit_tests (24.x)
- GitHub Check: call_unit_test / unit_tests (22.x)
- GitHub Check: call_unit_test / unit_tests (20.x)
- GitHub Check: create-dev-release
- GitHub Check: semgrep/ci
🔇 Additional comments (30)
packages/visual-editor/locales/platform/it/visual-editor.json (4)
535-536: LGTM! Pluralization structure is correct for Italian.The localisations correctly use
_oneand_othersuffixes for Italian pluralization, and the{{mile}}placeholder will dynamically resolve to the appropriate singular or plural form at runtime.
541-542: LGTM! Mile pluralization keys added correctly.The singular and plural forms for "mile" are properly defined and will be used to populate the
{{mile}}placeholder in distance-related strings.
651-659: LGTM! Social links structure is well-organized.The new
socialLinksobject provides accessible labels for social media platforms, following a consistent pattern suitable for aria-labels.
748-749: LGTM! Reviews pluralization implemented correctly.The Italian singular and plural forms for reviews are properly configured with the
{{count}}placeholder.packages/visual-editor/package.json (2)
57-61: Well-structured i18n workflow scripts.The new script structure effectively supports the PR's objective of separating platform and component translations. The workflow is logical (scan → translate → copy-platform-translations → fix-plurals), and each script has a clear, single responsibility. The use of command chaining with
&&ensures proper error propagation.
57-61: The referenced TypeScript script files exist in the correct location.All three scripts (
copyPlatformTranslations.ts,deleteTranslationKeys.ts,fixPlurals.ts) are present inpackages/visual-editor/scripts/and will be found correctly when the npm scripts execute from thepackages/visual-editor/package.jsoncontext.Likely an incorrect or invalid review comment.
packages/visual-editor/locales/platform/nb/visual-editor.json (6)
80-80: LGTM! Email translations are consistent.The Norwegian translations for email-related fields are accurate and consistent throughout the file.
Also applies to: 160-160, 222-225, 521-521, 584-584
535-536: LGTM! Distance string translations use correct placeholders.The translations properly incorporate the
{{mile}}placeholder and follow correct Norwegian grammar for singular/plural entity counts.Also applies to: 546-546
651-659: LGTM! Social media ARIA labels are well-translated.The social links object provides appropriate Norwegian translations with consistent formatting. The variation for YouTube ("Abonner på vår YouTube-kanal") is contextually appropriate for a video platform.
748-749: LGTM! Review count pluralization is correct for Norwegian.Norwegian Bokmål correctly uses only "one" and "other" plural forms. The translations are accurate: "vurdering" (singular) and "anmeldelser" (plural).
503-503: LGTM! Hero banner translation is appropriate."Heltebanner" is a correct and natural Norwegian translation.
574-574: LGTM! Preset image labels are correctly translated.Brand names are appropriately preserved in English while UI terms like "next" are properly translated to "Neste".
Also applies to: 596-596, 606-606
packages/visual-editor/locales/platform/es/visual-editor.json (4)
534-535: LGTM! Proper pluralization and consistent distance terminology.The addition of
mile_oneandmile_otherkeys with proper Spanish translations ("milla"/"millas") and their integration using{{mile}}placeholders in distance-related strings follows i18n best practices and maintains grammatical correctness.Also applies to: 540-541, 545-545
554-554: LGTM! Proper grammar and brand name corrections.These updates fix grammatical errors and properly handle brand names:
- "Abierto 24 horas" corrects the grammar (adjective vs. verb)
- Brand names (App Store, Apple, Galaxy Store, Uber Eats) are correctly kept in English
- "Flecha arriba" fixes the obvious translation error
Also applies to: 571-571, 573-573, 577-577, 586-586, 605-605
650-658: LGTM! Well-structured social links translations.The new
socialLinksobject provides consistent, grammatically correct Spanish translations with appropriate context for each social media platform.
747-748: AI summary mentions missingtotalReviews_zerokey.The AI-generated summary states that
totalReviews_zerowas added with value"{{count}} reseñas", but this key is not present in the code. OnlytotalReviews_oneandtotalReviews_otherare defined.packages/visual-editor/locales/platform/lt/visual-editor.json (4)
659-667: LGTM! Social links translations are well-structured.The
socialLinksobject provides clear, contextually appropriate Lithuanian labels for social media platforms. The translations maintain consistency in tone and follow proper Lithuanian grammar.
582-582: LGTM! Brand name updates follow best practices.Keeping brand names in their original form ("Apple", "Uber Eats") rather than translating them is the correct approach for international brand recognition and consistency.
Also applies to: 614-614
756-759: LGTM! Review count pluralization is complete.The addition of missing plural forms (_few, _many, _other) for
totalReviewsensures proper grammatical agreement for all numeric values in Lithuanian. This completes the pluralization pattern used throughout the file.
539-542: LGTM! Pluralization implementation is correctly configured.The distance and mile pluralization forms follow i18next conventions with appropriate Lithuanian translations. The
{{mile}}token integration allows for grammatically correct distance expressions.i18next v25.x automatically handles Lithuanian pluralization rules via the ECMAScript
Intl.PluralRulesstandard, which supports the four forms required for Lithuanian:_one,_few,_many, and_other. The codebase includes afixPlurals.tsscript that validates plural forms for each locale (including special handling for Lithuanian's fractional plural rule), ensuring the configuration is correct.packages/visual-editor/locales/components/nb/visual-editor.json (1)
1-113: LGTM - Structure and i18next patterns are correct.The JSON structure is valid, interpolation variables are properly formatted, and pluralization patterns follow i18next conventions for Norwegian Bokmål locale. The nested objects (
presetImages,socialLinks) are correctly structured for the new component-scoped translation loading approach.packages/visual-editor/locales/platform/cs/visual-editor.json (4)
666-674: LGTM: Social links translations look correct.The new
socialLinksobject is properly structured with consistent Czech translations. The variation in the YouTube translation ("Přihlaste se k odběru" vs "Sledujte nás") appropriately reflects the difference between subscribing to a channel versus following on social media.
763-766: Total reviews pluralization follows Czech grammar rules.The plural forms for
totalReviewscorrectly follow Czech CLDR plural rules and use appropriate grammatical forms. The structure mirrors the established pattern used elsewhere in the file.
546-549: Mile-based distance translations are properly structured.The distance-related translations correctly interpolate the new
{{mile}}variable alongside{{distance}},{{count}}, and{{name}}variables. The implementation aligns with the PR's objective to introduce mile-based framing across locales.Also applies to: 561-561
554-557: No changes needed; Czech plural forms for "mile" are correct.The translations follow proper Czech grammar rules: nominative singular "míle" for one (1), nominative plural "míle" for few (2-4), and genitive plural "mil" for many (fractional) and other (0, 5+) counts.
packages/visual-editor/locales/platform/pt/visual-editor.json (5)
574-574: LGTM! Brand names correctly preserved.The brand names "Apple" and "Uber Eats" are appropriately not translated, maintaining brand identity and international recognition.
Also applies to: 606-606
651-659: LGTM! Social links enhance accessibility.The new
socialLinkssection provides Portuguese aria-labels for social media platforms, improving accessibility for Portuguese-speaking users. The translations appropriately use "Siga-nos" (Follow us) for most platforms and "Inscreva-se" (Subscribe) for YouTube, which is contextually appropriate.
748-749: LGTM! Review count pluralization correctly implemented.The
totalReviewspluralization correctly distinguishes between singular "comentário" and plural "comentários", following i18next conventions and proper Portuguese grammar.
503-503: Translation updates look appropriate.The updated translations for
heroBanner,loadingMap, andloadingReviewsappear grammatically correct. If these translations haven't been reviewed by a native Portuguese speaker or through your established localization process, consider doing so to ensure linguistic accuracy and cultural appropriateness.Also applies to: 526-526, 528-528
535-536: Mile pluralization correctly implemented with proper Portuguese rules.The addition of
mile_one("milha") andmile_other("milhas") keys and their integration into distance-related strings using the{{mile}}token follows i18next pluralization conventions correctly. Portuguese uses only the "one" and "other" plural forms (verified viaIntl.PluralRules), which are properly provided. The refactoring enables correct grammatical agreement based on distance values.
packages/visual-editor/locales/components/nb/visual-editor.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/visual-editor/locales/platform/ja/visual-editor.json (1)
647-655: New social links translations look good, with minor spacing inconsistency.The social media follow prompts are natural and appropriate. However, there's a minor spacing inconsistency worth noting for polish:
- Lines 649 and 652 (instagram, tiktok) are missing a space before "で", while other entries have it
✨ Optional fix for spacing consistency
"socialLinks": { "facebook": "Facebook でフォローしてください", - "instagram": "Instagramでフォローしてください", + "instagram": "Instagram でフォローしてください", "linkedIn": "LinkedIn でフォローしてください", "pinterest": "Pinterest でフォローしてください", - "tiktok": "TikTokでフォローしてください", + "tiktok": "TikTok でフォローしてください", "xLink": "X (Twitter) でフォローしてください", "youtube": "YouTube チャンネルを購読してください" },
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (12)
packages/visual-editor/src/components/testing/screenshots/NearbyLocationsSection/[mobile] default props with multiple nearby locations.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/NearbyLocationsSection/[mobile] version 10 with multiple nearby locations.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/NearbyLocationsSection/[mobile] version 36 with multiple nearby locations.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 39 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with French locale (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 10 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[mobile] version 39 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] default props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with French locale (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 10 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[tablet] version 39 props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**
📒 Files selected for processing (5)
packages/visual-editor/locales/components/it/visual-editor.jsonpackages/visual-editor/locales/components/ja/visual-editor.jsonpackages/visual-editor/locales/platform/it/visual-editor.jsonpackages/visual-editor/locales/platform/ja/visual-editor.jsonpackages/visual-editor/locales/platform/tr/visual-editor.json
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/visual-editor/locales/components/ja/visual-editor.json
- packages/visual-editor/locales/components/it/visual-editor.json
⏰ 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). (2)
- GitHub Check: call_unit_test / unit_tests (20.x)
- GitHub Check: semgrep/ci
🔇 Additional comments (10)
packages/visual-editor/locales/platform/ja/visual-editor.json (3)
61-61: Excellent translation improvements for business status terms!The updated translations are much more natural and appropriate for business contexts:
- "閉じる" (close) is the correct verb form
- "閉店" (closed) and "営業中" (openNow) are standard business terms
- "一時休業中" (temporarilyClosed) accurately conveys temporary closure status
Also applies to: 64-65, 554-554, 662-662
570-570: Great corrections to preset image names!The preset image translations are now accurate:
- Brand names (Apple, Galaxy Store, Uber Eats) now use proper English names as is standard practice
- "ハート" (heart symbol) is more appropriate than "心臓" (anatomical heart) for an icon
- "再生" (play media) correctly replaces "遊ぶ" (play/have fun) for media controls
Also applies to: 583-584, 588-588, 595-595, 602-602
533-533: LGTM: Placeholder refactoring aligns well with Japanese grammar!The new placeholder pattern for distance units and counts is well-designed:
- Using
{{mile}}placeholder allows dynamic unit display and better i18n flexibility- Japanese grammatically doesn't distinguish plural forms, so using only
_othersuffix is appropriate- The removal of
_few/_many/_one/_zerovariants (mentioned in the summary) correctly reflects Japanese language rulesAlso applies to: 538-538, 542-542, 744-744
packages/visual-editor/locales/platform/it/visual-editor.json (1)
47-47: Italian translations look correct.The translations follow proper Italian grammar and i18next conventions:
- Mile pluralization: "miglio" (singular) and "miglia" (plural) are correct
- Location counts: "posizione" (singular) and "località" (plural) properly pluralized
- All distance-related strings correctly use the
{{mile}}placeholder which is populated at runtime with the appropriate singular/plural form based on the distance valueThe runtime code in
Locator.tsxcorrectly passes the distance value as thecountparameter when translating the mile key, ensuring proper pluralization by distance.packages/visual-editor/locales/platform/tr/visual-editor.json (6)
555-555: LGTM: Hours status translations are correct.The Turkish translations for
open24HoursandopenNoware grammatically correct and appropriate for UI context.Also applies to: 558-558
574-578: LGTM: Brand names and icon labels are correctly handled.Brand names (Apple, Figma, Galaxy Store) are appropriately kept in their original form, and arrow direction translations follow correct Turkish grammar.
Also applies to: 586-587
617-617: LGTM: Search refinement translation is appropriate.The Turkish translation "Aramanızı hassaslaştırın" is grammatically correct and uses appropriate phrasing for UI context.
651-659: LGTM: socialLinks section and additional translations are well-structured.The new
socialLinksobject at the platform level aligns with the PR's objective to restructure i18n. The Turkish translations correctly use locative case suffixes ('ta/'de) and appropriate verbs for each platform. ThetotalReviews_otherandvisitPagetranslations are also grammatically correct.Also applies to: 749-749, 758-758
304-304: No action needed for this key.The key
"base_text size"is used consistently across all 26+ locale files in the platform scope (en, de, fr, es, zh, ja, tr, pt, it, nl, and others). The embedded space is intentional and supported by i18next. This is not a translation issue.Likely an incorrect or invalid review comment.
531-536: Turkish pluralization pattern is correctly implemented for i18next.The
_one/_othersuffix pattern is the correct approach for Turkish in i18next, which recognizes two plural categories (one and other). The implementation correctly uses{{count}}placeholders, and the translation entries formile_oneandmile_otherboth use "mil" as expected—Turkish does not modify this word for plural forms. The{{distance}} {{mile}}placeholder pattern is consistent across related keys.
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Fix all issues with AI agents
In @packages/visual-editor/locales/platform/ja/visual-editor.json:
- Around line 653-661: The socialLinks JSON has inconsistent spacing around the
brand name and the Japanese particle/phrase; update the values under the
"socialLinks" object (keys: "instagram", "tiktok") to include a space after the
brand name to match others (e.g., change "Instagramでフォローしてください" → "Instagram
でフォローしてください" and "TikTokでフォローしてください" → "TikTok でフォローしてください"), leaving the
already-correct entries ("facebook", "linkedIn", "pinterest", "xLink",
"youtube") unchanged.
- Around line 539-548: The two translation keys
"locationsWithinDistanceOf_other" and "nearbyLocationsEmptyState" have
inconsistent spacing around the {{mile}} placeholder; update the value of
"nearbyLocationsEmptyState" to include the same space before "以内" (i.e., change
`{{mile}}以内` to `{{mile}} 以内`) so both strings render consistently.
In @packages/visual-editor/locales/platform/nb/visual-editor.json:
- Around line 754-755: The singular/plural pair for totalReviews is
inconsistent: "totalReviews_one" uses "vurdering" while "totalReviews_other"
uses "anmeldelser"; choose one base word and make both forms consistent (either
"anmeldelse" → set totalReviews_one to "{{count}} anmeldelse" and
totalReviews_other to "{{count}} anmeldelser", or "vurdering" → set
totalReviews_one to "{{count}} vurdering" and totalReviews_other to "{{count}}
vurderinger"), and update the values for the keys totalReviews_one and
totalReviews_other accordingly.
- Around line 547-548: Replace the incorrect English plural "mile" with the
Norwegian invariable "mil" for the JSON key "mile_other" (keeping "mile_one" as
"mil") in both nb visual-editor locale files (platform and components); update
the "mile_other" value from "mile" to "mil" so both "mile_one" and "mile_other"
are "mil".
In @packages/visual-editor/locales/platform/nl/visual-editor.json:
- Around line 507-515: Remove the "twitter" property from the footerSocialLinks
object in visual-editor.json so it matches other locales; locate the
"footerSocialLinks" block (containing keys like "facebook", "instagram",
"linkedIn", "pinterest", "tiktok", "youtube") and delete the "twitter" entry,
then verify the X/Twitter link is handled via the "socialLinks" block using
"xLink" elsewhere in the locale file.
In @packages/visual-editor/locales/platform/sk/visual-editor.json:
- Around line 554-557: The locale entry "mile_many" uses the wrong diacritic (L
with acute "ĺ") causing inconsistency; update the value for the "mile_many" key
to use the correct Slovak character (L with caron "ľ") so it matches the
genitive plural form used by "mile_other" and is consistent with
"mile_one"/"mile_few".
In @packages/visual-editor/locales/platform/tr/visual-editor.json:
- Around line 754-755: The singular/plural Turkish translations for totalReviews
are inconsistent: change the value of "totalReviews_other" to use the same term
as "totalReviews_one" so both use "inceleme" (i.e., update the
"totalReviews_other" entry currently set to "{{count}} yorum" to "{{count}}
inceleme") so singular and plural use consistent terminology; keep the keys
"totalReviews_one" and "totalReviews_other" unchanged.
🧹 Nitpick comments (3)
packages/visual-editor/locales/platform/hu/visual-editor.json (2)
541-542: Inconsistent sentence structure between singular and plural forms.The
_oneand_othervariants have different word order and structure:
_one: places{{name}}before the distance phrase_other: places{{name}}at the end after "a következőtől:"This inconsistency may cause a jarring user experience when the count changes between 1 and other values. Consider aligning the sentence structure for both variants.
657-665: Minor inconsistency: missing article for Instagram.Line 659 uses "Instagramon" without an article, while other social platforms include the article (e.g., "a Facebookon", "a LinkedIn-en", "az X-en"). For consistency, consider using "az Instagramon".
Suggested fix
"socialLinks": { "facebook": "Kövess minket a Facebookon", - "instagram": "Kövess minket Instagramon", + "instagram": "Kövess minket az Instagramon", "linkedIn": "Kövess minket a LinkedIn-en",packages/visual-editor/src/editor/Editor.tsx (1)
169-171: Consider propagating translation load errors.The current error handling logs to console but the failure is otherwise silent. While the editor can likely function with fallback translations, consider whether translation load failures should:
- Be reported via
sendErrorfor observability in the platform- Update some state to potentially show a subtle warning
This is a low-priority consideration since fallback behavior is likely acceptable.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (29)
packages/visual-editor/locales/platform/cs/visual-editor.jsonpackages/visual-editor/locales/platform/da/visual-editor.jsonpackages/visual-editor/locales/platform/de/visual-editor.jsonpackages/visual-editor/locales/platform/en-GB/visual-editor.jsonpackages/visual-editor/locales/platform/en/visual-editor.jsonpackages/visual-editor/locales/platform/es/visual-editor.jsonpackages/visual-editor/locales/platform/et/visual-editor.jsonpackages/visual-editor/locales/platform/fi/visual-editor.jsonpackages/visual-editor/locales/platform/fr/visual-editor.jsonpackages/visual-editor/locales/platform/hr/visual-editor.jsonpackages/visual-editor/locales/platform/hu/visual-editor.jsonpackages/visual-editor/locales/platform/it/visual-editor.jsonpackages/visual-editor/locales/platform/ja/visual-editor.jsonpackages/visual-editor/locales/platform/lt/visual-editor.jsonpackages/visual-editor/locales/platform/lv/visual-editor.jsonpackages/visual-editor/locales/platform/nb/visual-editor.jsonpackages/visual-editor/locales/platform/nl/visual-editor.jsonpackages/visual-editor/locales/platform/pl/visual-editor.jsonpackages/visual-editor/locales/platform/pt/visual-editor.jsonpackages/visual-editor/locales/platform/ro/visual-editor.jsonpackages/visual-editor/locales/platform/sk/visual-editor.jsonpackages/visual-editor/locales/platform/sv/visual-editor.jsonpackages/visual-editor/locales/platform/tr/visual-editor.jsonpackages/visual-editor/locales/platform/zh-TW/visual-editor.jsonpackages/visual-editor/locales/platform/zh/visual-editor.jsonpackages/visual-editor/package.jsonpackages/visual-editor/src/editor/Editor.tsxpackages/visual-editor/src/internal/puck/components/LayoutHeader.tsxpackages/visual-editor/src/utils/VisualEditorProvider.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/visual-editor/package.json
- packages/visual-editor/src/internal/puck/components/LayoutHeader.tsx
- packages/visual-editor/locales/platform/hr/visual-editor.json
- packages/visual-editor/locales/platform/cs/visual-editor.json
- packages/visual-editor/src/utils/VisualEditorProvider.tsx
- packages/visual-editor/locales/platform/it/visual-editor.json
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-12-23T16:36:42.670Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 958
File: packages/visual-editor/locales/ro/visual-editor.json:394-394
Timestamp: 2025-12-23T16:36:42.670Z
Learning: In Romanian locale files (ro), "Top" is an acceptable translation for directional terms like "top_direction" rather than the native Romanian "Sus". The maintainer benlife5 confirmed this is the preferred translation in packages/visual-editor/locales/ro/visual-editor.json.
Applied to files:
packages/visual-editor/locales/platform/ro/visual-editor.jsonpackages/visual-editor/locales/platform/hu/visual-editor.json
📚 Learning: 2025-12-12T20:17:37.033Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 946
File: packages/visual-editor/src/components/migrations/migrationRegistry.ts:47-48
Timestamp: 2025-12-12T20:17:37.033Z
Learning: In the yext/visual-editor repository, empty object placeholders (`{}`) in the migrationRegistry array are sometimes intentionally used to reserve migration slots for parallel PRs to prevent merge conflicts and maintain consistent migration indices.
Applied to files:
packages/visual-editor/locales/platform/en-GB/visual-editor.json
📚 Learning: 2025-12-15T20:59:25.571Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 943
File: packages/visual-editor/src/components/contentBlocks/image/Image.tsx:175-191
Timestamp: 2025-12-15T20:59:25.571Z
Learning: In the ImageWrapper component at packages/visual-editor/src/components/contentBlocks/image/Image.tsx, when an Image is wrapped in a MaybeLink, the aria-label should be omitted because the image's alt text serves as the accessible name for the link. Adding an aria-label would override the image's alt text.
Applied to files:
packages/visual-editor/locales/platform/en/visual-editor.json
📚 Learning: 2025-12-23T16:30:55.497Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 958
File: packages/visual-editor/src/components/pageSections/heroVariants/CompactHero.tsx:38-41
Timestamp: 2025-12-23T16:30:55.497Z
Learning: In CompactHero and CompactPromo components, duplicate IDs on image elements are intentional: conditional visibility classes (hidden/sm:block/sm:hidden) ensure only one image renders at a time based on responsive breakpoints and desktopImagePosition/mobileImagePosition settings.
Applied to files:
packages/visual-editor/locales/platform/en/visual-editor.json
🧬 Code graph analysis (1)
packages/visual-editor/src/editor/Editor.tsx (2)
packages/visual-editor/src/utils/i18n/platform.ts (2)
loadPlatformTranslations(58-73)i18nPlatformInstance(7-7)packages/visual-editor/src/utils/i18n/index.ts (1)
i18nPlatformInstance(3-3)
⏰ 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). (5)
- GitHub Check: call_unit_test / unit_tests (22.x)
- GitHub Check: call_unit_test / unit_tests (20.x)
- GitHub Check: call_unit_test / unit_tests (24.x)
- GitHub Check: semgrep/ci
- GitHub Check: create-dev-release
🔇 Additional comments (67)
packages/visual-editor/locales/platform/pl/visual-editor.json (1)
1-777: LGTM! Polish translation file with proper pluralization.The translation updates are well-structured:
- The
mile_*andtotalReviews_*plural forms correctly follow Polish CLDR pluralization rules (one/few/many/other)- The
{{mile}}token pattern in distance-related strings properly enables nested pluralization- The new
socialLinkssection provides consistent platform labelspackages/visual-editor/locales/platform/ro/visual-editor.json (3)
543-556: LGTM! Distance-based pluralization pattern is correctly implemented.The approach of using
{{mile}}as a separate interpolation variable inlocationsWithinDistanceOf_*andnearbyLocationsEmptyStateallows proper dual-dimension pluralization—countfor locations and a separately resolvedmile_*key for distance. Romanian plural forms (one/few/other) are correctly applied.
661-669: LGTM! Social links accessibility labels.The new
socialLinksobject provides clear, screen-reader-friendly labels for each social platform. Translations are appropriate for Romanian.
758-760: LGTM! Review count pluralization.The
totalReviews_*keys correctly use Romanian plural forms (one/few/other) and the translations are accurate.packages/visual-editor/locales/platform/lv/visual-editor.json (4)
543-545: LGTM! Proper plural handling with externalized unit.The refactoring to use
{{mile}}interpolation alongside the newmile_one,mile_other, andmile_zerokeys enables correct grammatical agreement in Latvian. The plural forms follow Latvian grammar rules correctly (singular "jūdze" vs. plural "jūdzes").Also applies to: 550-552, 556-556
584-584: LGTM! Brand names correctly kept in English.Proper translation practice to use original brand names ("Apple", "Galaxy Store", "Uber Eats") rather than translated versions. This ensures brand consistency and recognition.
Also applies to: 597-597, 616-616
661-669: LGTM! Social links labels added.The
socialLinksobject provides appropriate Latvian call-to-action text for each social platform, maintaining consistency with the platform-level translation structure across other locales.
758-760: LGTM! Review count pluralization is correct.The
totalReviews_*keys properly handle Latvian plural forms with singular "atsauksme" and plural "atsauksmes" for both zero and other cases.packages/visual-editor/locales/platform/pt/visual-editor.json (5)
580-580: LGTM! Brand names correctly preserved.Keeping "Apple" and "Uber Eats" as untranslated brand names is the correct approach. The previous translations ("Maçã" and "Uber come") were incorrect.
Also applies to: 612-612
541-542: LGTM! Mile pluralization implemented correctly.The Portuguese plural forms (
milha/milhas) follow CLDR rules, and the{{mile}}placeholder integration enables proper grammatical agreement in distance-related strings.Also applies to: 547-548, 552-552
657-665: LGTM! Social links translations are well-crafted.The Portuguese translations correctly use "Siga-nos no [Platform]" (Follow us on) pattern, with an appropriate variation for YouTube ("Inscreva-se em nosso canal" - Subscribe to our channel).
754-755: Verify translation choice for "reviews".The translation uses "comentário(s)" (comment/comments) rather than "avaliação/avaliações" (review/evaluation). While "comentário" is commonly used in Brazilian Portuguese for reviews, you may want to confirm this aligns with the intended terminology across the application.
509-509: LGTM!Translation updates for hero banner and loading states are correct.
Also applies to: 532-534
packages/visual-editor/locales/platform/zh/visual-editor.json (4)
539-548: LGTM! Correct pluralization for Chinese locale.The Chinese locale correctly uses only
mile_othersince Chinese follows CLDR "no plural" rules — i18next will use this form for all count values. The{{mile}}token pattern properly delegates pluralization handling to the runtime.
574-608: LGTM! Brand names correctly kept in English.Trademarked names (App Store, Apple, Figma, Galaxy Store, Uber Eats) are appropriately preserved in English across locales for brand consistency — this is standard i18n practice.
653-661: LGTM! Natural and idiomatic translations for social links.The social media follow prompts use appropriate Chinese phrasing patterns while correctly preserving platform brand names in English. The structure is consistent with the broader platform locale changes described in the PR.
750-750: LGTM!The translation correctly uses the Chinese measure word
条for counting reviews, and appropriately provides only the_otherform for this no-plural-distinction locale.packages/visual-editor/locales/platform/de/visual-editor.json (5)
25-26: LGTM!The translations are accurate. "ALT-Text" correctly maintains the technical acronym format, and "Für alle Standorte anwenden" properly conveys the apply-all action.
546-557: LGTM!The tokenized
{{mile}}approach withmile_one/mile_otheris a clean pattern for handling German singular/plural agreement. This correctly replaces the redundant_few/_many/_zeroforms that aren't needed for German pluralization rules.
662-670: LGTM!The social links translations are well done. The "(Twitter)" clarification on
xLinkaids user recognition, and using "Abonnieren" for YouTube appropriately reflects the platform's subscription model versus the "Folgen Sie uns" pattern used for other social platforms.
759-760: LGTM!Correct German singular/plural forms: "Rezension" (singular) and "Rezensionen" (plural) following proper i18next pluralization patterns.
79-79: Translation is acceptable."Brotkrumen" is a valid literal translation. Note that in German technical/UI contexts, the English loanword "Breadcrumbs" is also commonly used. Either is acceptable depending on the desired localization style (fully translated vs. technical terminology).
packages/visual-editor/locales/platform/hu/visual-editor.json (3)
547-548: LGTM!Using the same form "mérföld" for both singular and plural is correct for Hungarian grammar, as nouns remain in singular form when preceded by numbers.
587-612: LGTM!Good corrections to the preset image labels:
- Brand names now properly preserved (Dribbble, Figma, Uber Eats)
- UI action terms corrected to appropriate Hungarian translations (Bezárás, Lejátszás, Megosztás)
754-755: LGTM!Correctly uses the same form "vélemény" for both singular and plural, consistent with Hungarian grammar rules.
packages/visual-editor/locales/platform/zh-TW/visual-editor.json (4)
575-577: Good improvement: Brand names now use original form instead of translations.Keeping brand names like "App Store", "Apple", "Figma", "Galaxy Store", and "Uber Eats" in their original form is the correct localization practice. The previous translations (e.g., "無花果" for Figma, which means "fig fruit") were incorrect.
Also applies to: 589-591, 609-609
654-662: LGTM!The social links translations are appropriate for Traditional Chinese and follow the established pattern for social media follow prompts.
751-751: LGTM!The
totalReviews_othertranslation "{{count}} 條評論" correctly uses the Chinese counter word "條" for reviews.
540-549: No action needed—themile_otherkey-only pattern is correct for Chinese.Chinese (both Simplified and Traditional) and Japanese only define
_otherplural forms because these languages lack grammatical singular/plural distinction. This is consistent with CLDR plural rules and matches the implementation in all other Chinese and Japanese locales. i18next correctly handles this language-specific behavior without requiring a_onevariant.packages/visual-editor/locales/platform/fr/visual-editor.json (2)
540-541: Consistent mile tokenization applied.The distance-related strings now use
{{mile}}token with proper French pluralization (mile_one: "mile",mile_other: "miles"). This approach correctly handles singular/plural forms and aligns with the broader refactoring to support runtime translation loading.Also applies to: 547-548, 552-552
657-665: socialLinks object provides accessible labels.The new
socialLinksobject with French translations for social media platforms (Facebook, Instagram, LinkedIn, Pinterest, TikTok, X, YouTube) provides proper aria-label content for accessibility.packages/visual-editor/locales/platform/en-GB/visual-editor.json (1)
540-541: LGTM!The en-GB locale correctly mirrors the structural changes with mile tokenization (
mile_one,mile_other), updated distance strings using{{mile}}, and the newsocialLinksobject. The English phrasing is appropriate for British English locale.Also applies to: 546-547, 551-551, 656-664, 754-754
packages/visual-editor/locales/platform/lt/visual-editor.json (2)
553-556: Proper Lithuanian pluralization with four forms.Lithuanian correctly uses all four plural forms (
_one,_few,_many,_other) per CLDR pluralization rules. Themile_*andtotalReviews_*keys properly handle Lithuanian's complex plural system:
mile_one: "mylia"(singular)mile_few: "mylios"(few)mile_many: "mylios"(many)mile_other: "mylių"(other/genitive plural)Also applies to: 762-765
588-588: Brand names correctly preserved.Good update to keep brand names as proper nouns (
apple: "Apple",uberEats: "„Uber" Eats") rather than translated terms.Also applies to: 620-620
packages/visual-editor/locales/platform/fi/visual-editor.json (3)
62-62: Quality improvements to Finnish translations.Several corrections improve translation accuracy:
close: "Lähellä" → "Sulje" (fixed meaning: "Near" → "Close")closeMenu: "Suljevalikko" → "Sulje valikko" (added missing space)closesAt: "Sulkeutuu jhk" → "Sulkeutuu klo" (fixed typo)opensAt: "Avata" → "Avautuu klo" (fixed meaning: "Open" → "Opens at")Also applies to: 64-64, 66-66, 565-565
580-580: Brand names properly corrected.Good fixes to preserve brand names as proper nouns:
apple: "Omena" → "Apple" (was translated as "Apple" the fruit)figma: "Viikuna" → "Figma" (was translated as "Fig" the fruit)galaxyStore: "Galaksikauppa" → "Galaxy Store"uberEats: "Uber syö" → "Uber Eats"Also applies to: 592-593, 612-612
625-625: Typo fix in responseFrom template.Fixed
"Vastaus {{businessName}}}"→"Vastaus {{businessName}}"(removed extra closing brace).packages/visual-editor/src/editor/Editor.tsx (2)
19-22: LGTM!Clean import of
loadPlatformTranslationsalongsidei18nPlatformInstancefor the async translation loading flow.
154-180: Well-implemented async pattern with race condition guards.The async translation loading correctly handles:
- Unmount safety:
isCurrentflag prevents state updates after component unmount- Rapid locale change protection:
expectedLocalecapture and re-check at lines 163-166 prevents applying stale translations if locale changes during the async load- Proper cleanup: Effect cleanup sets
isCurrent = falseThe double-guard pattern (
isCurrent && templateMetadata?.platformLocale === expectedLocale) is a robust approach for handling async operations in React effects.packages/visual-editor/locales/platform/da/visual-editor.json (1)
664-672: LGTM!The
socialLinksblock with Danish translations for social media platform accessibility labels looks good.packages/visual-editor/locales/platform/en/visual-editor.json (2)
540-547: LGTM!The English pluralization for miles (
mile_one: "mile",mile_other: "miles") and the updated distance strings using the{{mile}}token are correct. This provides a clean interpolation pattern for distance-related messages.
656-664: LGTM!The new
socialLinksblock with accessibility labels for social media platforms is well-structured and provides clear, user-friendly text.packages/visual-editor/locales/platform/es/visual-editor.json (2)
546-551: LGTM!Spanish pluralization for miles (
milla/millas) is correct, and the distance-related strings properly use the{{mile}}token for interpolation.
656-664: LGTM!The Spanish
socialLinkstranslations are appropriate and follow natural phrasing for the language.packages/visual-editor/locales/platform/et/visual-editor.json (2)
547-552: LGTM!Estonian pluralization for miles (
miil/miili) correctly uses the partitive plural form, and the distance strings properly utilize the{{mile}}token.
657-665: LGTM!The Estonian
socialLinkstranslations are well-formed and use appropriate phrasing for the language.packages/visual-editor/locales/platform/sv/visual-editor.json (2)
548-553: LGTM!Swedish pluralization (
mil/milbeing identical) is grammatically correct. Note that the Swedish "mil" traditionally refers to the Scandinavian mile (~10 km) rather than the English mile (~1.6 km), but this is a localization decision that may be intentional depending on the target audience.
658-666: LGTM!The Swedish
socialLinkstranslations are well-formed and use natural phrasing.packages/visual-editor/locales/platform/ja/visual-editor.json (3)
62-66: LGTM!The translations for
close,closed, andclosesAtare appropriate Japanese translations for these status-related terms.
560-560: LGTM!The status translations (
openNow,temporarilyClosed) and preset image labels are correctly translated. Brand names (Apple, Galaxy Store, Uber Eats) are appropriately kept in their original English form, which is the standard practice for brand recognition in Japanese localization.Also applies to: 576-608, 668-668
750-750: LGTM!The
totalReviews_othertranslation is correct. Using the_othersuffix is the appropriate i18next pattern for Japanese, which doesn't have grammatical number distinctions.packages/visual-editor/locales/platform/sk/visual-editor.json (4)
546-549: LGTM - Mile token integration follows proper i18n patterns.The separation of
{{distance}}and{{mile}}tokens allows for proper pluralization of distance units independently from location counts. This correctly handles Slovak's complex plural forms.
666-674: LGTM - Social links translations are well structured.The translations appropriately use "Sledujte nás na" (Follow us on) for social platforms and "Prihláste sa na odber" (Subscribe to) for YouTube, reflecting the different user actions expected on each platform.
763-766: LGTM - Slovak plural forms for reviews are correct.The pluralization follows proper Slovak grammar: "recenzia" (singular), "recenzie" (2-4), and "recenzií" (5+/genitive plural).
551-551: LGTM - Corrected "map" translation.Changed from "Mapovať" (verb form meaning "to map") to "Mapa" (noun meaning "map"), which is the correct translation for a map UI element label.
packages/visual-editor/locales/platform/nb/visual-editor.json (5)
85-85: LGTM!Email-related translations are consistent and use the correct Norwegian term "E-post" throughout.
Also applies to: 165-165, 227-230
541-542: LGTM!The
{{mile}}token integration for distance-based strings is implemented correctly, allowing dynamic plural form injection.Also applies to: 552-552
580-580: LGTM!Brand names are correctly capitalized ("Apple", "Uber Eats") following proper trademark conventions.
Also applies to: 612-612
657-665: LGTM!Social links translations are well-structured with appropriate Norwegian phrasing. The YouTube entry correctly uses "Abonner" (Subscribe) rather than "Følg" (Follow), and the X/Twitter branding is properly handled.
509-509: LGTM!Translations for "heroBanner" → "Heltebanner" and "next" → "Neste" are correct.
Also applies to: 602-602
packages/visual-editor/locales/platform/tr/visual-editor.json (4)
541-548: LGTM!The new
mile_one/mile_othertokens and updatedlocationsWithinDistanceOftranslations correctly preserve placeholders. Using "mil" for both singular and plural forms is appropriate for Turkish, as quantity is expressed via the numeral rather than noun inflection.
552-552: LGTM!The
{{mile}}placeholder is correctly integrated, allowing dynamic unit display consistent with the i18n refactor.
657-665: LGTM!The new
socialLinksblock provides appropriate Turkish translations with correct locative suffixes for each platform. The YouTube entry appropriately uses "subscribe" phrasing rather than "follow."
561-623: LGTM!UI string updates are correct. Arrow direction translations, brand name preservation (Figma, Galaxy Store), and Turkish phrasing for status messages and actions are appropriate.
packages/visual-editor/locales/platform/nl/visual-editor.json (3)
550-551: LGTM! Pluralization and template variable usage is correct.The
mile_one/mile_otherkeys correctly handle Dutch pluralization ("mijl" vs. "mijlen"), and the{{mile}}interpolation inlocationsWithinDistanceOf_*andnearbyLocationsEmptyStateis properly consistent.Also applies to: 556-557, 561-561
763-764: LGTM! Review count pluralization is correct.The
totalReviews_one("recensie") andtotalReviews_other("recensies") properly handle Dutch singular/plural forms.
1-775: Overall translation file looks good.The Dutch translations appear linguistically appropriate, JSON structure is valid, and the i18next pluralization conventions (
_one,_other) are correctly applied for the Dutch locale.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @packages/visual-editor/locales/platform/ja/visual-editor.json:
- Line 548: The translation key nearbyLocationsEmptyState contains a malformed
placeholder "{{mile} }" which breaks i18n interpolation; update the value so
each mustache placeholder is properly formed (e.g., change "{{mile} }" to
"{{mile}}") and verify the other placeholders ("{{radius}}", "{{entityType}}")
are correctly formatted with no extra spaces.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (9)
packages/visual-editor/src/components/testing/screenshots/BreadcrumbsSection/[tablet] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/BreadcrumbsSection/[tablet] version 4 props.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/BreadcrumbsSection/[tablet] version 8 with non-default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[desktop] [compact] version 17 props using constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/HeroSection/[xl] [compact] version 31 props with constant values.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] default props with document data (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] default props with document data.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with French locale (after interactions).pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**packages/visual-editor/src/components/testing/screenshots/ReviewsSection/[desktop] version 10 props with French locale.pngis excluded by!**/*.png,!packages/visual-editor/src/components/testing/screenshots/**
📒 Files selected for processing (11)
packages/visual-editor/locales/components/da/visual-editor.jsonpackages/visual-editor/locales/components/ja/visual-editor.jsonpackages/visual-editor/locales/components/nb/visual-editor.jsonpackages/visual-editor/locales/components/sk/visual-editor.jsonpackages/visual-editor/locales/components/tr/visual-editor.jsonpackages/visual-editor/locales/platform/da/visual-editor.jsonpackages/visual-editor/locales/platform/ja/visual-editor.jsonpackages/visual-editor/locales/platform/nb/visual-editor.jsonpackages/visual-editor/locales/platform/nl/visual-editor.jsonpackages/visual-editor/locales/platform/sk/visual-editor.jsonpackages/visual-editor/locales/platform/tr/visual-editor.json
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/visual-editor/locales/components/sk/visual-editor.json
- packages/visual-editor/locales/platform/nb/visual-editor.json
- packages/visual-editor/locales/components/tr/visual-editor.json
- packages/visual-editor/locales/platform/da/visual-editor.json
- packages/visual-editor/locales/components/da/visual-editor.json
- packages/visual-editor/locales/components/ja/visual-editor.json
⏰ 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). (5)
- GitHub Check: call_unit_test / unit_tests (22.x)
- GitHub Check: call_unit_test / unit_tests (24.x)
- GitHub Check: call_unit_test / unit_tests (20.x)
- GitHub Check: create-dev-release
- GitHub Check: semgrep/ci
🔇 Additional comments (17)
packages/visual-editor/locales/components/nb/visual-editor.json (1)
1-113: LGTM! Norwegian locale file structure is correct.The JSON structure is valid, pluralization suffixes follow i18next conventions (
_one,_other), and interpolation placeholders are consistent across plural forms.Minor observation: There's some terminology variation for "location" across different keys (
plassering,lokasjoner,sted,steder). This may be intentional for natural Norwegian phrasing in different contexts, but consider verifying with a native speaker for consistency if desired.packages/visual-editor/locales/platform/sk/visual-editor.json (5)
554-557: Slovak pluralization for "mile" looks correct.The four plural forms follow Slovak grammar rules:
mile_one: "míľa" (1)mile_few: "míle" (2-4)mile_many: "míľ" (5+, decimals)mile_other: "míľ" (fallback)This pattern correctly handles Slovak noun declension for distance units.
546-549: Good use of interpolated{{mile}}token for noun-number agreement.Using a separate pluralized token for "mile" that gets interpolated into the distance strings is the correct approach for Slavic languages where nouns must agree with numbers in grammatical form. This allows:
locationsWithinDistanceOf_*to focus on location count pluralizationmile_*to handle the distance unit pluralization independentlyThis is cleaner than trying to handle compound pluralization in a single string.
Also applies to: 561-561
763-766: Review pluralization for "totalReviews".The Slovak pluralization appears correct:
totalReviews_one: "{{count}} recenzia"totalReviews_few: "{{count}} recenzie"totalReviews_many: "{{count}} recenzií"totalReviews_other: "{{count}} recenzií"The feminine noun "recenzia" correctly declines through its plural forms.
666-674: NewsocialLinksobject with accessible labels.The social media follow prompts are well-structured and provide meaningful accessible labels for screen readers (e.g., "Sledujte nás na Facebooku" = "Follow us on Facebook").
1-777: LGTM - Slovak localization file is well-structured.The translation file correctly implements:
- Valid JSON structure
- Proper Slovak plural forms (one/few/many/other) for i18next
- Consistent
{{placeholder}}interpolation syntax- New keys for social links, distance units, and UI elements
No issues identified with the localization changes.
packages/visual-editor/locales/platform/nl/visual-editor.json (5)
66-66: LGTM!The translation updates are consistent:
getDirectionsis uniformly translated to "Routebeschrijving" across all three occurrences (lines 106, 150, 508)- Hero-related keys are now properly localized to Dutch ("Heldenbanner", "Held koptekst", "Heldenbeeld") instead of the previous English-based translations
closesAtupdate to "Sluit om" is more natural Dutch phrasingAlso applies to: 106-106, 150-150, 508-511
541-542: LGTM!The mile pluralization implementation is well-structured:
mile_one("mijl") andmile_other("mijlen") provide proper Dutch singular/plural forms- Using the
{{mile}}token inlocationsWithinDistanceOfandnearbyLocationsEmptyStateallows i18next to select the correct plural form based on the distance value- This pattern correctly decouples the noun pluralization from the containing sentence
Also applies to: 547-548, 552-552
578-612: LGTM!Brand names are appropriately preserved ("App Store", "Apple", "Dribbble", "Galaxy Store", "Uber Eats") while generic UI terms are correctly translated to Dutch ("Vinkje", "Sluiten", "Afspelen"). The "Uber Eats" correction from the previous "Uber eet" is appropriate as it's a brand name.
657-665: LGTM!The socialLinks block is well-structured with consistent Dutch phrasing. Good attention to platform-specific conventions: YouTube uses "Abonneer je" (Subscribe) rather than "Volg" (Follow), which is the appropriate action for that platform. The
xLinkentry helpfully includes both "X" and "Twitter" for user clarity.
754-755: LGTM!The
totalReviewspluralization correctly uses Dutch singular ("recensie") and plural ("recensies") forms with the{{count}}placeholder.packages/visual-editor/locales/platform/tr/visual-editor.json (5)
541-542: LGTM! Mile-based distance keys properly added.The Turkish translations correctly use different grammatical structures for the singular and plural forms:
_one: Uses'a(dative suffix) with "mesafede"_other: Uses'den(ablative suffix) with "uzaklıktaki"This follows proper Turkish grammar conventions for attaching suffixes to quoted text.
547-548: LGTM! Turkish pluralization is correct.Both
mile_oneandmile_othertranslate to "mil" — this is correct because Turkish nouns typically don't change form when preceded by a numeral.
552-552: LGTM! Empty state message updated with mile placeholder.The template now uses
{{radius}} {{mile}}for dynamic distance display, aligning with the mile-based terminology introduced across other locales.
657-665: LGTM! Social links block added with proper Turkish translations.The new
socialLinksobject provides accessible aria labels for social media links. The translations appropriately localize "Follow us on..." and "Subscribe to our YouTube channel" to Turkish.
754-755: LGTM! Turkish plural forms are consistent.Both
totalReviews_oneandtotalReviews_otherusing "inceleme" is correct for Turkish, as the noun form doesn't change based on count when preceded by a numeral.packages/visual-editor/locales/platform/ja/visual-editor.json (1)
62-66: LGTM!The remaining translation updates look good:
- Hour-related strings (
close,closed,closesAt,openNow,temporarilyClosed) are contextually appropriate.- The
mile_otherandlocationsWithinDistanceOf_otherkeys properly support the new mile-based placeholders.- Brand names (Apple, Galaxy Store, Uber Eats) are correctly kept in English.
- The
socialLinksobject provides proper Japanese translations for social media follow prompts.- Pluralization keys (
totalReviews_other) follow i18next conventions.Also applies to: 539-544, 560-560, 576-576, 589-590, 594-594, 601-601, 608-608, 653-661, 668-668, 750-750
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.