Skip to content

Comments

feat: add default data for all locales (draft)#1044

Open
asanehisa wants to merge 2 commits intomainfrom
default-locales
Open

feat: add default data for all locales (draft)#1044
asanehisa wants to merge 2 commits intomainfrom
default-locales

Conversation

@asanehisa
Copy link
Contributor

@asanehisa asanehisa commented Feb 12, 2026

Intent:

  1. Add utilities for localized default content
  • defaultText and defaultRichText now build translatable defaults for all supported locales.
  • defaultRichText now generates consistent html + json per locale using getDefaultRTF.
  • packages/visual-editor/src/utils/defaultContent.ts
  1. Replace hardcoded { en, hasLocalizedValue } defaults across components
  • Many components now call defaultText(...) / defaultRichText(...) instead of embedding en only defaults.
  • This makes new components/sections start with locale-populated values (when you drag them into Editor).
  1. Inject translated defaults only for untouched template layouts (during Pages Generation step in transformProps)
  • Before migration/resolve, check if layout still matches canonical template defaults.
  • If untouched, inject missing locale values from default registries.
  • If edited, do nothing (preserve user customizations).
  1. Add to i18n workflow

@asanehisa asanehisa added the create-dev-release Triggers dev release workflow label Feb 12, 2026
@github-actions
Copy link
Contributor

Warning: Component files have been updated but no migrations have been added. See https://github.com/yext/visual-editor/blob/main/packages/visual-editor/src/components/migrations/README.md for more information.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 12, 2026

commit: f40821e

@asanehisa asanehisa force-pushed the default-locales branch 9 times, most recently from 8456bb9 to a83f797 Compare February 12, 2026 20:49
@asanehisa asanehisa changed the title feat: test (draft) feat: add default data for all locales Feb 13, 2026
@asanehisa asanehisa changed the title feat: add default data for all locales feat: add default data for all locales (draft) Feb 13, 2026
@asanehisa asanehisa marked this pull request as ready for review February 13, 2026 21:03
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

Walkthrough

This PR introduces a centralized i18n infrastructure for component default text values in the visual-editor. It creates utility functions (defaultText and defaultRichText) that dynamically fetch locale-specific defaults from a registry built from JSON locale files. The PR refactors 40+ component files to replace inline hardcoded localized objects with calls to these utilities. It also implements a template layout injection system that applies default translations to template layouts when appropriate. Translation generation scripts are extended to support a new "componentDefaults" scope, and componentDefaults translation keys are populated across all supported locales.

Sequence Diagram

sequenceDiagram
    participant Component
    participant defaultText as defaultText()
    participant Registry as componentDefaultRegistry
    participant Locales as Locale JSON Files
    participant Editor as Editor/Templates

    Component->>defaultText: defaultText(key, enDefault)
    defaultText->>Registry: Query registry for locale
    Registry->>Locales: Loaded from JSON on build
    Registry-->>defaultText: Return locale-specific value or fallback
    defaultText-->>Component: TranslatableString with localized values
    
    Editor->>Editor: Parse template layout
    Editor->>Editor: Check if layout matches default
    alt Layout is default
        Editor->>Editor: processTemplateLayoutData()
        Editor->>defaultText: Get localized defaults for each key
        defaultText->>Registry: Query for target locales
        Registry-->>defaultText: Return localized values
        Editor->>Editor: Inject localized values into layout
    else Layout is custom/edited
        Editor->>Editor: Skip injection
    end
    Editor-->>Component: Resolved layout with translations
Loading

Possibly related PRs

Suggested reviewers

  • mkilpatrick
  • benlife5
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding default data for all locales to enable localized defaults across components.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, outlining the intent, key changes, and follow-up TODOs for adding localized default content utilities.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch default-locales

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/component-defaults/fr/visual-editor.json`:
- Around line 1-7: The localized heading in aboutSection.heading uses the
translated placeholder "[[nom]]" which likely won't resolve because the code
expects the language-independent entity field placeholder "[[name]]"; update the
FR locale string to use the same placeholder token the component expects
(replace "[[nom]]" with "[[name]]") and verify AboutSection.tsx's interpolation
logic still finds and replaces [[name]] (or adjust the component if it expects a
different token), ensuring placeholder tokens remain consistent across locales
and the AboutSection.tsx rendering path.

In `@packages/visual-editor/locales/component-defaults/zh-TW/visual-editor.json`:
- Line 3: The locale entry under the "heading" key uses a translated placeholder
`[[姓名]]` which breaks the embedded-field resolver that expects ASCII field keys
via the regex /\[\[([a-zA-Z0-9._]+)\]\]/g; change the placeholder to the
canonical field key `[[name]]` (i.e., "heading": "關於[[name]]") and audit other
locale files for translated placeholders like `[[nome]]`, `[[namn]]`,
`[[naam]]`, `[[isim]]`, replacing them with the canonical `[[name]]` so the
resolver (which matches ASCII field identifiers) can correctly substitute
values.

In `@packages/visual-editor/scripts/generateComponentDefaultTranslations.ts`:
- Around line 168-194: The placeholder tokens like [[name]] must be protected
before calling translateText and restored afterwards; in the missingKeys async
handler (inside the Promise.allSettled loop) wrap any [[...]] placeholders in
the source string into safe temporary tokens, call translateText on the
tokenized text, then replace tokens back into the translated result (and also
apply removeEmbeddedContext if a context was embedded) before saving to
defaultsCache; ensure this tokenization/restoration runs regardless of whether
extractContextFromKey returned a context so placeholders are never sent raw to
the translation API (refer to functions/vars: extractContextFromKey,
embedContextInText, removeEmbeddedContext, translateText, defaultsCache,
missingKeys).

In
`@packages/visual-editor/src/components/pageSections/AboutSection/AboutSection.tsx`:
- Around line 206-209: Locale placeholder identifiers were translated (e.g., fr:
[[nom]]) which breaks findField() lookup because entity properties are
language-agnostic and expect the English property name; update all locale files
so aboutSection.heading uses the placeholder [[name]] (the constantValue passed
to defaultText in AboutSection.tsx) and scan other sections for similarly
translated placeholders (e.g., [[name]] vs [[nombre]]/[[Name]]) and normalize
them to the English property identifiers so findField() can resolve
document.name correctly.

In
`@packages/visual-editor/src/components/pageSections/EventSection/EventCard.tsx`:
- Around line 42-45: The missing localization key eventCard.description
referenced by defaultRichText("eventCard.description", ...) must be added to
every locale; update each locale's translation object (e.g., the en, zh, zh-TW,
es, tr, sk locale files) to include an eventCard.description entry with the
proper translated string (or confirm intentionally left in English), so that the
EventCard component's defaultRichText lookup finds a locale value instead of
always falling back to the English default.

In `@packages/visual-editor/src/components/pageSections/FAQsSection/FAQCard.tsx`:
- Around line 25-32: The locale files are missing the faqCard.question and
faqCard.answer keys used by defaultRichText, so add these two keys to every
locale object under the faqCard namespace (faqCard.question and faqCard.answer)
with appropriate localized rich-text strings (or copy the English fallback
content) so defaultRichText("faqCard.question", ...) and
defaultRichText("faqCard.answer", ...) can resolve for all locales; ensure the
keys match the same structure/format used by other rich-text translations so the
FAQCard component reads them correctly.

In
`@packages/visual-editor/src/components/pageSections/ProfessionalHeroSection.tsx`:
- Around line 727-730: The secondary CTA `link` is a URL but is wrapped with the
translation helper defaultText("professionalHeroSection.secondaryCtaLink", "#"),
which will send the placeholder "#" into the i18n pipeline; change the
assignment for `link` in ProfessionalHeroSection (the secondary CTA object where
`link: defaultText("professionalHeroSection.secondaryCtaLink", "#")`) to a plain
string (`link: "#"`) like the primary CTA so the URL is not translated.

In `@packages/visual-editor/src/utils/resolveYextEntityField.ts`:
- Around line 113-166: The fallback branch inside resolveYextEntityField
currently returns raw strings or inner objects when locale is missing; change
those to return the full translatable object shape like the locale-present
branch: for TranslatableString use return { ...data, en:
resolveEmbeddedFieldsInString(data.en, streamDocument, locale) }, for
TranslatableRichText use return { ...data, en: { ...data.en, html:
resolveEmbeddedFieldsInString(data.en.html, streamDocument, locale) } }, and for
the final missing case return the original data object (not an empty string);
keep use of resolveEmbeddedFieldsInString and preserve hasLocalizedValue and
other existing fields on data.

In `@packages/visual-editor/src/vite-plugin/templates/locator.tsx`:
- Around line 107-123: The call to processTemplateLayoutData passes layoutData
as a positional property name but the function expects rawLayoutData; update the
options object in the locator template where processTemplateLayoutData is
invoked (the block that currently sets layoutData and resolvedPuckData) to pass
rawLayoutData: layoutData so rawLayoutData is populated correctly; ensure the
rest of the call (streamDocument: document, templateId: "locator",
buildProcessedLayout using migrate and resolveAllData with locatorConfig)
remains unchanged.

In `@packages/visual-editor/src/vite-plugin/templates/main.tsx`:
- Around line 109-125: The call to processTemplateLayoutData is passing
layoutData instead of the required rawLayoutData, causing rawLayoutData to be
undefined; update the object passed to processTemplateLayoutData in main.tsx
(and replicate the same change in locator.tsx and directory.tsx) to use
rawLayoutData: layoutData while keeping the other properties (streamDocument:
document, templateId: "main", buildProcessedLayout: async () => { const
migratedData = migrate(layoutData, migrationRegistry, mainConfig, document);
return await resolveAllData(migratedData, mainConfig, { streamDocument: document
}); }). Ensure the symbol names layoutData, rawLayoutData,
processTemplateLayoutData, migrate, resolveAllData, migrationRegistry,
mainConfig, and document are used exactly as shown.
🟡 Minor comments (17)
packages/visual-editor/locales/component-defaults/pl/visual-editor.json-8-11 (1)

8-11: ⚠️ Potential issue | 🟡 Minor

Fix incorrect Polish translation: "header": "Chodnikowiec" should be "Nagłówek"

The English source for this field is "header": "Header". The Polish translation "Chodnikowiec" (sidewalk/pavement) is semantically incorrect. The proper Polish equivalent for "Header" in this context is "Nagłówek" (header/heading).

packages/visual-editor/src/utils/resolveComponentData.tsx-144-150 (1)

144-150: ⚠️ Potential issue | 🟡 Minor

Avoid treating intentional empty translations as missing.
!value[locale] falls back to English even if the locale key exists but is intentionally empty. Consider falling back only when the locale value is null/undefined.

Suggested fix
-  if (value.hasLocalizedValue === "true" && !value[locale]) {
-    const fallbackValue = value.en ?? "";
+  const localizedValue = value[locale];
+  if (value.hasLocalizedValue === "true" && localizedValue == null) {
+    const fallbackValue = value.en ?? "";
     if (isRichText(fallbackValue)) {
       return toStringOrElement(fallbackValue);
     }
     return fallbackValue;
   }
packages/visual-editor/locales/component-defaults/sk/visual-editor.json-74-76 (1)

74-76: ⚠️ Potential issue | 🟡 Minor

Untranslated "Insights" string in Slovak locale.

insightSection.sectionHeading is left in English while other sectionHeading values in the same file are properly translated (e.g., nearbyLocations.sectionHeading → "Polohy v okolí", photoGallery.sectionHeading → "Galéria"). Provide Slovak translation to match the pattern.

packages/visual-editor/locales/component-defaults/hu/visual-editor.json-74-76 (1)

74-76: ⚠️ Potential issue | 🟡 Minor

"Insights" left untranslated in Hungarian.

Line 75 has the English word "Insights" instead of a Hungarian translation (e.g., "Betekintések" or "Elemzések"). This was likely missed during automated translation.

packages/visual-editor/locales/component-defaults/hu/visual-editor.json-3-3 (1)

3-3: ⚠️ Potential issue | 🟡 Minor

Likely mistranslation: "Körülbelül" means "approximately", not "about (regarding)".

In Hungarian, "Körülbelül" conveys numerical approximation ("approximately"), not "about" in the sense of "regarding" or "information about." A more appropriate translation for "About [[name]]" would be something like "A(z) [[név]]-ról/ről" or "Rólunk" depending on context. This appears to be a machine-translation artifact.

packages/visual-editor/locales/component-defaults/nb/visual-editor.json-54-55 (1)

54-55: ⚠️ Potential issue | 🟡 Minor

Several Norwegian strings left untranslated in English.

Lines 55, 91, and 93 contain English text ("Header Link", "Call to Action") while the rest of the file is translated to Norwegian. These appear to be missed by the translation script.

Also applies to: 89-94

packages/visual-editor/locales/component-defaults/fi/visual-editor.json-134-136 (1)

134-136: ⚠️ Potential issue | 🟡 Minor

Potentially awkward Finnish translation for "Featured Testimonials".

"Suositellut suosittelut" appears redundant — it roughly reads as "Recommended recommendations." Consider having a native Finnish speaker review this translation.

packages/visual-editor/locales/component-defaults/da/visual-editor.json-18-20 (1)

18-20: ⚠️ Potential issue | 🟡 Minor

Untranslated strings: directoryRoot values remain in English.

Both breadcrumbs.directoryRoot (Line 19) and directory.directoryRoot (Line 32) are still "Directory Root" in English instead of Danish. Similarly, footer.sectionLabel on Line 52 is "Footer label" rather than a Danish translation. These appear to be machine translation gaps.

Also applies to: 31-33

packages/visual-editor/locales/component-defaults/et/visual-editor.json-74-76 (1)

74-76: ⚠️ Potential issue | 🟡 Minor

Untranslated string: insightSection.sectionHeading is still in English.

This value remains "Insights" while all other strings in this file are translated to Estonian. Other locale files have this translated (e.g., German: "Einblicke", Czech: "Postřehy", Danish: "Indsigt"). The Estonian equivalent would be something like "Ülevaated".

packages/visual-editor/locales/component-defaults/de/visual-editor.json-27-30 (1)

27-30: ⚠️ Potential issue | 🟡 Minor

Mistranslation: "Taste" means keyboard key, not UI button.

"Taste" is used throughout this file for button labels (lines 29, 39, 63, 65, 69, 90, 92, 97, 109, 113, 118, 123), but in German it refers to a physical keyboard key. The standard German UI term is "Button" (widely adopted loanword) or "Schaltfläche". This affects all buttonText, primaryButtonText, and secondaryButtonText entries.

packages/visual-editor/locales/component-defaults/ja/visual-editor.json-1-137 (1)

1-137: ⚠️ Potential issue | 🟡 Minor

Machine-translated strings contain notable mistranslations.

A few entries stand out as incorrect or awkward:

  1. Line 6"socialHeader": "私たちに従ってください": "従う" means "obey/comply", not "follow" in the social-media sense. Consider "フォローしてください" or "ソーシャルメディア".
  2. Line 125"name": "最初から最後まで": The English source "First Last" is a placeholder name (like "John Doe"), but this was translated as "From beginning to end". It should be a Japanese placeholder name, e.g. "姓 名" or "山田 太郎".
  3. Line 115"subtitle": "字幕": "字幕" means movie/video subtitles. For a secondary heading, "サブタイトル" is more appropriate.

Since these defaults are user-facing in the editor, consider having a native speaker review the machine-translated files — especially for languages where placeholder names and UI idioms don't translate literally.

packages/visual-editor/locales/component-defaults/es/visual-editor.json-122-127 (1)

122-127: ⚠️ Potential issue | 🟡 Minor

Same placeholder-name mistranslation as the Japanese file.

Line 125 — "name": "Primero último" literally translates "First Last" word-by-word, but the intent is a placeholder person name (like "John Doe"). A more natural Spanish equivalent would be "Nombre Apellido" or a culturally common placeholder like "Juan Pérez".

packages/visual-editor/locales/component-defaults/es/visual-editor.json-77-79 (1)

77-79: ⚠️ Potential issue | 🟡 Minor

Capitalization inconsistency: "encontrar una ubicación" should be title-cased.

Line 78 — Other headings in this file use sentence case with an initial capital (e.g., "Próximos eventos", "Preguntas frecuentes"), but this one starts lowercase. Should be "Encontrar una ubicación".

Proposed fix
   "locator": {
-    "pageHeadingTitle": "encontrar una ubicación"
+    "pageHeadingTitle": "Encontrar una ubicación"
   },
packages/visual-editor/locales/component-defaults/zh/visual-editor.json-46-46 (1)

46-46: ⚠️ Potential issue | 🟡 Minor

Missing empty faqCard key present in the English baseline.

The en locale file has "faqCard": {} but it's absent here. Minor inconsistency — harmless since it's empty, but worth keeping in sync for the translation diff tooling.

packages/visual-editor/locales/component-defaults/en/visual-editor.json-65-65 (1)

65-65: ⚠️ Potential issue | 🟡 Minor

Inconsistent capitalization of "Call to Action" vs "Call To Action".

heroSection.primaryCtaLabel (line 65) uses "Call To Action" (Title Case) while primaryHeader.primaryCtaLabel (line 92) uses "Call to Action" (lowercase "to"). These serve the same purpose as default CTA labels — consider normalizing.

Also applies to: 92-92

packages/visual-editor/locales/component-defaults/zh/visual-editor.json-115-115 (1)

115-115: ⚠️ Potential issue | 🟡 Minor

Incorrect Chinese translation for "subtitle".

"字幕" means video captions/subtitles, not a heading subtitle. The correct term in a UI/heading context is "副标题".

Proposed fix
-    "subtitle": "字幕"
+    "subtitle": "副标题"
packages/visual-editor/locales/component-defaults/sv/visual-editor.json-115-115 (1)

115-115: ⚠️ Potential issue | 🟡 Minor

Questionable machine translation: "subtitle": "Texta".

"Texta" in Swedish means "to text (someone)" or "to subtitle (a film)". For a UI label representing a subtitle/subheading, "Underrubrik" or "Undertitel" would be more appropriate. This is likely a Google Translate artifact. Since the PR TODO mentions testing with more locales, this may get caught in a review pass of all translations.

🧹 Nitpick comments (7)
packages/visual-editor/locales/component-defaults/pl/visual-editor.json (1)

131-136: Minor translation quality: "referencje" used for "testimonials".

"Referencje" (Line 132, 135) more closely maps to "references" in Polish. A more natural translation for "testimonials" would be "opinie" or "rekomendacje". Similarly, on Line 107, "credentials" is rendered as "Referencje" which is a different meaning. Since these are auto-generated via Google Translate (per PR description), a quick human review pass on the Polish file would catch these semantic mismatches.

packages/visual-editor/src/components/footer/SecondaryFooterSlot.tsx (1)

11-16: Import and reuse defaultLink from ExpandedFooter.tsx to avoid duplication.

This local defaultLink is identical to the export in ExpandedFooter.tsx (same key "footer.linkLabel", same shape). FooterExpandedLinkSectionSlot.tsx already imports it from there, confirming the import path works and the export is intended for reuse. Consolidating to the shared export prevents drift if the default link structure changes.

♻️ Suggested refactor
-import { defaultText } from "../../utils/defaultContent.ts";
-
-const defaultLink = {
-  linkType: "URL" as const,
-  label: defaultText("footer.linkLabel", "Footer Link"),
-  link: "#",
-  openInNewTab: false,
-};
+import { defaultLink } from "./ExpandedFooter.tsx";
packages/visual-editor/locales/component-defaults/zh/visual-editor.json (1)

125-125: Consider a more natural Chinese name placeholder.

"第一个 最后一个" is a literal translation of "First Last" but reads unnaturally in Chinese. A conventional placeholder like "张三" (the Chinese equivalent of "John Doe") would be more idiomatic.

packages/visual-editor/scripts/generateComponentDefaultTranslations.ts (2)

98-125: Unofficial Google Translate API endpoint is unreliable and has no rate-limiting.

The client=gtx endpoint is an undocumented, free API that Google can rate-limit or block without notice. Combined with Promise.allSettled on Line 171 firing all missing keys concurrently, this can trigger rate limits or IP bans during bulk translation runs.

Consider:

  1. Using the official Cloud Translation API with an API key.
  2. Adding concurrency control (e.g., batching or a semaphore) to limit parallel requests.

18-39: extractContextFromKey uses _ separator but flattened keys use . — context feature is effectively dead code.

flatten produces keys like "aboutSection.heading". Since extractContextFromKey splits on "_" (CONTEXT_SEPARATOR), it will never find a multi-part key in the current schema. The embedContextInText / removeEmbeddedContext functions are therefore never invoked. If this is intentional scaffolding for future use, consider adding a comment. Otherwise, the separator should align with the actual key format.

packages/visual-editor/src/utils/defaultLayoutTranslations.ts (2)

189-226: Static analysis: forEach callback implicitly returns — use for...of to satisfy the linter.

Biome flags Line 191 because forEach callbacks shouldn't return values, even though injectLocalizedValues is void. Switching to for...of silences the lint and is more idiomatic for side-effect-only loops.

Suggested fix
 const injectLocalizedValues = (node: unknown, locales: string[]): void => {
   if (Array.isArray(node)) {
-    node.forEach((item) => injectLocalizedValues(item, locales));
+    for (const item of node) {
+      injectLocalizedValues(item, locales);
+    }
     return;
   }

125-152: Ambiguous English values (e.g., "Button") will silently skip injection.

The reverse-mapping approach via enValueToKeys means any English string used by multiple component keys (like "Button" for both ctaWrapper.buttonText and eventCard.buttonText) where those keys happen to have different locale translations will cause candidateValues.size !== 1, returning undefined and skipping injection for that value.

This is a safe design choice, but it could result in many common defaults (e.g., "Button", "Phone", "Text") not being injected. Consider logging a debug-level message when ambiguity is detected to help diagnose missing translations during development.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/component-defaults/et/visual-editor.json`:
- Around line 74-76: The key insightSection.sectionHeading is still in English
("Insights"); update its value to the proper Estonian translation (for example
"Ülevaated" or "Teadmised") in the visual-editor.json so the locale file
contains the localized string for insightSection.sectionHeading.

In `@packages/visual-editor/locales/component-defaults/fi/visual-editor.json`:
- Around line 134-136: The Finnish translation for
testimonialSection.sectionHeading currently reads "Suositellut suosittelut",
which is awkwardly repetitive; update the value of
"testimonialSection"."sectionHeading" to a clearer phrase such as "Esitellyt
suosittelut" or "Suositellut suositukset" (pick the one that best fits the UI
context) to remove the near-duplicate wording and improve readability.
- Around line 105-116: In the professionalHeroSection locale object, fix two
Finnish translation errors: change the value of professionalName from
"Ammattilainen nimi" to the correct genitive form "Ammattilaisen nimi", and
change subtitle from "Tekstitys" to a more appropriate heading term like
"Alaotsikko"; update these keys (professionalHeroSection.professionalName and
professionalHeroSection.subtitle) in the JSON so the translations read
correctly.

In `@packages/visual-editor/locales/component-defaults/fr/visual-editor.json`:
- Line 36: Multiple keys use an inconsistent French translation for "Learn more"
— replace the non-idiomatic "Apprendre encore plus" with the idiomatic "En
savoir plus" for all relevant keys (e.g., textAndLinkLabel, insightCard.ctaLabel
and the other occurrences noted) so the translations are consistent across the
JSON; update each string value to "En savoir plus" while preserving the
surrounding JSON structure and keys.

In `@packages/visual-editor/locales/component-defaults/hu/visual-editor.json`:
- Around line 74-76: The JSON value for insightSection.sectionHeading is left in
English ("Insights"); update that value to a Hungarian translation (for example
"Betekintések" or "Cikkek") so it matches the rest of the locale file, ensuring
the key "insightSection" and its nested "sectionHeading" are preserved and only
the string value is changed.

In `@packages/visual-editor/locales/component-defaults/ja/visual-editor.json`:
- Around line 122-127: The translation for the placeholder name is incorrect:
replace the literal translation "最初から最後まで" under the teamCard.name key with a
proper Japanese placeholder for a person’s name (e.g., "姓 名" or "山田 太郎") so it
reads as a name placeholder rather than "from start to finish"; update the
teamCard.name value accordingly and scan other locale files generated by the
translation script for similar literal translations of "First Last" (e.g.,
Lithuanian/Estonian) to apply the same fix.
- Around line 3-6: The translation for the "socialHeader" key is too literal and
directive; update the value for "socialHeader" in the JSON (key: "socialHeader")
to a more natural social-media phrasing such as "フォローしてください" or "SNSでフォロー" so it
reads appropriately as "Follow Us" in Japanese.

In `@packages/visual-editor/src/utils/defaultLayoutTranslations.ts`:
- Around line 19-23: defaultLayoutsByTemplate currently parses JSON at module
load using JSON.parse on defaultLayoutData.main/directory/locator which will
throw and crash imports if any blob is malformed; change this to either wrap
each JSON.parse call in a try/catch that falls back to a safe default and logs
the error, or lazy-initialize parsing (e.g., replace the module-level object
with a getter/factory that parses on first access and handles parse failures).
Update references to defaultLayoutsByTemplate so consumers still get the same
shape (use VisualEditorTemplateId keys) while ensuring malformed JSON does not
throw during import.
🧹 Nitpick comments (4)
packages/visual-editor/src/utils/defaultLayoutTranslations.ts (2)

189-193: forEach callback implicitly returns a value — use for...of instead.

Biome flags this because the arrow in .forEach((item) => injectLocalizedValues(item, locales)) implicitly returns the (void) result. A for...of loop is cleaner and avoids the lint warning.

Suggested fix
 const injectLocalizedValues = (node: unknown, locales: string[]): void => {
   if (Array.isArray(node)) {
-    node.forEach((item) => injectLocalizedValues(item, locales));
+    for (const item of node) {
+      injectLocalizedValues(item, locales);
+    }
     return;
   }

154-170: extractDefaultRichTextInfo only handles a single top-level HTML tag.

The regex /<(strong|span)>(.*?)<\/\1>/i matches only the first <strong> or <span> element. If default rich text ever contains multiple elements or nested tags, this will silently extract only the first match. This is fine if defaults are always simple single-wrapped text, but worth noting as a constraint.

packages/visual-editor/scripts/generateComponentDefaultTranslations.ts (2)

55-98: flatten, unflatten, loadJsonSafe, and saveJson are duplicated from generateTranslations.ts.

These four utilities have near-identical implementations in both scripts. Consider extracting them into a shared module (e.g., scripts/translationUtils.ts) to reduce maintenance burden.


156-184: No concurrency limit on translation API calls.

All missingKeys for a locale are fired concurrently via Promise.allSettled. For locales with many missing keys, this could trigger rate limiting from the Google Translate API. Consider batching or throttling (e.g., processing in chunks of 10–20).

Comment on lines 74 to 76
"insightSection": {
"sectionHeading": "Insights"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

"Insights" left untranslated in Estonian.

insightSection.sectionHeading is still the English word "Insights" rather than an Estonian translation (e.g., "Ülevaated" or "Teadmised"). This was likely missed by the auto-translation step.

🤖 Prompt for AI Agents
In `@packages/visual-editor/locales/component-defaults/et/visual-editor.json`
around lines 74 - 76, The key insightSection.sectionHeading is still in English
("Insights"); update its value to the proper Estonian translation (for example
"Ülevaated" or "Teadmised") in the visual-editor.json so the locale file
contains the localized string for insightSection.sectionHeading.

Comment on lines 105 to 116
"professionalHeroSection": {
"businessName": "Yrityksen nimi",
"credentials": "Valtuustiedot",
"phoneLabel": "Puhelin",
"primaryButtonText": "Painike",
"primaryCtaLabel": "Ota minuun yhteyttä",
"professionalName": "Ammattilainen nimi",
"professionalTitle": "Ammattinimike",
"secondaryButtonText": "Painike",
"secondaryCtaLabel": "Lisätietoja",
"subtitle": "Tekstitys"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor Finnish translation quality issues in professionalHeroSection.

  • Line 111: "Ammattilainen nimi" is grammatically incorrect — it should be "Ammattilaisen nimi" (genitive form) to mean "Professional's name."
  • Line 115: "Tekstitys" means "subtitling" (as in film/TV captions), not a secondary heading. A more appropriate translation would be "Alaotsikko".

These may have been auto-generated; worth a quick review pass with a native speaker or improved prompt.

Suggested fix
-    "professionalName": "Ammattilainen nimi",
+    "professionalName": "Ammattilaisen nimi",
...
-    "subtitle": "Tekstitys"
+    "subtitle": "Alaotsikko"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"professionalHeroSection": {
"businessName": "Yrityksen nimi",
"credentials": "Valtuustiedot",
"phoneLabel": "Puhelin",
"primaryButtonText": "Painike",
"primaryCtaLabel": "Ota minuun yhteyttä",
"professionalName": "Ammattilainen nimi",
"professionalTitle": "Ammattinimike",
"secondaryButtonText": "Painike",
"secondaryCtaLabel": "Lisätietoja",
"subtitle": "Tekstitys"
},
"professionalHeroSection": {
"businessName": "Yrityksen nimi",
"credentials": "Valtuustiedot",
"phoneLabel": "Puhelin",
"primaryButtonText": "Painike",
"primaryCtaLabel": "Ota minuun yhteyttä",
"professionalName": "Ammattilaisen nimi",
"professionalTitle": "Ammattinimike",
"secondaryButtonText": "Painike",
"secondaryCtaLabel": "Lisätietoja",
"subtitle": "Alaotsikko"
},
🤖 Prompt for AI Agents
In `@packages/visual-editor/locales/component-defaults/fi/visual-editor.json`
around lines 105 - 116, In the professionalHeroSection locale object, fix two
Finnish translation errors: change the value of professionalName from
"Ammattilainen nimi" to the correct genitive form "Ammattilaisen nimi", and
change subtitle from "Tekstitys" to a more appropriate heading term like
"Alaotsikko"; update these keys (professionalHeroSection.professionalName and
professionalHeroSection.subtitle) in the JSON so the translations read
correctly.

},
"enhancedCta": {
"getDirectionsLabel": "Obtenir un itinéraire",
"textAndLinkLabel": "Apprendre encore plus"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent translation for "Learn more" across keys.

Some keys use "Apprendre encore plus" (lines 36, 40, 66, 98, 114, 119) while insightCard.ctaLabel on line 71 uses "En savoir plus". The latter is the more idiomatic French for "Learn more"; "Apprendre encore plus" back-translates to "Learn even more." Consider aligning all instances to "En savoir plus" for consistency and accuracy.

Also applies to: 40-40, 66-66, 71-71, 98-98, 114-114, 119-119

🤖 Prompt for AI Agents
In `@packages/visual-editor/locales/component-defaults/fr/visual-editor.json` at
line 36, Multiple keys use an inconsistent French translation for "Learn more" —
replace the non-idiomatic "Apprendre encore plus" with the idiomatic "En savoir
plus" for all relevant keys (e.g., textAndLinkLabel, insightCard.ctaLabel and
the other occurrences noted) so the translations are consistent across the JSON;
update each string value to "En savoir plus" while preserving the surrounding
JSON structure and keys.

Comment on lines 74 to 76
"insightSection": {
"sectionHeading": "Insights"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

"Insights" appears untranslated.

This string is left in English while every other value in the file is localized to Hungarian. Consider translating it (e.g., "Betekintések" or "Cikkek").

🤖 Prompt for AI Agents
In `@packages/visual-editor/locales/component-defaults/hu/visual-editor.json`
around lines 74 - 76, The JSON value for insightSection.sectionHeading is left
in English ("Insights"); update that value to a Hungarian translation (for
example "Betekintések" or "Cikkek") so it matches the rest of the locale file,
ensuring the key "insightSection" and its nested "sectionHeading" are preserved
and only the string value is changed.

Comment on lines 3 to 6
"heading": "[[name]]について",
"hoursHeader": "営業時間",
"servicesHeader": "提供されるサービス",
"socialHeader": "私たちに従ってください"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

"Follow Us" social header translated too literally.

Line 6: "私たちに従ってください" means "Please obey/follow us" in a directive sense. For a social media "Follow Us" context, more natural Japanese would be "フォローしてください" or "SNSでフォロー".

🤖 Prompt for AI Agents
In `@packages/visual-editor/locales/component-defaults/ja/visual-editor.json`
around lines 3 - 6, The translation for the "socialHeader" key is too literal
and directive; update the value for "socialHeader" in the JSON (key:
"socialHeader") to a more natural social-media phrasing such as "フォローしてください" or
"SNSでフォロー" so it reads appropriately as "Follow Us" in Japanese.

Comment on lines 122 to 127
"teamCard": {
"buttonText": "ボタン",
"ctaLabel": "プロフィールにアクセス",
"name": "最初から最後まで",
"title": "アソシエイトエージェント"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Mistranslation: "First Last" placeholder name translated as "最初から最後まで" (From start to finish).

The teamCard.name value "First Last" is a placeholder representing a person's name (first name + last name). The Japanese translation "最初から最後まで" literally means "From start to finish," which is a mistranslation. Consider using a Japanese placeholder name like "姓 名" or "太郎 山田".

The same issue likely affects other locale files generated by the translation script (e.g., Lithuanian has "Pirmas Paskutinis" and Estonian has "Esimene Viimane" which are also literal translations of "First"/"Last").

🤖 Prompt for AI Agents
In `@packages/visual-editor/locales/component-defaults/ja/visual-editor.json`
around lines 122 - 127, The translation for the placeholder name is incorrect:
replace the literal translation "最初から最後まで" under the teamCard.name key with a
proper Japanese placeholder for a person’s name (e.g., "姓 名" or "山田 太郎") so it
reads as a name placeholder rather than "from start to finish"; update the
teamCard.name value accordingly and scan other locale files generated by the
translation script for similar literal translations of "First Last" (e.g.,
Lithuanian/Estonian) to apply the same fix.

@asanehisa asanehisa marked this pull request as draft February 20, 2026 16:27
@asanehisa asanehisa marked this pull request as ready for review February 20, 2026 21:33
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (32)
packages/visual-editor/locales/components/ja/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

"price" uses a USD ($) placeholder in the Japanese locale.

"$123.00" is the English/USD currency format. For Japanese users, "¥12,300" (or at minimum "¥123") would be more natural as a placeholder default. If this value is intentionally locale-agnostic (purely a numeric example), a code comment or documentation note explaining that would help avoid future confusion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/ja/visual-editor.json` at line 57,
The "price" entry in the Japanese locale file (key "price" in
visual-editor.json) currently uses a USD placeholder "$123.00"; update this
value to a Japan-appropriate currency example such as "¥12,300" (or at minimum
"¥123") to match the locale, or if the intention is a locale-agnostic numeric
example, add a brief comment or adjacent metadata clarifying that the
placeholder is intentionally currency-neutral so future contributors won't
change it.
packages/visual-editor/locales/components/ja/visual-editor.json-64-64 (1)

64-64: ⚠️ Potential issue | 🟡 Minor

"字幕" is a mistranslation for "subtitle" in this context.

"字幕" in Japanese specifically refers to video/film subtitles or closed captions, not a UI section subheading. For this component context, "サブタイトル" (loanword, unambiguous) or "小見出し" (small heading) would be more accurate.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/ja/visual-editor.json` at line 64,
The JSON value for the key "subtitle" is currently the incorrect Japanese term
"字幕"; update the value for "subtitle" in
packages/visual-editor/locales/components/ja/visual-editor.json to the correct
UI subheading translation (use "サブタイトル" or "小見出し" — prefer "サブタイトル") and ensure
the change is applied only to the "subtitle" property so other keys remain
untouched.
packages/visual-editor/locales/components/lt/visual-editor.json-61-61 (1)

61-61: ⚠️ Potential issue | 🟡 Minor

Capitalisation mismatch: componentDefaults.readMore vs root-level readMore.

  • Line 61 (componentDefaults): "readMore": "Skaityti Daugiau" — "D" is capitalised.
  • Line 127 (root): "readMore": "Skaityti daugiau" — "d" is lowercase.

Lithuanian capitalisation rules do not capitalise the second word of a phrase, so "Skaityti daugiau" (line 127) is correct. The capital "D" in line 61 appears to be a translation error.

✏️ Proposed fix
-    "readMore": "Skaityti Daugiau",
+    "readMore": "Skaityti daugiau",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/lt/visual-editor.json` at line 61,
The componentDefaults translation key has incorrect capitalization: change
componentDefaults.readMore's value from "Skaityti Daugiau" to match the
root-level "readMore" ("Skaityti daugiau"); update the string for the key named
readMore under componentDefaults in the visual-editor.json so both entries use
the lowercase "d" form.
packages/visual-editor/locales/components/tr/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

price placeholder uses USD ($) in a Turkish locale — consider using TRY () or a locale-neutral symbol.

As a default content placeholder, "123,00$" correctly applies Turkish decimal formatting (comma separator), but the USD currency symbol may feel out of place for tr locale users. Other locale files likely carry the same value; if this is intentionally currency-agnostic, a comment or documentation note would help future translators understand the intent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/tr/visual-editor.json` at line 57,
The "price" JSON placeholder currently uses a USD symbol which is inappropriate
for the Turkish locale; update the "price" value in visual-editor.json to a
Turkey-appropriate format (e.g. "123,00 ₺") or a locale-neutral placeholder
(e.g. "123,00") and, if this value is deliberately currency-agnostic, add a
brief inline comment or documentation note explaining that behavior so
translators know not to change currency symbols; locate the "price" key in the
file and make the replacement and/or add the explanatory comment.
packages/visual-editor/locales/components/hr/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

"price" placeholder references dollars; Croatia has used the Euro since January 2023.

"123,00 dolara" (Croatian genitive of "dollar") is locale-inaccurate for hr. Prefer "123,00 eura" to reflect the current currency.

💶 Proposed fix
-    "price": "123,00 dolara",
+    "price": "123,00 eura",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/hr/visual-editor.json` at line 57,
The "price" translation value in the hr locale is using the outdated currency
"dolar" ("123,00 dolara"); update the "price" string in
packages/visual-editor/locales/components/hr/visual-editor.json for the "price"
key to use Euro phrasing (e.g., "123,00 eura") so the Croatian locale reflects
the current currency.
packages/visual-editor/locales/components/hr/visual-editor.json-30-30 (1)

30-30: ⚠️ Potential issue | 🟡 Minor

Two componentDefaults values are incorrectly lowercased.

"credentials": "vjerodajnice" (line 30) and "hours": "sati" (line 48) begin with lowercase, inconsistent with every other sibling value. "Sati" is also capitalised at the root level (line 85).

🔤 Proposed fix
-    "credentials": "vjerodajnice",
+    "credentials": "Vjerodajnice",
-    "hours": "sati",
+    "hours": "Sati",

Also applies to: 48-48

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/hr/visual-editor.json` at line 30,
The two values in componentDefaults are incorrectly lowercased—update the value
for the "credentials" key from "vjerodajnice" to "Vjerodajnice" and the value
for the "hours" key from "sati" to "Sati" to match the capitalization used by
sibling entries (note that the root-level "Sati" is already capitalized); edit
the entries for "credentials" and "hours" in the componentDefaults block to use
the capitalized forms.
packages/visual-editor/locales/components/hr/visual-editor.json-45-45 (1)

45-45: ⚠️ Potential issue | 🟡 Minor

componentDefaults keys that overlap with root-level keys use different Croatian translations.

Key componentDefaults Root-level
getDirections "Preuzmite upute" (line 45) "Dobiti upute" (line 81)
hours "sati" (line 48) "Sati" (line 85)
readMore "Pročitajte više" (line 61) "Pročitaj više" (line 122)
findALocation "Pronađite mjesto" (line 37) "Pronađite lokaciju" (line 79)

If these keys represent the same UI concept, the divergence will produce inconsistent phrasing across the product. If they intentionally serve different purposes (e.g., placeholder content vs. button labels), a brief comment in the file or the generating script would clarify the intent.

Also applies to: 48-48, 61-61, 37-37

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/hr/visual-editor.json` at line 45,
The file contains inconsistent Croatian translations for keys that likely
represent the same UI text (keys: getDirections, hours, readMore, findALocation)
between the componentDefaults section and the root-level section; either unify
the translations so both componentDefaults and root-level use the same string
for each key (e.g., make getDirections, hours, readMore, findALocation identical
across sections) or, if the differences are intentional, add a short inline
comment near each differing key pair explaining the distinct usage (e.g.,
“componentDefaults used as placeholder vs root-level used as button label”) to
avoid future drift; update the values in the componentDefaults or root-level
entries (whichever is canonical) and/or add comments next to getDirections,
hours, readMore, and findALocation to document intent.
packages/visual-editor/locales/components/de/visual-editor.json-67-67 (1)

67-67: ⚠️ Potential issue | 🟡 Minor

"visitProfile" is grammatically incomplete — missing the definite article.

"Besuchen Sie Profil" is ungrammatical in German; the noun requires the article das. Correct form: "Besuchen Sie das Profil".

✏️ Suggested fix
-    "visitProfile": "Besuchen Sie Profil"
+    "visitProfile": "Besuchen Sie das Profil"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/de/visual-editor.json` at line 67,
The translation for the "visitProfile" key is grammatically incorrect in German;
update the value of "visitProfile" in the visual-editor.json locale file from
"Besuchen Sie Profil" to the correct form "Besuchen Sie das Profil" so the
definite article is included.
packages/visual-editor/locales/components/de/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

Wrong currency symbol for German locale ($).

"123,00 $" correctly uses the German decimal-comma format but pairs it with a US-dollar sign. German/EU defaults should use . If this is intentional as a purely numeric placeholder, the symbol should still match the locale to avoid misleading editors.

✏️ Suggested fix
-    "price": "123,00 $",
+    "price": "123,00 €",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/de/visual-editor.json` at line 57,
The "price" translation contains the wrong currency symbol for German
locale—replace the US dollar sign with the Euro sign so the value reads "123,00
€" while preserving the German decimal-comma format; update the "price" key in
visual-editor.json (the "price" string) accordingly and scan nearby locale
entries to ensure currency symbols match the locale.
packages/visual-editor/locales/components/de/visual-editor.json-48-48 (1)

48-48: ⚠️ Potential issue | 🟡 Minor

"hours" value is a bare abbreviation — use a full label.

"Std" is the German abbreviation for Stunden (hours), but every other entry in this block uses a full word or phrase. The existing top-level "hours" key (line 85) already uses "Öffnungszeiten". A component-default label that renders as "Std" would look truncated to users.

✏️ Suggested fix
-    "hours": "Std",
+    "hours": "Öffnungszeiten",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/de/visual-editor.json` at line 48,
The component-localization key "hours" in
packages/visual-editor/locales/components/de/visual-editor.json currently uses
the bare abbreviation "Std" — replace this value with the full German word
"Stunden" (or another full-label translation as used elsewhere) so the component
label is not truncated; update the "hours" value in the file (note there is also
a top-level "hours" key elsewhere labeled "Öffnungszeiten", so ensure this
component-specific "hours" uses the full word "Stunden" for consistency).
packages/visual-editor/locales/components/ro/visual-editor.json-61-61 (1)

61-61: ⚠️ Potential issue | 🟡 Minor

componentDefaults.readMore conflicts with the top-level readMore at line 122.

  • Line 61 (componentDefaults): "Citeşte mai mult" — informal singular imperative, cedilla ş (U+015F, non-standard modern Romanian).
  • Line 122 (top-level): "Citiți mai mult" — formal/plural imperative, comma-below ș (U+0219, standard modern Romanian).

These map to the same concept but produce different UI text depending on which context is rendered. The top-level form should be used for consistency.

✏️ Proposed fix
-    "readMore": "Citeşte mai mult",
+    "readMore": "Citiți mai mult",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/ro/visual-editor.json` at line 61,
componentDefaults.readMore is using an inconsistent, informal spelling ("Citeşte
mai mult" with U+015F) that conflicts with the top-level readMore ("Citiți mai
mult" with standard U+0219); update the value for componentDefaults.readMore to
the top-level form "Citiți mai mult" using the standard comma-below 'ș' (U+0219)
so both keys (componentDefaults.readMore and readMore) are consistent across the
locale.
packages/visual-editor/locales/components/sv/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

"price" placeholder uses USD for a Swedish locale.

"123,00 USD" has the correct Swedish decimal separator (comma), but USD is US-specific. For the Swedish locale, a locale-representative placeholder like "123,00 SEK" (or a currency-agnostic format) would be more appropriate, assuming this is a sample/default display value rather than a computed one.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/sv/visual-editor.json` at line 57,
Update the "price" placeholder value in the Swedish locale resource so it uses a
Sweden-appropriate currency or a currency-agnostic format: locate the "price"
key in packages/visual-editor/locales/components/sv/visual-editor.json and
replace "123,00 USD" with a representative Swedish value such as "123,00 SEK"
(or use a neutral sample like "123,00" if currency is injected elsewhere) to
match the sv locale.
packages/visual-editor/locales/components/sv/visual-editor.json-64-64 (1)

64-64: ⚠️ Potential issue | 🟡 Minor

"subtitle""Texta" is an incorrect translation.

"Texta" is a Swedish verb (meaning "to letter in block capitals" or informally "to caption/subtitle a video"), not the noun "subtitle/subheading". The correct Swedish noun translation is "Underrubrik" or "Undertitel".

🐛 Proposed fix
-    "subtitle": "Texta",
+    "subtitle": "Underrubrik",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/sv/visual-editor.json` at line 64,
The translation for the "subtitle" key in visual-editor.json is incorrect
(currently "Texta"); update the value for the "subtitle" JSON key to the correct
Swedish noun, e.g. change "Texta" to "Underrubrik" (or "Undertitel") so the key
"subtitle" in the locales/components/sv/visual-editor.json contains the proper
noun translation.
packages/visual-editor/locales/components/da/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

Consider using DKK (or a currency-neutral placeholder) for the Danish locale.

"price": "123,00 USD" uses the correct Danish decimal separator (,) but the currency is USD. For a da locale default, 123,00 DKK would be more representative. If the intent is a purely formatting sample that doesn't imply a real currency, a currency-neutral form (e.g., 123,00) may be preferable to avoid confusion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/da/visual-editor.json` at line 57,
The "price" sample in the Danish locale uses "123,00 USD" which mixes Danish
formatting with USD; update the "price" value in the da visual-editor JSON (key
"price") to a Denmark-appropriate representation such as "123,00 DKK" or remove
the currency to use a neutral sample "123,00" depending on whether you want a
locale-specific currency or a currency-neutral placeholder.
packages/visual-editor/locales/components/da/visual-editor.json-31-31 (1)

31-31: ⚠️ Potential issue | 🟡 Minor

"directoryRoot" appears untranslated.

The value "Directory Root" is in English while all surrounding keys carry Danish translations. If this is a product/technical term intentionally kept in English (consistent across all locales), this is fine — otherwise it should be translated (e.g., "Biblioteksrod" or the appropriate Danish equivalent).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/da/visual-editor.json` at line 31,
The "directoryRoot" localization key currently has an English value ("Directory
Root") while surrounding entries are Danish; update the value for the
"directoryRoot" key in visual-editor.json to the proper Danish translation
(e.g., "Biblioteksrod" or the agreed-upon Danish term) and ensure the change
preserves JSON formatting and surrounding punctuation, or if the term is
intentionally English across locales, add a brief comment in the repo's
localization guidelines and leave a note in the PR explaining the intentional
choice.
packages/visual-editor/locales/components/nl/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

"price" placeholder uses $ instead of for the NL locale.

The Dutch locale conventionally uses the Euro (). The current value "$ 123,00" looks like a copy of the EN default. If this is purely a format placeholder, at minimum the currency symbol should reflect the locale.

✏️ Suggested fix
-    "price": "$ 123,00",
+    "price": "€ 123,00",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/nl/visual-editor.json` at line 57,
The "price" placeholder in
packages/visual-editor/locales/components/nl/visual-editor.json uses the US
dollar symbol; update the value for the "price" key to use the Euro symbol and
Dutch formatting (e.g., change "$ 123,00" to "€ 123,00" or match the existing
locale spacing/decimal comma convention) so the NL locale shows the correct
currency.
packages/visual-editor/locales/components/nl/visual-editor.json-48-48 (1)

48-48: ⚠️ Potential issue | 🟡 Minor

"hours" default is singular — consider using the plural form.

"Uur" (hour, singular) is the componentDefaults value, while the sibling top-level key at line 85 already uses "Uren" (hours, plural). A component labelled "Hours" in the UI is almost always a section covering multiple time spans, so "Uren" is the more natural Dutch default.

✏️ Suggested fix
-    "hours": "Uur",
+    "hours": "Uren",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/nl/visual-editor.json` at line 48,
The "hours" translation key in the NL visual-editor locale is using the singular
"Uur" but should use the plural "Uren" to match the top-level sibling and
component intent; update the value for the "hours" key in
packages/visual-editor/locales/components/nl/visual-editor.json (the "hours"
JSON key under componentDefaults/top-level translations) from "Uur" to "Uren" so
the UI displays the plural form consistently.
packages/visual-editor/locales/components/zh-TW/visual-editor.json-64-64 (1)

64-64: ⚠️ Potential issue | 🟡 Minor

Mistranslation: "subtitle" should map to "副標題", not "字幕".

"字幕" in Traditional Chinese means video/film captions or closed captions. The correct translation for "subtitle" as a UI section heading is "副標題".

📝 Proposed fix
-    "subtitle": "字幕",
+    "subtitle": "副標題",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/zh-TW/visual-editor.json` at line
64, The "subtitle" JSON entry is mistranslated — update the value for the
"subtitle" key in visual-editor.json from "字幕" to the correct Traditional
Chinese UI label "副標題"; ensure no other keys are changed and run any locale
linting/formatting after the edit.
packages/visual-editor/locales/components/zh-TW/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

zh-TW locale should clarify currency in price placeholder.

The zh-TW locale uses "$123.00" (USD format) without explicit currency indication. Many other locales clarify this is USD (e.g., Romanian: "123,00 USD", Portuguese: "US$ 123,00"), while Taiwan's currency is the New Taiwan Dollar (NT$). Update this to either "NT$123.00" for local context or "US$123.00" / "123.00 USD" for consistency with other locales and clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/zh-TW/visual-editor.json` at line
57, Update the zh-TW locale's price placeholder value for clarity: locate the
"price" entry in the visual-editor.json for zh-TW (the JSON key "price") and
change the example from "$123.00" to an explicit currency format—either local
(e.g., "NT$123.00") or explicit USD (e.g., "US$123.00" or "123.00 USD")
depending on intended context—so the placeholder unambiguously indicates the
currency.
packages/visual-editor/locales/components/cs/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

price default uses USD ($) in a Czech locale.

"price": "123,00 $" correctly uses a comma decimal separator (Czech convention) but pairs it with the US dollar symbol. Czech users would expect or CZK. If this is intentionally a locale-neutral placeholder (e.g., matching what other locales emit), document that intent; otherwise update to "123,00 Kč".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/cs/visual-editor.json` at line 57,
The "price" localization entry currently uses a USD symbol ("price": "123,00 $")
which is incorrect for Czech; update the value of the "price" key in the cs
visual-editor.json to use the Czech currency symbol and format (e.g., "123,00
Kč") or, if the USD sign is intentional as a locale-neutral placeholder, add a
clarifying comment or documentation near the "price" key explaining that intent
so translators and developers understand it's not a localization bug.
packages/visual-editor/locales/components/cs/visual-editor.json-67-67 (1)

67-67: ⚠️ Potential issue | 🟡 Minor

Unnecessary mid-word capitalisation: "Navštivte Profil""Navštivte profil".

Czech does not capitalise common nouns mid-sentence. "Profil" should be lowercase.

✏️ Proposed fix
-    "visitProfile": "Navštivte Profil"
+    "visitProfile": "Navštivte profil"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/cs/visual-editor.json` at line 67,
The translation value for the key "visitProfile" uses incorrect mid-word
capitalization ("Navštivte Profil"); update the string value to use lowercase
for the common noun by changing it to "Navštivte profil" so the key
"visitProfile" reads correctly in Czech.
packages/visual-editor/locales/components/cs/visual-editor.json-37-37 (1)

37-37: ⚠️ Potential issue | 🟡 Minor

Divergent translations for keys that also exist at the top level.

Four componentDefaults values produce Czech strings that differ from the already-established top-level translations for the same concept:

componentDefaults key componentDefaults value Top-level value (line)
findALocation "Najděte místo" "Najděte polohu" (ln 79)
getDirections "Získejte trasu" "Získejte pokyny" (ln 81)
hours "hodiny" (lowercase) "Hodiny" (ln 85)
readMore "Přečtěte si více" "Číst více" (ln 127)

If these are intentionally distinct (e.g., placeholder copy vs. UI action label), a brief comment in the file or the generation script would help translators maintain the distinction. If not intentional, align them with the established top-level strings.

Also applies to: 45-45, 48-48, 61-61

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/cs/visual-editor.json` at line 37,
The component-level translations for the keys findALocation, getDirections,
hours, and readMore diverge from the established top-level strings; update the
componentDefaults entries for "findALocation", "getDirections", "hours", and
"readMore" to match the top-level translations ("Najděte polohu", "Získejte
pokyny", "Hodiny", "Číst více") or, if the differences are intentional, add a
brief inline comment in the locale JSON generation script or next to those keys
documenting why these variants are different so translators understand the
distinction.
packages/visual-editor/locales/components/sk/visual-editor.json-50-50 (1)

50-50: ⚠️ Potential issue | 🟡 Minor

"insights" is not translated — left as English.

"Insights" is the only value in the block that appears to be an untranslated English string. If this is intentional (e.g. a brand/product name), a brief inline comment or documented convention would help future translators. Otherwise the Slovak equivalent should be provided.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/sk/visual-editor.json` at line 50,
The "insights" key in the SK locale file (visual-editor.json) is left
untranslated; update the value for the "insights" key to the correct Slovak
translation (e.g., "Prehľady" or the agreed term) or, if the English term is
intentional, add a brief inline comment or follow the project's convention to
mark it as a deliberate untranslated brand term; locate the "insights" key in
the locales/components/sk/visual-editor.json and replace the value or annotate
accordingly.
packages/visual-editor/locales/components/sk/visual-editor.json-30-30 (1)

30-30: ⚠️ Potential issue | 🟡 Minor

Lowercase first letter on credentials and hours is inconsistent with the rest of the block.

"poverenia" (line 30) and "hodiny" (line 48) start with a lowercase letter while every other value in componentDefaults starts with an uppercase letter. The root-level "hours" at line 85 is already "Hodiny" (uppercase).

✏️ Proposed fix
-    "credentials": "poverenia",
+    "credentials": "Poverenia",
...
-    "hours": "hodiny",
+    "hours": "Hodiny",

Also applies to: 48-48

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/sk/visual-editor.json` at line 30,
In the componentDefaults block, the values for the keys "credentials" and
"hours" are inconsistent (currently "poverenia" and "hodiny"); update them to
start with an uppercase letter to match the rest of the block (e.g., "Poverenia"
and "Hodiny") ensuring consistency with the root-level "hours" which is already
"Hodiny" so that all localized component default strings use an initial capital
letter.
packages/visual-editor/locales/components/fr/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

Currency symbol mismatch for fr locale.

The fr locale (France) uses the Euro (€), not the US dollar ($). Even as a placeholder default, displaying "123,00 $" to French editors is misleading.

💱 Suggested fix
-    "price": "123,00 $",
+    "price": "123,00 €",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/fr/visual-editor.json` at line 57,
The "price" entry in the fr locale uses the US dollar symbol; update the value
for the "price" key in
packages/visual-editor/locales/components/fr/visual-editor.json to use the Euro
symbol and proper French spacing/formatting (e.g., "123,00 €") so French editors
see the correct currency representation for the fr locale.
packages/visual-editor/locales/components/fr/visual-editor.json-51-51 (1)

51-51: ⚠️ Potential issue | 🟡 Minor

learnMore translation is non-idiomatic French.

"Apprendre encore plus" (literally "learn even more") is an awkward, machine-translated phrase. The standard French call-to-action for "Learn more" is "En savoir plus", which is already used for readMore at line 61. If learnMore and readMore need to be visually distinct, alternatives such as "Découvrir" or "En apprendre davantage" are more natural.

🌐 Suggested fix
-    "learnMore": "Apprendre encore plus",
+    "learnMore": "En savoir plus",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/fr/visual-editor.json` at line 51,
The translation for the JSON key "learnMore" is non-idiomatic; update the value
of "learnMore" to a natural French call-to-action such as "En savoir plus" (if
reuse is acceptable) or, to keep it visually distinct from "readMore", use
"Découvrir" or "En apprendre davantage" — locate the "learnMore" key in the
visual-editor locale JSON and replace its string accordingly.
packages/visual-editor/locales/components/zh/visual-editor.json-20-68 (1)

20-68: ⚠️ Potential issue | 🟡 Minor

Translation quality could be improved for a few Chinese entries.

A couple of entries may benefit from review by a native speaker:

  • Line 39: "followUs": "跟着我们" — in a social-media context, "关注我们" is the standard phrasing.
  • Line 64: "subtitle": "字幕" — means video subtitles/captions. For a sub-heading, "副标题" is more appropriate. (Same concern applies to the Finnish locale's "Tekstitys".)
  • Line 57: "price": "$123.00" — kept identical to English. Other locales (fi, nb) localize the number format. Consider "¥123.00" or "$123.00" with localized decimal separator if locale-appropriate formatting matters here.

These are likely auto-translated values; a human review pass across all locales before release would be valuable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/zh/visual-editor.json` around lines
20 - 68, Update the Chinese locale entries to use more natural UI wording:
change the value for "followUs" from "跟着我们" to "关注我们", change "subtitle" from
"字幕" to "副标题" (to indicate sub-heading rather than captions), and review "price"
to use a locale-appropriate currency/format (e.g., "¥123.00" or keep "$123.00"
but adjust decimal separator) in the componentDefaults object so the keys
"followUs", "subtitle", and "price" reflect correct, native phrasing and
formatting.
packages/visual-editor/locales/components/nb/visual-editor.json-20-68 (1)

20-68: ⚠️ Potential issue | 🟡 Minor

A few componentDefaults entries appear untranslated in Norwegian.

Lines 27 and 47 have English values ("Call to Action", "Header Link") instead of Norwegian translations. Other locales (e.g., Finnish) have these translated. Please verify whether these were intentionally left in English or missed by the translation pipeline.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/nb/visual-editor.json` around lines
20 - 68, The componentDefaults JSON contains untranslated English values for the
keys callToAction and headerLink; update componentDefaults["callToAction"] from
"Call to Action" to an appropriate Norwegian translation (e.g., "Oppfordring til
handling" or agreed string) and componentDefaults["headerLink"] from "Header
Link" to a Norwegian equivalent (e.g., "Overskriftslenke"), then run the
locale/translation pipeline or confirm with the localization owner that these
values should be changed and commit the updated visual-editor.json.
packages/visual-editor/locales/components/fi/visual-editor.json-20-68 (1)

20-68: ⚠️ Potential issue | 🟡 Minor

componentDefaults keys are consistent with the English locale — good.

One minor translation quality note: "subtitle": "Tekstitys" (line 64) translates closer to "Subtitling" (video captions) in Finnish. The intended meaning here is likely "Subtitle" as in a sub-heading. Consider "Alaotsikko" instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/fi/visual-editor.json` around lines
20 - 68, Update the Finnish translation for the componentDefaults key "subtitle"
within the visual-editor.json locale: replace the current value "Tekstitys" with
"Alaotsikko" so the string represents a sub-heading rather than video captions;
ensure you modify the "componentDefaults" object entry for "subtitle".
packages/visual-editor/locales/components/es/visual-editor.json-37-37 (1)

37-37: ⚠️ Potential issue | 🟡 Minor

componentDefaults.findALocation and the root-level findALocation are inconsistent.

Line 37 uses a lowercase infinitive ("encontrar una ubicación") while the root-level equivalent at line 79 uses a capitalized imperative ("Encuentra una ubicación"). Since both describe the same UI action, they should match in capitalization and verb form.

✏️ Suggested fix
-    "findALocation": "encontrar una ubicación",
+    "findALocation": "Encuentra una ubicación",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/es/visual-editor.json` at line 37,
componentDefaults.findALocation and the root-level findALocation values are
inconsistent in verb form/capitalization; update one so both match (e.g., change
"findALocation" under componentDefaults to "Encuentra una ubicación" or change
the root-level to "encontrar una ubicación") ensuring the keys
componentDefaults.findALocation and the root-level findALocation have identical
strings.
packages/visual-editor/locales/components/et/visual-editor.json-48-50 (1)

48-50: ⚠️ Potential issue | 🟡 Minor

Translation quality: "Tundi" and "Insightsi" may need review by a native speaker.

  • Line 48: "hours": "Tundi" uses the partitive singular, while the existing root-level "hours" (line 85) is translated as "Tööaeg" (working hours). The two usages may serve different contexts, but the inconsistency could confuse users.
  • Line 50: "insights": "Insightsi" appears to be a direct anglicism with an Estonian suffix. A more natural Estonian term (e.g., "Ülevaated") might be preferable unless "Insights" is used as a product/feature name.

These look machine-translated — consider having the Estonian translations reviewed by a native speaker before release.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/et/visual-editor.json` around lines
48 - 50, The translations for the keys "hours" and "insights" look
inconsistent/unnatural: review and update the Estonian strings for "hours",
"information", and "insights" to ensure they match the intended UI context and
other translations (e.g., the root-level "hours" entry uses "Tööaeg"); replace
"Tundi" with the appropriate form ("Tööaeg", "Tunnid", or context-specific
variant) and replace "Insightsi" with a natural Estonian term like "Ülevaated"
unless "Insights" is a proper product name that must remain untranslated; have a
native Estonian reviewer confirm the final choices and apply the updated strings
for the keys "hours", "information", and "insights".
packages/visual-editor/locales/components/pl/visual-editor.json-46-46 (1)

46-46: ⚠️ Potential issue | 🟡 Minor

Incorrect Polish translation: "Chodnikowiec" means "sidewalk", not "Header".

"Chodnikowiec" is Polish for "sidewalk/pavement". The intended translation for a page/UI header should be "Nagłówek" (which is already used elsewhere in this file, e.g., "heroHeader": "Nagłówek bohatera" on line 83).

🌐 Suggested fix
-    "header": "Chodnikowiec",
+    "header": "Nagłówek",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/pl/visual-editor.json` at line 46,
The "header" translation value is incorrect: replace the Polish word
"Chodnikowiec" with the appropriate UI term "Nagłówek" for the "header" key in
packages/visual-editor/locales/components/pl/visual-editor.json; locate the
"header" property in the JSON (key "header") and update its value to "Nagłówek"
so it matches other uses like "heroHeader".
🧹 Nitpick comments (8)
packages/visual-editor/locales/components/ja/visual-editor.json (1)

46-47: Inconsistent transliteration of "header": "ヘッダ" vs "ヘッダー".

header drops the long vowel mark while headerLink retains it. The JIS Z 8301 guideline recommends the long vowel mark (ー) for foreign loanwords of more than 3 mora, so "ヘッダー" is preferred for both keys.

✏️ Proposed fix
-    "header": "ヘッダ",
+    "header": "ヘッダー",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/ja/visual-editor.json` around lines
46 - 47, The localization has inconsistent transliteration: the "header" key
uses "ヘッダ" while "headerLink" uses "ヘッダー"; update the "header" value to "ヘッダー"
so both keys ("header" and "headerLink") use the long vowel mark (ー) per JIS Z
8301, ensuring consistent Japanese localization in the visual-editor.json
component locale.
packages/visual-editor/src/components/footer/SecondaryFooterSlot.tsx (1)

10-15: defaultLink is duplicated in ExpandedFooter.tsx — consider consolidating into a shared file to reduce redundancy.

Both files define an identical defaultLink constant with the same shape and defaultText call:

  • ExpandedFooter.tsx (lines 17-22): export const defaultLink = { ... }
  • SecondaryFooterSlot.tsx (lines 10-15): const defaultLink = { ... }

No circular dependency exists (SecondaryFooterSlot does not import ExpandedFooter), so consolidation is feasible. Moving this to a shared utility file would eliminate duplication and maintain a single source of truth.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/src/components/footer/SecondaryFooterSlot.tsx` around
lines 10 - 15, Duplicate constant defaultLink is defined in ExpandedFooter and
SecondaryFooterSlot; extract it into a shared module (e.g., a new utils or
constants file) as a single exported symbol (export const defaultLink = { ... })
and replace the local definitions in both ExpandedFooter.tsx and
SecondaryFooterSlot.tsx with imports of that exported defaultLink; ensure the
shape and defaultText call remain unchanged and update any references to use the
imported identifier to avoid duplication.
packages/visual-editor/src/components/pageSections/FAQsSection/FAQCard.tsx (1)

29-32: defaultFAQ remains English-only — inconsistent with the PR's localization goal

Every other component migrated in this PR (BodyText, HeadingText, CtaWrapper, Phone, etc.) now calls defaultText(...) / defaultRichText(...) from utils/defaultContent.ts to get locale-populated defaults. FAQCard instead uses a raw English string for question and a hardcoded English getDefaultRTF(...) call for answer.

A previous review flagged missing faqCard.question / faqCard.answer locale keys when this file called defaultRichText("faqCard.question", ...). The current revision removes those calls rather than adding the locale keys — non-English users still receive English-only FAQ defaults, just via a different code path.

If this is intentionally deferred (aligns with PR TODO #1), consider adding an inline comment so it isn't missed. Otherwise, align with the rest of the PR:

♻️ Proposed alignment with the PR's localization pattern
+import { defaultText, defaultRichText } from "../../../utils/defaultContent.ts";

 const defaultFAQ = {
-  question: "Question Lorem ipsum dolor sit amet?",
-  answer: getDefaultRTF(
-    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
-  ),
+  // TODO(`#1`): ensure faqCard.question / faqCard.answer keys exist in all locale files
+  question: defaultText("faqCard.question", "Question Lorem ipsum dolor sit amet?"),
+  answer: defaultRichText(
+    "faqCard.answer",
+    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+  ),
 } satisfies FAQStruct;

The locale JSON files would also need faqCard.question and faqCard.answer entries added (matching the format of other component-defaults keys in this PR).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/src/components/pageSections/FAQsSection/FAQCard.tsx`
around lines 29 - 32, defaultFAQ in FAQCard.tsx uses hardcoded English for
question and answer (question and answer fields, getDefaultRTF) which breaks the
PR's localization pattern; replace the raw string and getDefaultRTF call with
the localization helpers (e.g., defaultText("faqCard.question", "...") for
question and defaultRichText("faqCard.answer", "...") for answer) and add
corresponding faqCard.question and faqCard.answer keys to the locale JSONs, or
if intentionally deferred, add an explicit inline TODO comment above defaultFAQ
referencing the PR TODO and why localization is skipped.
packages/visual-editor/locales/components/zh-TW/visual-editor.json (1)

38-38: Unnatural name placeholder translation for "firstLast".

"第一個 最後一個" translates word-for-word as "the first one, the last one", which is not how a name placeholder reads in Traditional Chinese. "名 姓" (given name, family name) would be more idiomatic.

📝 Proposed fix
-    "firstLast": "第一個 最後一個",
+    "firstLast": "名 姓",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/zh-TW/visual-editor.json` at line
38, The translation for the "firstLast" placeholder is unnatural; replace the
value "第一個 最後一個" with a more idiomatic Traditional Chinese name placeholder such
as "名 姓" (given name, family name) by updating the JSON entry for the
"firstLast" key in the locales/components/zh-TW/visual-editor resource so the UI
reads naturally for Chinese users.
packages/visual-editor/locales/components/it/visual-editor.json (1)

57-57: Consider aligning the price placeholder with Italian locale conventions.

"$ 123,00" mixes a USD ($) symbol with Italian decimal notation. Italian users would typically expect € 123,00. If this is a deliberate generic/currency-agnostic placeholder, it's worth a comment; otherwise the currency symbol should match the locale.

💡 Suggested update
-    "price": "$ 123,00",
+    "price": "€ 123,00",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/it/visual-editor.json` at line 57,
The "price" translation uses a USD symbol with Italian formatting ("price" in
visual-editor.json) which is inconsistent; update the value for the "price" key
to use the Euro symbol with Italian number formatting (e.g., "€ 123,00") or, if
the placeholder is intentionally currency-agnostic, add a brief inline comment
explaining that it's a generic placeholder—adjust the "price" entry accordingly
to ensure locale-consistent currency display.
packages/visual-editor/locales/components/en-GB/visual-editor.json (1)

57-57: USD symbol in British English locale.

The default price placeholder uses $ (USD) for the en-GB locale. Consider using £123.00 to match regional expectations, as UK editors will see this placeholder before mapping their own data.

✏️ Suggested fix
-    "price": "$123.00",
+    "price": "£123.00",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/en-GB/visual-editor.json` at line
57, The placeholder price string for the British English locale is using a USD
symbol; update the "price" value in visual-editor.json from "$123.00" to
"£123.00" so the en-GB locale shows the pound symbol (edit the "price" key in
the locales/components/en-GB/visual-editor.json entry).
packages/visual-editor/scripts/generateTranslations.ts (2)

415-443: Unbounded parallelism may trigger rate limiting from the translation endpoint.

All translation requests are fired concurrently via Promise.allSettled(translationTargets.map(async ...)). For large locale files with many missing keys, this could result in hundreds of simultaneous HTTP requests to the Google Translate endpoint, leading to 429s or connection failures.

Consider adding a simple concurrency limiter or batching translations in chunks (e.g., 10–20 at a time).

Example batched approach
-    await Promise.allSettled(
-      translationTargets.map(async ({ key, english, sourceKey }) => {
+    const BATCH_SIZE = 10;
+    for (let i = 0; i < translationTargets.length; i += BATCH_SIZE) {
+      const batch = translationTargets.slice(i, i + BATCH_SIZE);
+      await Promise.allSettled(
+        batch.map(async ({ key, english, sourceKey }) => {
           // ... existing translation logic ...
-      })
-    );
+        })
+      );
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/scripts/generateTranslations.ts` around lines 415 -
443, The current loop fires all translations concurrently
(translationTargets.map with Promise.allSettled) which can hit rate limits on
translateText; change to a bounded concurrency approach (e.g., use a simple
semaphore/p-limit or process translationTargets in chunks of N, 10–20) so only N
translateText calls run at once. Locate the block using translationTargets,
translateText, maskInterpolationVariables, unmaskInterpolationVariables,
embedContextInText and removeEmbeddedContext and wrap the per-item async work
behind a concurrency limiter or iterate in batched slices, preserving the
existing masking/embedding/unmasking logic, cache.set and success/fail
increments and logging. Ensure errors for each item are still caught and counted
as before.

308-333: No timeout on the fetch call — script can hang indefinitely.

If the Google Translate endpoint is slow or unresponsive, the script will hang with no timeout. Consider adding an AbortSignal.timeout():

Suggested fix
-  const response = await fetch(url);
+  const response = await fetch(url, { signal: AbortSignal.timeout(10_000) });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/scripts/generateTranslations.ts` around lines 308 -
333, The translateText function lacks a fetch timeout and can hang; update
translateText to create an AbortSignal with a reasonable timeout (e.g., using
AbortSignal.timeout(timeoutMs) or an AbortController fallback), pass that signal
to fetch(url, { signal }), and handle the abort case by throwing a clear error
(e.g., "Google Translate request timed out for text=..."). Ensure the timeout
value is configurable or a constant, and keep the existing error handling for
non-ok responses and invalid JSON in place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/visual-editor/locales/components/pt/visual-editor.json`:
- Line 57: The "price" string in the Portuguese locale ("pt") currently uses the
US Dollar symbol ("US$ 123,00"); update the locale entry for the "price" key in
packages/visual-editor/locales/components/pt/visual-editor.json to use the
Brazilian Real symbol so it reads "R$ 123,00" (preserve spacing and number
formatting "R$ 123,00") to reflect Brazilian Portuguese currency conventions.

---

Duplicate comments:
In
`@packages/visual-editor/src/components/pageSections/EventSection/EventCard.tsx`:
- Around line 43-45: The description is created with getDefaultRTF(...)
directly, producing a single non-localized RTF value while title and cta.label
use defaultText(...) for multi-locale defaults; update EventCard's description
to be locale-aware by wrapping/constructing the RTF value via the same locale
helper used for other defaults (e.g. use defaultText(...) with per-locale RTF
values or pass getDefaultRTF(...) through the defaultText API) and ensure the
eventCard.description key exists in locale resources (or add an inline comment
if a single Lorem ipsum default is intentionally untranslated). Reference:
getDefaultRTF, defaultText, eventCard.description, title, cta.label in
EventCard.tsx.

---

Nitpick comments:
In `@packages/visual-editor/locales/components/en-GB/visual-editor.json`:
- Line 57: The placeholder price string for the British English locale is using
a USD symbol; update the "price" value in visual-editor.json from "$123.00" to
"£123.00" so the en-GB locale shows the pound symbol (edit the "price" key in
the locales/components/en-GB/visual-editor.json entry).

In `@packages/visual-editor/locales/components/it/visual-editor.json`:
- Line 57: The "price" translation uses a USD symbol with Italian formatting
("price" in visual-editor.json) which is inconsistent; update the value for the
"price" key to use the Euro symbol with Italian number formatting (e.g., "€
123,00") or, if the placeholder is intentionally currency-agnostic, add a brief
inline comment explaining that it's a generic placeholder—adjust the "price"
entry accordingly to ensure locale-consistent currency display.

In `@packages/visual-editor/locales/components/ja/visual-editor.json`:
- Around line 46-47: The localization has inconsistent transliteration: the
"header" key uses "ヘッダ" while "headerLink" uses "ヘッダー"; update the "header"
value to "ヘッダー" so both keys ("header" and "headerLink") use the long vowel mark
(ー) per JIS Z 8301, ensuring consistent Japanese localization in the
visual-editor.json component locale.

In `@packages/visual-editor/locales/components/zh-TW/visual-editor.json`:
- Line 38: The translation for the "firstLast" placeholder is unnatural; replace
the value "第一個 最後一個" with a more idiomatic Traditional Chinese name placeholder
such as "名 姓" (given name, family name) by updating the JSON entry for the
"firstLast" key in the locales/components/zh-TW/visual-editor resource so the UI
reads naturally for Chinese users.

In `@packages/visual-editor/scripts/generateTranslations.ts`:
- Around line 415-443: The current loop fires all translations concurrently
(translationTargets.map with Promise.allSettled) which can hit rate limits on
translateText; change to a bounded concurrency approach (e.g., use a simple
semaphore/p-limit or process translationTargets in chunks of N, 10–20) so only N
translateText calls run at once. Locate the block using translationTargets,
translateText, maskInterpolationVariables, unmaskInterpolationVariables,
embedContextInText and removeEmbeddedContext and wrap the per-item async work
behind a concurrency limiter or iterate in batched slices, preserving the
existing masking/embedding/unmasking logic, cache.set and success/fail
increments and logging. Ensure errors for each item are still caught and counted
as before.
- Around line 308-333: The translateText function lacks a fetch timeout and can
hang; update translateText to create an AbortSignal with a reasonable timeout
(e.g., using AbortSignal.timeout(timeoutMs) or an AbortController fallback),
pass that signal to fetch(url, { signal }), and handle the abort case by
throwing a clear error (e.g., "Google Translate request timed out for
text=..."). Ensure the timeout value is configurable or a constant, and keep the
existing error handling for non-ok responses and invalid JSON in place.

In `@packages/visual-editor/src/components/footer/SecondaryFooterSlot.tsx`:
- Around line 10-15: Duplicate constant defaultLink is defined in ExpandedFooter
and SecondaryFooterSlot; extract it into a shared module (e.g., a new utils or
constants file) as a single exported symbol (export const defaultLink = { ... })
and replace the local definitions in both ExpandedFooter.tsx and
SecondaryFooterSlot.tsx with imports of that exported defaultLink; ensure the
shape and defaultText call remain unchanged and update any references to use the
imported identifier to avoid duplication.

In `@packages/visual-editor/src/components/pageSections/FAQsSection/FAQCard.tsx`:
- Around line 29-32: defaultFAQ in FAQCard.tsx uses hardcoded English for
question and answer (question and answer fields, getDefaultRTF) which breaks the
PR's localization pattern; replace the raw string and getDefaultRTF call with
the localization helpers (e.g., defaultText("faqCard.question", "...") for
question and defaultRichText("faqCard.answer", "...") for answer) and add
corresponding faqCard.question and faqCard.answer keys to the locale JSONs, or
if intentionally deferred, add an explicit inline TODO comment above defaultFAQ
referencing the PR TODO and why localization is skipped.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

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/locales/platform/zh/visual-editor.json (1)

1-695: ⚠️ Potential issue | 🔴 Critical

The componentDefaults block is missing from ALL platform locale files.

The componentDefaults object that was added to all 25 packages/visual-editor/locales/components/ files is absent from all 25 packages/visual-editor/locales/platform/ files, including the zh locale under review. This is a systemic omission—platform/en, platform/es, platform/fr, and all other platform locales are missing this block. All platform locale files will incorrectly fall back to English defaults at runtime until componentDefaults is added to each of them.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/zh/visual-editor.json` around lines 1
- 695, The platform locale is missing the componentDefaults object, causing
fallbacks to English; add a componentDefaults object to this locale (and all
other platform/* locale JSONs) mirroring the structure/keys used in
packages/visual-editor/locales/components/* (use the same keys and translations
as the corresponding platform translations in other locales), ensuring the
top-level JSON includes "componentDefaults": { ... } with the same identifiers
as in the components locale files so runtime lookup uses the localized defaults
instead of falling back to English.
🟡 Minor comments (30)
packages/visual-editor/locales/platform/hu/visual-editor.json-251-253 (1)

251-253: ⚠️ Potential issue | 🟡 Minor

Minor: Inconsistent capitalization for linkTarget value.

"linkTarget": "cél" is lowercase, while the adjacent "linkType": "Linktípus" and other field labels in this section (e.g., "linkedInLink": "LinkedIn Link") are capitalized. For UI consistency, consider capitalizing to "Cél".

Proposed fix
-    "linkTarget": "cél",
+    "linkTarget": "Cél",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/hu/visual-editor.json` around lines
251 - 253, The translation value for the key "linkTarget" is inconsistently
lowercased; change the value for "linkTarget" from "cél" to "Cél" so it matches
the capitalization style used by neighboring keys like "linkType" and
"linkedInLink" in the visual-editor locale JSON; update only the value for
"linkTarget" in the same object to preserve spacing and formatting.
packages/visual-editor/locales/platform/hu/visual-editor.json-475-476 (1)

475-476: ⚠️ Potential issue | 🟡 Minor

Incorrect Hungarian translations for fontSize and fontSizeDefaultLabel.

  1. "fontSize": "Betűkészlet" — "Betűkészlet" means "character set" / "font family", not "font size". The correct Hungarian term for "font size" is "Betűméret".

  2. "fontSizeDefaultLabel": "Mulasztás" — "Mulasztás" means "omission" or "negligence" (a legal/formal term), not "default" in the UI/computing sense. The correct Hungarian term is "Alapértelmezett" (already correctly used on line 141 for the "default" key).

Note: The same "Mulasztás" mistranslation also exists in pre-existing keys (options.default on line 288, spacingDefaultLabel on line 607) — worth fixing those too in a follow-up.

Proposed fix for the new keys
-  "fontSize": "Betűkészlet",
-  "fontSizeDefaultLabel": "Mulasztás",
+  "fontSize": "Betűméret",
+  "fontSizeDefaultLabel": "Alapértelmezett",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/hu/visual-editor.json` around lines
475 - 476, The translations for the keys "fontSize" and "fontSizeDefaultLabel"
are incorrect: change the value of "fontSize" from "Betűkészlet" to "Betűméret"
and change "fontSizeDefaultLabel" from "Mulasztás" to "Alapértelmezett" so they
correctly map to "font size" and "default" respectively; ensure you update only
the string values for the keys "fontSize" and "fontSizeDefaultLabel" (and, if
desired later, audit other keys using "Mulasztás" such as "options.default" and
"spacingDefaultLabel" in a follow-up).
packages/visual-editor/locales/platform/sk/visual-editor.json-177-177 (1)

177-177: ⚠️ Potential issue | 🟡 Minor

Inconsistent Slovak term for "buttons" — "Gombíky" should be "Tlačidlá".

"Gombíky" refers to physical/clothing buttons in Slovak. The rest of this file consistently uses "Tlačidlo" / "tlačidla" for UI buttons (e.g., line 30 "Tlačidlo s ikonou", line 176 "Text tlačidla", line 643 "Tlačidlo"). This should match.

Proposed fix
-    "buttons": "Gombíky",
+    "buttons": "Tlačidlá",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/sk/visual-editor.json` at line 177,
Replace the incorrect Slovak translation value for the JSON key "buttons"
(currently "Gombíky") with the consistent UI term "Tlačidlá"; update the entry
for "buttons" so it matches the rest of the file's usage (e.g., "Tlačidlo s
ikonou", "Text tlačidla", "Tlačidlo") to ensure consistent UI terminology across
the locale JSON.
packages/visual-editor/locales/platform/sk/visual-editor.json-513-519 (1)

513-519: ⚠️ Potential issue | 🟡 Minor

Inconsistent base words across Slovak plural forms for location counts.

Three different words are used for "location" across the plural forms:

  • locationWithCount_one (line 515): "lokácia"
  • locationWithCount_few / _many (lines 513-514): "miest" (from "miesto" = place)
  • locationWithCount_other (line 516): "lokality"
  • locationsNear_one (line 519): "umiestnenie" (means "placement/positioning", not "location")

Each plural group should use a single base word consistently. Additionally, "umiestnenie" on line 519 is semantically incorrect for a location count — it should align with whichever word the other locationsNear_* forms use (they use "miest").

Suggested fix (using "miesto/miest" consistently, which aligns with the _few/_many forms)
-  "locationWithCount_few": "{{count}} miest",
-  "locationWithCount_many": "{{count}} miest",
-  "locationWithCount_one": "{{count}} lokácia",
-  "locationWithCount_other": "{{count}} lokality",
+  "locationWithCount_few": "{{count}} miesta",
+  "locationWithCount_many": "{{count}} miest",
+  "locationWithCount_one": "{{count}} miesto",
+  "locationWithCount_other": "{{count}} miest",
   "locationsNear_few": "{{count}} miest v blízkosti „{{name}}"",
   "locationsNear_many": "{{count}} miest v blízkosti „{{name}}"",
-  "locationsNear_one": "{{count}} umiestnenie blízko „{{name}}"",
+  "locationsNear_one": "{{count}} miesto v blízkosti „{{name}}"",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/sk/visual-editor.json` around lines
513 - 519, The Slovak entries use inconsistent base words for "location"; update
the keys locationWithCount_one and locationWithCount_other to use the same base
as locationWithCount_few/locationWithCount_many (miesto/miest) and fix
locationsNear_one to match locationsNear_few/locationsNear_many (miest).
Concretely, change locationWithCount_one to use "{{count}} miesto" and
locationWithCount_other to use "{{count}} miest" (so all plural variants align
to miesto/miest), and change locationsNear_one to "{{count}} miesto v blízkosti
„{{name}}“" while keeping locationsNear_few/locationsNear_many as "{{count}}
miest v blízkosti „{{name}}“".
packages/visual-editor/locales/platform/tr/visual-editor.json-511-512 (1)

511-512: ⚠️ Potential issue | 🟡 Minor

locationWithCount_other uses incorrect Turkish pluralization and has a capitalization mismatch.

In Turkish, a noun following a numeral does not take a plural suffix — "5 konumlar" is grammatically incorrect; "5 konum" is correct regardless of count. Every other plural pair in this file (kilometer, mile, totalReviews) uses the same string for both _one and _other, which aligns with this rule.

Additionally, _one capitalises "Konum" while _other uses lowercase "konumlar", creating an inconsistency.

🌐 Proposed fix
-  "locationWithCount_one": "{{count}} Konum",
-  "locationWithCount_other": "{{count}} konumlar",
+  "locationWithCount_one": "{{count}} konum",
+  "locationWithCount_other": "{{count}} konum",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/tr/visual-editor.json` around lines
511 - 512, The two localization keys locationWithCount_one and
locationWithCount_other are incorrect: Turkish does not pluralize nouns after
numerals and the casing is inconsistent; update locationWithCount_other to match
locationWithCount_one by using the same string "{{count}} Konum" so both keys
use the identical, correctly capitalized phrase.
packages/visual-editor/locales/components/et/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

"price" default uses USD ("dollarit") — Estonia uses EUR.

"123,00 dollarit" hard-codes a US Dollar label in a locale file for Estonia, which is part of the Eurozone. Even as a placeholder/example value, this is regionally inaccurate. Consider "123,00 €" or a currency-neutral form.

💡 Suggested correction
-    "price": "123,00 dollarit",
+    "price": "123,00 €",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/et/visual-editor.json` at line 57,
The "price" entry in the Estonian locale (key "price" in visual-editor.json)
incorrectly uses a USD label ("123,00 dollarit"); update the value to an
Estonia-appropriate format such as "123,00 €" or a currency-neutral placeholder
(e.g., "123,00") so the locale no longer hard-codes US dollars; change the
string for the "price" key accordingly.
packages/visual-editor/locales/components/pl/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

"123,00 dolarów" uses US dollars for a Polish locale — should be PLN.

Poland's currency is the złoty (PLN), not the dollar. Using "dolarów" as the placeholder currency in the Polish locale will confuse users seeing this default value in the Editor. The value should reference PLN/złoty, e.g. "123,00 zł".

🌍 Suggested fix
-    "price": "123,00 dolarów",
+    "price": "123,00 zł",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/pl/visual-editor.json` at line 57,
Replace the incorrect currency string for the "price" key in the Polish locale
JSON (key: "price") so it uses PLN/złoty instead of US dollars; update the value
from "123,00 dolarów" to a Polish-format representation like "123,00 zł" (or
"123,00 złotych" if you prefer the full word) to match the locale.
packages/visual-editor/locales/components/ro/visual-editor.json-67-67 (1)

67-67: ⚠️ Potential issue | 🟡 Minor

Minor: lowercase "profil" for consistency with surrounding Romanian strings.

Common nouns are not capitalised mid-sentence in Romanian. Compare with "visitPage": "Vizitați pagina" (line 156) where "pagina" is lowercase.

📝 Suggested fix
-    "visitProfile": "Vizitați Profil"
+    "visitProfile": "Vizitați profil"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/ro/visual-editor.json` at line 67,
The string value for the localization key "visitProfile" in visual-editor.json
uses a capitalized noun ("Vizitați Profil"); change it to lowercase ("Vizitați
profil") to match Romanian sentence casing and remain consistent with other
entries like "visitPage"; update the value for the "visitProfile" key
accordingly.
packages/visual-editor/locales/components/de/visual-editor.json-32-33 (1)

32-33: ⚠️ Potential issue | 🟡 Minor

Inconsistent German word for "event" across sibling keys

"eventImage" uses "Ereignis" (a general occurrence/incident) while "eventTitle" uses "Veranstaltung" (a scheduled/planned event). Both keys describe the same domain concept ("event" as in a calendar/business event), so they should use the same German word. "Veranstaltung" is the more precise choice for a business-events context.

✏️ Suggested correction
-    "eventImage": "Ereignisbild",
+    "eventImage": "Veranstaltungsbild",
     "eventTitle": "Veranstaltungstitel",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/de/visual-editor.json` around lines
32 - 33, The two sibling localization keys use inconsistent German terms for
"event": change the value of "eventImage" from "Ereignisbild" to use the same
domain term as "eventTitle" by replacing it with "Veranstaltungsbild" so both
keys ("eventImage" and "eventTitle") consistently use "Veranstaltung".
packages/visual-editor/locales/components/de/visual-editor.json-26-26 (1)

26-26: ⚠️ Potential issue | 🟡 Minor

"button": "Taste" — misleading for a UI element

"Taste" in German refers to a physical key or hardware button (e.g., a keyboard key). The standard term for a software UI button is "Schaltfläche" (or the widely-accepted loanword "Button", which appears in German UI guidelines and is used unmodified throughout the rest of this file's non-componentDefaults sections). Editors seeing "Taste" may not recognize it as a clickable UI element label.

✏️ Suggested correction
-    "button": "Taste",
+    "button": "Schaltfläche",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/de/visual-editor.json` at line 26,
The translation for the "button" key is misleading ("Taste" implies a physical
key); update the value for the "button" JSON key in
packages/visual-editor/locales/components/de/visual-editor.json to a proper UI
term such as "Schaltfläche" (or consistent use of "Button" if preferred across
the file) so it clearly denotes a clickable software UI element; ensure you only
change the value for the "button" key and keep surrounding keys/formatting
intact.
packages/visual-editor/locales/components/hu/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

Minor translation issue: "eura" → "euró".

"eura" is a genitive form used in some Slavic languages; the standard Hungarian nominative is "euró". The value should likely be "123 euró".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/hu/visual-editor.json` at line 57,
The translation for the key "price" uses the incorrect form "eura"; update the
value for the "price" key in the hu visual-editor localization (key "price")
from "123 eura" to the correct Hungarian nominative "123 euró" so the locale
string reads "123 euró".
packages/visual-editor/locales/platform/lv/visual-editor.json-512-514 (1)

512-514: ⚠️ Potential issue | 🟡 Minor

locationWithCount_other uses an inconsistent short form.

"{{count}} vietas" (line 513) diverges from the full compound noun used in the sibling keys on lines 512 and 514 ("atrašanās vieta" / "atrašanās vietas"). Every analogous key in this file (locationsNear_*, locationsWithinDistanceOf_*) uses the full "atrašanās vieta/vietas" form throughout all plural variants, so the shortened form here appears to be an oversight.

✏️ Suggested correction
-  "locationWithCount_other": "{{count}} vietas",
+  "locationWithCount_other": "{{count}} atrašanās vietas",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/lv/visual-editor.json` around lines
512 - 514, Replace the inconsistent short form in the locale key
locationWithCount_other so it matches the full compound noun used by its
siblings (locationWithCount_one and locationWithCount_zero); change the value
from "{{count}} vietas" to use "atrašanās vietas" (i.e., "{{count}} atrašanās
vietas") to keep pluralization consistent across locationWithCount_* keys.
packages/visual-editor/locales/components/hr/visual-editor.json-64-64 (1)

64-64: ⚠️ Potential issue | 🟡 Minor

Minor translation quality: "subtitle": "Titl" may mislead Croatian speakers.

In Croatian, titl specifically means film/TV subtitles (closed captions). For a UI section subtitle element, podnaslov is the natural term.

✏️ Suggested correction
-    "subtitle": "Titl",
+    "subtitle": "Podnaslov",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/hr/visual-editor.json` at line 64,
The "subtitle" translation value currently uses "Titl", which refers to film/TV
captions in Croatian; update the localization entry for the "subtitle" key in
visual-editor.json so the value is the natural UI term "Podnaslov" (preserve
capitalization style used elsewhere) to avoid misleading Croatian users.
packages/visual-editor/locales/components/nb/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

price default uses USD $ symbol in the Norwegian locale.

Norway's currency is Norwegian krone (kr/NOK). All other locales use their respective local currencies (e.g., Danish uses "DKK", Swedish uses "SEK", German uses "€"), but the Norwegian locale uses $123,00 instead. Consider using "123,00 kr" to match the currency format and decimal separator conventions of Norwegian.

Suggested fix
-    "price": "$123,00",
+    "price": "123,00 kr",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/nb/visual-editor.json` at line 57,
The Norwegian locale entry uses a USD-formatted string for the "price" key in
visual-editor.json (nb locale); update the value for "price" from "$123,00" to a
Norwegian-formatted string like "123,00 kr" so the currency symbol and decimal
separator match Norway/NOK conventions (keep the key name "price" intact).
packages/visual-editor/locales/platform/sv/visual-editor.json-216-216 (1)

216-216: ⚠️ Potential issue | 🟡 Minor

expandedFooterLinks translation drops "footer" — inconsistent with footerLinks.

"Utvidgade sidlänkar" literally means "expanded page/side links". The adjacent key fields.footerLinks (line 222) uses "Sidfotlänkar" — correctly composing sidfot (footer) + länkar (links). For consistency the translation here should include the same "sidfot" stem.

🌐 Suggested fix
-    "expandedFooterLinks": "Utvidgade sidlänkar",
+    "expandedFooterLinks": "Utvidgade sidfotslänkar",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/sv/visual-editor.json` at line 216,
The Swedish translation for the key expandedFooterLinks is inconsistent: change
its value from "Utvidgade sidlänkar" to include "sidfot" to match
fields.footerLinks; update the string for expandedFooterLinks so it reads
"Utvidgade sidfotlänkar" (or another natural Swedish phrasing that preserves
"sidfot") to keep terminology consistent with fields.footerLinks.
packages/visual-editor/locales/components/nl/visual-editor.json-37-37 (1)

37-37: ⚠️ Potential issue | 🟡 Minor

Inconsistent Dutch translation for findALocation.

componentDefaults.findALocation (line 37) translates to "Zoek een locatie", while the top-level findALocation key (line 80) is "Vind een locatie". Both are valid Dutch but they express the same UI action; the two keys should be aligned.

🔤 Suggested alignment
-    "findALocation": "Zoek een locatie",
+    "findALocation": "Vind een locatie",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/nl/visual-editor.json` at line 37,
The componentDefaults.findALocation value and the top-level findALocation are
inconsistent; pick one phrasing and make both identical (e.g., change
componentDefaults.findALocation or the top-level findALocation) so
componentDefaults.findALocation and findALocation use the same Dutch string
across the file; update whichever key (componentDefaults.findALocation or
findALocation) to match the chosen wording.
packages/visual-editor/locales/components/nl/visual-editor.json-67-67 (1)

67-67: ⚠️ Potential issue | 🟡 Minor

Inconsistent noun capitalisation in visitProfile.

"Bezoek Profiel" capitalises "Profiel", but Dutch (unlike German) does not capitalise common nouns. The comparable top-level key "visitPage": "Bezoek pagina" (line 150) correctly uses lowercase. This should be "Bezoek profiel".

🔤 Suggested fix
-    "visitProfile": "Bezoek Profiel"
+    "visitProfile": "Bezoek profiel"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/nl/visual-editor.json` at line 67,
The translation for the key "visitProfile" uses incorrect noun capitalization
("Bezoek Profiel"); update the value to use lowercase for the common noun to
match Dutch style and the existing "visitPage" convention—i.e., change the
string value of visitProfile to "Bezoek profiel".
packages/visual-editor/locales/platform/it/visual-editor.json-518-520 (1)

518-520: ⚠️ Potential issue | 🟡 Minor

Inconsistent Italian preposition for "within" in locationsWithinDistanceOf plural forms.

The unchanged _many form (line 518) uses "all'interno di" while the new _one (line 519) — and the pre-existing _other (line 520) — use "entro". Both mean "within", but mixing them across plural forms of the same key is inconsistent.

✏️ Suggested fix for consistency

Align the _one form with the _other form (keeping "entro"):

- "locationsWithinDistanceOf_many": "{{count}} posizioni all'interno di {{distance}} {{unit}} di \"{{name}}\"",
+ "locationsWithinDistanceOf_many": "{{count}} posizioni entro {{distance}} {{unit}} di \"{{name}}\"",
  "locationsWithinDistanceOf_one": "{{count}} posizione entro {{distance}} {{unit}} di \"{{name}}\"",
  "locationsWithinDistanceOf_other": "{{count}} località entro {{distance}} {{unit}} di \"{{name}}\"",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/it/visual-editor.json` around lines
518 - 520, The Italian translations for the pluralization variants of
locationsWithinDistanceOf are inconsistent: locationsWithinDistanceOf_many
currently uses "all'interno di" while locationsWithinDistanceOf_one and
locationsWithinDistanceOf_other use "entro"; update
locationsWithinDistanceOf_many to use "entro" so all three variants
(locationsWithinDistanceOf_many, locationsWithinDistanceOf_one,
locationsWithinDistanceOf_other) consistently use "entro" for "within".
packages/visual-editor/locales/platform/it/visual-editor.json-512-514 (1)

512-514: ⚠️ Potential issue | 🟡 Minor

Inconsistent Italian word for "location" across locationWithCount plural forms.

locationWithCount_many uses "posizioni" while locationWithCount_other uses "località" — two different Italian words for the same concept within the same key group. Italian pluralization rules mean both _many and _other apply to counts > 1, so users would see different words for the same UI element depending on exact count.

✏️ Suggested fix for consistency
-  "locationWithCount_many": "{{count}} posizioni",
+  "locationWithCount_many": "{{count}} località",
   "locationWithCount_one": "{{count}} posizione",
-  "locationWithCount_other": "{{count}} località",
+  "locationWithCount_other": "{{count}} posizioni",

Or alternatively, unify on "posizioni"/"posizione":

   "locationWithCount_many": "{{count}} posizioni",
   "locationWithCount_one": "{{count}} posizione",
-  "locationWithCount_other": "{{count}} località",
+  "locationWithCount_other": "{{count}} posizioni",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/it/visual-editor.json` around lines
512 - 514, The translations for the locationWithCount plural keys are
inconsistent: locationWithCount_many uses "posizioni" while
locationWithCount_other uses "località"; update the locale entries so both
plural forms use the same Italian word (and keep locationWithCount_one as the
singular "posizione"), e.g., change locationWithCount_other to " {{count}}
posizioni" (or change _many to "località" if you prefer that term) so all plural
variants consistently use the same term across locationWithCount_many and
locationWithCount_other.
packages/visual-editor/locales/components/fi/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

Currency mismatch: "dollaria" (USD) in a Finnish locale that should use EUR.

Finland uses the euro. The placeholder value "123,00 dollaria" uses USD ("dollaria" = dollars). While the decimal formatting is correctly Finnish (comma separator), the currency unit should be euroa or .

🌍 Proposed fix
-    "price": "123,00 dollaria",
+    "price": "123,00 euroa",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/fi/visual-editor.json` at line 57,
The "price" translation uses USD ("dollaria") but Finnish should use euros;
update the value for the "price" key in visual-editor.json to use the euro
currency (e.g., "123,00 euroa" or include the symbol "123,00 €") while
preserving Finnish number formatting (comma decimal separator) and the existing
key "price".
packages/visual-editor/locales/components/fi/visual-editor.json-59-59 (1)

59-59: ⚠️ Potential issue | 🟡 Minor

Grammatical error: "Ammattilainen nimi" should use the genitive case.

In Finnish, when a noun modifies another noun, it takes the genitive form. "Ammattilainen" (nominative) before "nimi" is incorrect; it should be "Ammattilaisen nimi" (genitive).

🔤 Proposed fix
-    "professionalName": "Ammattilainen nimi",
+    "professionalName": "Ammattilaisen nimi",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/fi/visual-editor.json` at line 59,
The localization value for the key "professionalName" uses the incorrect
nominative form "Ammattilainen nimi"; update the string value for the
"professionalName" entry to use the genitive case "Ammattilaisen nimi" so the
Finnish phrase is grammatically correct.
packages/visual-editor/locales/platform/nl/visual-editor.json-251-251 (1)

251-251: ⚠️ Potential issue | 🟡 Minor

"linkTarget": "Doel koppelen" — slightly non-idiomatic Dutch

"Doel koppelen" reads as a verbal phrase ("to link a target") rather than a nominal label. Standard Dutch UI terminology would favour a noun compound such as "Koppeldoel" or "Linkdoel", which aligns better with how the other fields.* labels in this file are phrased.

✏️ Suggested value
-    "linkTarget": "Doel koppelen",
+    "linkTarget": "Koppeldoel",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/nl/visual-editor.json` at line 251,
The value for the translation key "linkTarget" is a verb phrase; change the
string value for the "linkTarget" key to a nominal UI label (e.g., "Koppeldoel"
or "Linkdoel") to match the noun-style used by other fields.* entries—update the
"linkTarget" entry in visual-editor.json so it reads "Koppeldoel" (or your
chosen noun-form) and keep capitalization consistent with neighboring keys.
packages/visual-editor/locales/platform/hr/visual-editor.json-690-692 (1)

690-692: ⚠️ Potential issue | 🟡 Minor

totalReviews_one uses a different Croatian root word than _few/_other.

The existing _few ("recenzije") and _other ("recenzija") forms both derive from recenzija, but the new _one uses pregled — a different, less precise synonym. All three plural forms should use the same root:

📝 Proposed fix
- "totalReviews_one": "{{count}} pregled",
+ "totalReviews_one": "{{count}} recenzija",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/hr/visual-editor.json` around lines
690 - 692, The key "totalReviews_one" uses an inconsistent Croatian root
("pregled"); change its value to use the same root as the other plural forms
(derive from "recenzija") so all three keys — totalReviews_one,
totalReviews_few, totalReviews_other — are consistent (e.g., set
totalReviews_one to "{{count}} recenzija" or the correct singular form of
"recenzija").
packages/visual-editor/locales/platform/ro/visual-editor.json-516-516 (1)

516-516: ⚠️ Potential issue | 🟡 Minor

locationsNear_one uses ASCII quotes instead of Romanian typographic quotes

locationsNear_one uses escaped ASCII quotes \"{{name}}\", while the sibling pluralization forms (_few on line 515, _other on line 517) both use Romanian typographic guillemets „{{name}}". This renders inconsistently at runtime: the _one form will show straight "..." while other forms show „...".

🛠️ Proposed fix
-  "locationsNear_one": "{{count}} locație lângă \"{{name}}\"",
+  "locationsNear_one": "{{count}} locație lângă „{{name}}"",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/ro/visual-editor.json` at line 516,
The localization key locationsNear_one uses escaped ASCII quotes around the
{{name}} interpolation; change it to use Romanian typographic guillemets like
the sibling keys (e.g., „{{name}}”) so the string matches locationsNear_few and
locationsNear_other; update the value for the locationsNear_one entry to use the
same guillemet characters and keep the {{count}} and {{name}} placeholders
intact.
packages/visual-editor/locales/platform/ro/visual-editor.json-519-519 (1)

519-519: ⚠️ Potential issue | 🟡 Minor

locationsWithinDistanceOf_one has mismatched quotation marks around {{name}}

The value opens with the Romanian typographic opening quote „ (U+201E) but closes with an escaped ASCII quote \" (U+0022). Sibling forms (_few on line 518, _other on line 520) consistently use „{{name}}" on both sides. This results in a visually broken „name" in the rendered output for the singular case.

🛠️ Proposed fix
-  "locationsWithinDistanceOf_one": "{{count}} locație la {{distance}} {{unit}} de „{{name}}\"",
+  "locationsWithinDistanceOf_one": "{{count}} locație la {{distance}} {{unit}} de „{{name}}"",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/ro/visual-editor.json` at line 519,
The localization string "locationsWithinDistanceOf_one" uses mismatched opening
and closing quotes around {{name}} (opening U+201E „ but closing ASCII "), fix
the value so both quotes are the same typographic pair used by siblings (use
„{{name}}"), i.e. update the string for the key locationsWithinDistanceOf_one to
use the opening and closing Romanian typographic quotes around {{name}} to match
locationsWithinDistanceOf_few and locationsWithinDistanceOf_other.
packages/visual-editor/locales/platform/cs/visual-editor.json-253-253 (1)

253-253: ⚠️ Potential issue | 🟡 Minor

linkedInLink inconsistently uses English "Link" instead of Czech "odkaz"

The dominant pattern across social link field labels in this file is Czech "odkaz":

  • facebookLink"Facebook odkaz"
  • instagramLink"Instagram odkaz"
  • xLink"X odkaz"
  • youtubeLink"Odkaz na YouTube"

Only pinterestLink and tiktokLink deviate by using English "Link". The new linkedInLink entry follows the minority pattern. For consistency:

🌐 Proposed fix
-    "linkedInLink": "LinkedIn Link",
+    "linkedInLink": "LinkedIn odkaz",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/cs/visual-editor.json` at line 253,
The JSON key "linkedInLink" uses English "Link" while most social link labels
use Czech "odkaz"; update the value for linkedInLink to use the Czech term to
match the established pattern (e.g., change the string for "linkedInLink" to use
"odkaz" like "LinkedIn odkaz"), ensuring consistency with other keys such as
"facebookLink", "instagramLink", "xLink", "pinterestLink", and "tiktokLink".
packages/visual-editor/locales/platform/cs/visual-editor.json-513-519 (1)

513-519: ⚠️ Potential issue | 🟡 Minor

Inconsistent word choice between locationWithCount / locationsNear singular and plural forms

Within both key families, the _one (and _other) forms use "umístění" (abstract: placement/positioning) while _few and _many use "míst" (genitive plural of "místo" = physical place). These are different Czech words, not inflections of the same root, so mixing them within the same pluralization family is inconsistent:

key value
locationWithCount_one {{count}} umístění
locationWithCount_other {{count}} umístění
locationWithCount_few {{count}} míst
locationWithCount_many {{count}} míst
locationsNear_one {{count}} umístění poblíž…
locationsNear_few/many/other {{count}} míst poblíž…

For contrast, locationsWithinDistanceOf_one correctly uses "místo" (nominative singular of "místo").

Suggested fix: align _one/_other to the same root as _few/_many:

🌐 Proposed fix
-  "locationWithCount_one": "{{count}} umístění",
-  "locationWithCount_other": "{{count}} umístění",
+  "locationWithCount_one": "{{count}} místo",
+  "locationWithCount_other": "{{count}} míst",
   "locationsNear_few": "{{count}} míst poblíž „{{name}}"",
   "locationsNear_many": "{{count}} míst poblíž „{{name}}"",
-  "locationsNear_one": "{{count}} umístění poblíž „{{name}}"",
+  "locationsNear_one": "{{count}} místo poblíž „{{name}}"",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/cs/visual-editor.json` around lines
513 - 519, The Czech plural forms are inconsistent: replace the abstract
"umístění" with the same root as the plural "míst" so all forms align;
specifically update locationWithCount_one to "{{count}} místo" and
locationWithCount_other to "{{count}} míst", and update locationsNear_one to
"{{count}} místo poblíž „{{name}}“" (and any locationsNear_other to "{{count}}
míst poblíž „{{name}}“") so the singular uses the nominative "místo" and plurals
use "míst".
packages/visual-editor/locales/platform/pt/visual-editor.json-512-514 (1)

512-514: ⚠️ Potential issue | 🟡 Minor

locationWithCount_many and locationWithCount_other use different Portuguese words inconsistently.

Every other _many/_other sibling pair in this file is identical (e.g., locationsNear_many/other → both "{{count}} locais próximos...", kilometer_many/other → both "quilômetros"). Here, _many uses "locais" while _other uses "localizações". Portuguese plural rules only distinguish singular (one) from plural (other), so _many won't be selected at runtime for pt—but the divergence from the established convention is still a latent trap if plural rules are ever adjusted.

🔧 Proposed fix — align `_many` with `_other`
- "locationWithCount_many": "{{count}} locais",
- "locationWithCount_one": "{{count}} localização",
- "locationWithCount_other": "{{count}} localizações",
+ "locationWithCount_many": "{{count}} localizações",
+ "locationWithCount_one": "{{count}} localização",
+ "locationWithCount_other": "{{count}} localizações",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/pt/visual-editor.json` around lines
512 - 514, The two Portuguese plural keys are inconsistent:
locationWithCount_many uses "locais" while locationWithCount_other uses
"localizações"; update locationWithCount_many to match locationWithCount_other
(i.e., make locationWithCount_many equal to "{{count}} localizações") so that
locationWithCount_many and locationWithCount_other are identical and consistent
with locationWithCount_one.
packages/visual-editor/locales/platform/pl/visual-editor.json-177-177 (1)

177-177: ⚠️ Potential issue | 🟡 Minor

Verify the Polish translation for “buttons.”

Line 177 uses “Pikolak,” which doesn’t look like a standard Polish translation for “Buttons.” Please confirm with the translation source (common translation is “Przyciski”).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/pl/visual-editor.json` at line 177,
The "buttons" translation entry currently reads "Pikolak" which appears
incorrect; update the "buttons" key in visual-editor.json (the "buttons" string)
to the correct Polish translation ("Przyciski") or confirm with your translation
source and replace it accordingly so the JSON entry reads the validated Polish
term.
packages/visual-editor/locales/components/en-GB/visual-editor.json-57-57 (1)

57-57: ⚠️ Potential issue | 🟡 Minor

Wrong currency symbol for en-GB$123.00 should use £.

The price default in componentDefaults uses the US dollar sign, but en-GB represents British Pounds. This placeholder will be shown to UK-locale users in the Editor.

🐛 Proposed fix
-    "price": "$123.00",
+    "price": "£123.00",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/en-GB/visual-editor.json` at line
57, Update the en-GB locale default for the price placeholder to use the British
pound symbol: locate the "price" entry (used by componentDefaults) in
packages/visual-editor/locales/components/en-GB/visual-editor.json and replace
the value "$123.00" with "£123.00" so UK users see the correct currency symbol.
🧹 Nitpick comments (5)
packages/visual-editor/locales/components/et/visual-editor.json (1)

61-61: readMore in componentDefaults differs in register from the top-level key.

componentDefaults.readMore"Loe edasi" (informal, "read on") while the top-level readMore at line 119 → "Lugege rohkem" (formal, "read more"). If these are meant to represent the same CTA label at different call sites, the inconsistent register may confuse translators and users.

♻️ Align to the existing formal register
-    "readMore": "Loe edasi",
+    "readMore": "Lugege rohkem",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/et/visual-editor.json` at line 61,
componentDefaults.readMore uses an informal register ("Loe edasi") while the
top-level readMore uses the formal "Lugege rohkem"; update
componentDefaults.readMore to match the formal register by changing its value to
"Lugege rohkem" so both keys (componentDefaults.readMore and top-level readMore)
are consistent for translators and users.
packages/visual-editor/locales/platform/it/visual-editor.json (1)

251-251: "Obiettivo del collegamento" is a suboptimal translation for linkTarget.

"Obiettivo" (objective/goal) doesn't naturally map to "target" in an Italian UI context (where it refers to the link destination, e.g. _blank, _self). A more natural phrasing would be "Destinazione del collegamento" or "Target del collegamento".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/platform/it/visual-editor.json` at line 251,
Replace the current Italian value for the JSON key "linkTarget" ("Obiettivo del
collegamento") with a more natural UI phrasing such as "Destinazione del
collegamento" (or "Target del collegamento") so the label correctly conveys the
link destination option (e.g., _blank, _self); update the value for "linkTarget"
in the visual-editor.json locale entry accordingly.
packages/visual-editor/locales/components/fi/visual-editor.json (1)

36-36: "Suositellut suosittelut" is repetitive — both words share the root suosittele-.

"Suositellut" (featured/recommended) and "suosittelut" (testimonials) both derive from the same Finnish verb, making the phrase sound redundant. A clearer alternative: "Asiakassuosittelut" or "Suositellut asiakasarviot".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/fi/visual-editor.json` at line 36,
Replace the redundant Finnish label for the "featuredTestimonials" key: change
the value "Suositellut suosittelut" to a clearer, non-redundant phrase such as
"Asiakassuosittelut" or "Suositellut asiakasarviot" by updating the JSON value
for the "featuredTestimonials" property to the chosen alternative.
packages/visual-editor/src/utils/defaultLayoutTranslations.ts (2)

72-82: unknown | undefined return type is redundant — undefined is already a subtype of unknown.

Both getTemplateLayout and getNormalizedTemplateLayout are annotated unknown | undefined; simplify to unknown.

♻️ Proposed refactor
-const getTemplateLayout = (templateId: string): unknown | undefined => {
+const getTemplateLayout = (templateId: string): unknown => {
   return defaultLayoutsByTemplate[templateId as VisualEditorTemplateId];
 };
 
 const getNormalizedTemplateLayout = (
   templateId: string
-): unknown | undefined => {
+): unknown => {
   return normalizedDefaultLayoutsByTemplate[
     templateId as VisualEditorTemplateId
   ];
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/src/utils/defaultLayoutTranslations.ts` around lines
72 - 82, The return type annotations for getTemplateLayout and
getNormalizedTemplateLayout are redundant because undefined is already
assignable to unknown; update both function signatures to return unknown (remove
the union with undefined) — i.e., change the annotated return types on
getTemplateLayout and getNormalizedTemplateLayout from "unknown | undefined" to
"unknown" and ensure any callers still handle potential undefined values at call
sites if needed.

10-10: JsonObject re-declared locally — already exported from jsonUtils.ts.

type JsonObject = Record<string, unknown> is exported from ./i18n/jsonUtils.ts. Importing it directly avoids the duplication.

♻️ Proposed refactor
-type JsonObject = Record<string, unknown>;
+import type { JsonObject } from "./i18n/jsonUtils.ts";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/src/utils/defaultLayoutTranslations.ts` at line 10,
The file redeclares the JsonObject type locally; remove the local "type
JsonObject = Record<string, unknown>" and instead import the exported JsonObject
from ./i18n/jsonUtils.ts (add an import like `import { JsonObject } from
'./i18n/jsonUtils'`), then use that imported JsonObject wherever referenced
(e.g., in defaultLayoutTranslations.ts) to avoid duplicate type definitions and
keep types consistent with jsonUtils.ts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/visual-editor/locales/components/hr/visual-editor.json`:
- Line 57: Update the JSON value for the "price" key in the Croatian locale
(visual-editor.json) to include two decimal places using comma as decimal
separator; replace the current "123 €" string with "123,00 €" so it matches the
EUR formatting used across other locales (e.g., "price": "123,00 €").

In `@packages/visual-editor/src/utils/defaultLayoutTranslations.ts`:
- Around line 327-330: Remove the debug console.log that prints
"shouldInjectDefaultTranslations" (the call currently inside
processTemplateLayoutData) so it doesn't spam production logs; if logging this
value is still useful, replace the console.log with a proper logger call (e.g.,
processLogger.debug or similar) or wrap it behind an environment check (NODE_ENV
!== 'production') so it only runs in development. Ensure you remove the exact
console.log(...) statement referencing shouldInjectDefaultTranslations.

---

Outside diff comments:
In `@packages/visual-editor/locales/platform/zh/visual-editor.json`:
- Around line 1-695: The platform locale is missing the componentDefaults
object, causing fallbacks to English; add a componentDefaults object to this
locale (and all other platform/* locale JSONs) mirroring the structure/keys used
in packages/visual-editor/locales/components/* (use the same keys and
translations as the corresponding platform translations in other locales),
ensuring the top-level JSON includes "componentDefaults": { ... } with the same
identifiers as in the components locale files so runtime lookup uses the
localized defaults instead of falling back to English.

---

Duplicate comments:
In `@packages/visual-editor/src/utils/defaultLayoutTranslations.ts`:
- Around line 19-23: The module currently calls JSON.parse on
defaultLayoutData.main/directory/locator at module load in
defaultLayoutsByTemplate, which can throw and crash imports; change this to
safely parse at runtime using a helper (e.g., safeParseLayout) or lazy-parse on
access: wrap each JSON.parse for defaultLayoutData.* in try/catch and return a
sensible fallback (null/empty layout) and log the error, or store the raw string
and parse via a getter that handles parse errors; update references to
defaultLayoutsByTemplate to use the safe parsing mechanism so malformed JSON no
longer throws during module initialization.

---

Nitpick comments:
In `@packages/visual-editor/locales/components/et/visual-editor.json`:
- Line 61: componentDefaults.readMore uses an informal register ("Loe edasi")
while the top-level readMore uses the formal "Lugege rohkem"; update
componentDefaults.readMore to match the formal register by changing its value to
"Lugege rohkem" so both keys (componentDefaults.readMore and top-level readMore)
are consistent for translators and users.

In `@packages/visual-editor/locales/components/fi/visual-editor.json`:
- Line 36: Replace the redundant Finnish label for the "featuredTestimonials"
key: change the value "Suositellut suosittelut" to a clearer, non-redundant
phrase such as "Asiakassuosittelut" or "Suositellut asiakasarviot" by updating
the JSON value for the "featuredTestimonials" property to the chosen
alternative.

In `@packages/visual-editor/locales/platform/it/visual-editor.json`:
- Line 251: Replace the current Italian value for the JSON key "linkTarget"
("Obiettivo del collegamento") with a more natural UI phrasing such as
"Destinazione del collegamento" (or "Target del collegamento") so the label
correctly conveys the link destination option (e.g., _blank, _self); update the
value for "linkTarget" in the visual-editor.json locale entry accordingly.

In `@packages/visual-editor/src/utils/defaultLayoutTranslations.ts`:
- Around line 72-82: The return type annotations for getTemplateLayout and
getNormalizedTemplateLayout are redundant because undefined is already
assignable to unknown; update both function signatures to return unknown (remove
the union with undefined) — i.e., change the annotated return types on
getTemplateLayout and getNormalizedTemplateLayout from "unknown | undefined" to
"unknown" and ensure any callers still handle potential undefined values at call
sites if needed.
- Line 10: The file redeclares the JsonObject type locally; remove the local
"type JsonObject = Record<string, unknown>" and instead import the exported
JsonObject from ./i18n/jsonUtils.ts (add an import like `import { JsonObject }
from './i18n/jsonUtils'`), then use that imported JsonObject wherever referenced
(e.g., in defaultLayoutTranslations.ts) to avoid duplicate type definitions and
keep types consistent with jsonUtils.ts.

"name": "Ime",
"nearbyLocations": "Lokacije u blizini",
"phone": "Telefon",
"price": "123 €",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Compare price key across all locale componentDefaults files
rg -n '"price"' --type json packages/visual-editor/locales/components/

Repository: yext/visual-editor

Length of output: 2390


"price": "123 €" — fix to include decimal notation for consistency.

The Croatian locale is the only EUR locale without decimal notation. All other Euro-using locales use "123,00 €" format (German, French, Italian, Dutch, etc.), and the English locale uses "$123.00" with decimals. Change to "123,00 €" to align with the standard EUR formatting pattern in this codebase.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/locales/components/hr/visual-editor.json` at line 57,
Update the JSON value for the "price" key in the Croatian locale
(visual-editor.json) to include two decimal places using comma as decimal
separator; replace the current "123 €" string with "123,00 €" so it matches the
EUR formatting used across other locales (e.g., "price": "123,00 €").

Comment on lines +327 to +330
console.log(
"shouldInjectDefaultTranslations:",
shouldInjectDefaultTranslations
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove debug console.log before merging.

This fires on every call to processTemplateLayoutData — i.e., on every template page request — and will pollute production server logs.

🐛 Proposed fix
-  console.log(
-    "shouldInjectDefaultTranslations:",
-    shouldInjectDefaultTranslations
-  );
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(
"shouldInjectDefaultTranslations:",
shouldInjectDefaultTranslations
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/visual-editor/src/utils/defaultLayoutTranslations.ts` around lines
327 - 330, Remove the debug console.log that prints
"shouldInjectDefaultTranslations" (the call currently inside
processTemplateLayoutData) so it doesn't spam production logs; if logging this
value is still useful, replace the console.log with a proper logger call (e.g.,
processLogger.debug or similar) or wrap it behind an environment check (NODE_ENV
!== 'production') so it only runs in development. Ensure you remove the exact
console.log(...) statement referencing shouldInjectDefaultTranslations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

create-dev-release Triggers dev release workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant