Conversation
|
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. |
|
| Key | Languages Removed |
|---|---|
CTA |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
Category
| Key | Languages Removed |
|---|---|
Category |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
Heading
| Key | Languages Removed |
|---|---|
Heading |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
Image
| Key | Languages Removed |
|---|---|
Image |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
Link
| Key | Languages Removed |
|---|---|
Link |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput
| Key | Languages Removed |
|---|---|
addressInput.city |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput.countryCode |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput.line1 |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput.line2 |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput.line3 |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput.postalCode |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput.region |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
addressInput.sublocality |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
arrayField
| Key | Languages Removed |
|---|---|
arrayField |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
borderRadiusDefaultLabel
| Key | Languages Removed |
|---|---|
borderRadiusDefaultLabel |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
categories
| Key | Languages Removed |
|---|---|
categories.directory |
cs,da de |
categories.locator |
cs,da de |
category
| Key | Languages Removed |
|---|---|
category |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
components
| Key | Languages Removed |
|---|---|
components.DirectoryGrid |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
components.Video |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
components.enhancedCallToAction |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
components.faqs |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
components.imageButton |
cs,da et,fi hr,hu it,ja lt,lv nb,nl pl,pt ro,sk sv,tr zh,zh-TW |
components.servicesList |
cs,da de |
copyrightMessage
| Key | Languages Removed |
|---|---|
copyrightMessage |
cs,da de |
ctaTypes
| Key | Languages Removed |
|---|---|
ctaTypes.link |
cs,da de |
currentLocation
| Key | Languages Removed |
|---|---|
currentLocation |
da,pl sk,sv |
emailList
| Key | Languages Removed |
|---|---|
emailList |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
enterSchemaMarkup
| Key | Languages Removed |
|---|---|
enterSchemaMarkup |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
expandedHeaderDesktop
| Key | Languages Removed |
|---|---|
expandedHeaderDesktop |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
expandedHeaderMobile
| Key | Languages Removed |
|---|---|
expandedHeaderMobile |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields
| Key | Languages Removed |
|---|---|
fields.CTAVariant |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.ariaLabel |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.aspectRatioForLogo |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.breadcrumbsBackgroundColor |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.businessName |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.businessNameHeadingLevel |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.cards |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.category |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.contributorName |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.coordinate |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.description |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.destinationURL |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.displayType |
cs,da de |
fields.emailsListLength |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.eventName |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.events |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.format |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.hasLocalizedValue |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.heading |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.headingText |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.headshot |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.height |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.hero |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.hoursText |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.imageUrl |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.includeHyperlink |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.infoColumn |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.insightSection |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.level |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.localGeomodifier |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.localGeomodifierHeadingLevel |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.logo |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.logoLink |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.logoStyles |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.logoUrl |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.mainPhone |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.name |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.HoursStatus |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.HoursTable |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.base |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.bottom |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.large |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.right |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.showFullText |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.small |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.sticky |
zh-TW |
fields.options.top |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.options.truncate |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.presetImageType |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.primaryCTAVariant |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.primaryCta |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.primaryHeader |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.primaryHeaderLinks |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.products |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.secondaryCTAVariant |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.secondaryCta |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.secondaryFooter |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.secondaryFooterLinks |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.secondaryHeader |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.secondaryHeaderLinks |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.secondaryLinks |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.servicesColumn |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.servicesList |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.siteName |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.socialLinks |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.socialMedia |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.target |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.team |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.teamSection |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.testimonialSection |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.testimonials |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.textList |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.title |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.url |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.utilityImagesStyles |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.utilityImagesWidth |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.width |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
filters
| Key | Languages Removed |
|---|---|
filters |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
label
| Key | Languages Removed |
|---|---|
label |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
linkType
| Key | Languages Removed |
|---|---|
linkType |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
loadingReviews
| Key | Languages Removed |
|---|---|
loadingReviews |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
localGeomodifier
| Key | Languages Removed |
|---|---|
localGeomodifier |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
logoLink
| Key | Languages Removed |
|---|---|
logoLink |
fr |
mediaType
| Key | Languages Removed |
|---|---|
mediaType |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
name
| Key | Languages Removed |
|---|---|
name |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
noHeroFieldsMsg
| Key | Languages Removed |
|---|---|
noHeroFieldsMsg |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
noPromoFieldsMsg
| Key | Languages Removed |
|---|---|
noPromoFieldsMsg |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
pageSettings
| Key | Languages Removed |
|---|---|
pageSettings |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages
| Key | Languages Removed |
|---|---|
presetImages.appGallery |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.appGalleryOutline |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.appStore |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.appStoreOutline |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.apple |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.arrowDown |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.arrowLeft |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.arrowRight |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.arrowUp |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.calendar |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.check |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.close |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.download |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.dribbble |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.email |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.facebook |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.figma |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.galaxyStore |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.galaxyStoreOutline |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.google |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.googlePlay |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.googlePlayOutline |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.heart |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.location |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.menu |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.minus |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.next |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.pause |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.phone |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.play |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.plus |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.previous |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.search |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.share |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.star |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.twitter |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
presetImages.uberEats |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
primaryHeader
| Key | Languages Removed |
|---|---|
primaryHeader |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
professionalHero
| Key | Languages Removed |
|---|---|
professionalHero |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
recentReviews
| Key | Languages Removed |
|---|---|
recentReviews |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
search
| Key | Languages Removed |
|---|---|
search |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
secondaryHeader
| Key | Languages Removed |
|---|---|
secondaryHeader |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme
| Key | Languages Removed |
|---|---|
theme.fontWeight.black |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.bold |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.extrabold |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.extralight |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.light |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.medium |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.normal |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.semibold |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.fontWeight.thin |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.radius.pill |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
theme.radius.pill_shape |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
title
| Key | Languages Removed |
|---|---|
title |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
video
| Key | Languages Removed |
|---|---|
video |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
WalkthroughThis PR modernizes the i18n infrastructure by replacing i18next-scanner with i18next-cli and restructuring the translation pipeline. It updates 23 locale files across platform and components directories, adds new i18n configuration files for extracting and linting translations, introduces new npm scripts for extract/translate/propagate/lint workflows, and removes legacy translation management scripts. Additionally, multiple component files are updated to align with new translation key naming conventions (e.g., lowercase keys) and i18n patterns. The PR also adds utility functions for JSON/locale handling and introduces new validation tooling for interpolation variables in translations. Sequence Diagram(s)sequenceDiagram
actor Dev as Developer
participant CLI as i18next-cli
participant Extract as Extract Step
participant Translate as Translate Step
participant Propagate as Propagate Step
participant Lint as Lint Step
participant Verify as Verify Interpolation
participant Locale as Locale Files
Dev->>CLI: Run i18n:update
CLI->>Extract: i18n:extract:platform
Extract->>Locale: Scan TS/TSX for keys
Locale-->>Extract: Return found keys
Extract->>Locale: Write extracted.json
CLI->>Translate: i18n:translate:platform
Translate->>Locale: Load platform en & target locales
Locale-->>Translate: Return locale data
Translate->>Translate: Mask interpolation vars
Translate->>Translate: Translate missing/empty keys
Translate->>Translate: Unmask interpolation vars
Translate->>Locale: Update platform locales
CLI->>Propagate: i18n:propagate:components
Propagate->>Locale: Load platform & components locales
Locale-->>Propagate: Return locale data
Propagate->>Propagate: Build allowed key set
Propagate->>Propagate: Sync platform→components keys
Propagate->>Locale: Update components locales
CLI->>Lint: i18n:lint
Lint->>Locale: Check for empty translations
Locale-->>Lint: Return validation results
Lint-->>CLI: Report issues
CLI->>Verify: i18n:check:interpolation
Verify->>Locale: Validate {{var}} consistency
Locale-->>Verify: Return validation results
Verify-->>CLI: Report mismatches
CLI-->>Dev: Workflow complete
Possibly Related PRs
Suggested Labels
Suggested Reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
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 (4)
packages/visual-editor/locales/components/sv/visual-editor.json (1)
25-37:⚠️ Potential issue | 🟡 MinorPolish Swedish translations for new section labels.
Lines 25–37 and 62–75 include a few literal/awkward strings (or English) that read unnaturally in Swedish UI. Consider updating for consistency with common terminology.
✏️ Example adjustments (confirm with localization)
- "coreInfoSection": "Kärninfo -sektionen", + "coreInfoSection": "Kärninfo-sektionen", - "hours": "Timme", - "hoursSection": "Timmarssektion", + "hours": "Öppettider", + "hoursSection": "Öppettidsavsnitt", - "promoMedia": "Promo media", + "promoMedia": "Kampanjmedia", - "servicesSection": "Serviceavdelning", + "servicesSection": "Tjänsteavsnitt",Also applies to: 62-75
packages/visual-editor/locales/platform/ja/visual-editor.json (1)
28-28:⚠️ Potential issue | 🟡 Minor“パン塊” is an incorrect breadcrumb term.
For breadcrumb navigation, “パンくず” or “パンくずリスト” is the standard UI term.
✍️ Suggested wording
- "breadcrumb": "パン塊", + "breadcrumb": "パンくず",packages/visual-editor/locales/platform/nb/visual-editor.json (1)
141-141:⚠️ Potential issue | 🟡 MinorIncorrect Norwegian translation for "Default".
The translation "Misligholde" is used for "Default" in multiple places, but this Norwegian word means "to default on a payment" or "to neglect/fail an obligation" — not a default/fallback option in a UI context. The correct translation for a default setting should be "Standard".
Affected locations:
- Line 141:
"default": "Misligholde"- Line 275:
"default": "Misligholde"- Line 448:
"fontSizeDefaultLabel": "Misligholde"- Line 566:
"spacingDefaultLabel": "Misligholde"🌍 Proposed fix for translation accuracy
- "default": "Misligholde", + "default": "Standard",- "default": "Misligholde", + "default": "Standard",- "fontSizeDefaultLabel": "Misligholde", + "fontSizeDefaultLabel": "Standard",- "spacingDefaultLabel": "Misligholde", + "spacingDefaultLabel": "Standard",Also applies to: 275-275, 448-448, 566-566
packages/visual-editor/locales/platform/fr/visual-editor.json (1)
83-85:⚠️ Potential issue | 🟡 MinorSame interpolation issue:
{{numéro}}should likely be{{number}}.This is the same issue as in the components French locale. The interpolation variable
{{numéro}}should match the code's parameter name, which is likelynumber.Proposed fix
"footerUtilityImagesSlot": { - "defaultAlt": "Image utilitaire {{numéro}}" + "defaultAlt": "Image utilitaire {{number}}" },
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/components/ja/visual-editor.json`:
- Line 46: The translation key locationsWithinDistanceOf_one uses non-matching
placeholders {{距離}} and {{ユニット}} which i18next won't interpolate and differ from
the _other variant; update the string for locationsWithinDistanceOf_one to use
the same interpolation tokens as the plural form (e.g., {{distance}} and
{{unit}}) and mirror the structure of locationsWithinDistanceOf_other so both
singular and plural keys interpolate consistently.
In `@packages/visual-editor/locales/components/pt/visual-editor.json`:
- Around line 20-24: The Portuguese and French translations use locale-specific
placeholder names ({{número}} / {{numéro}}) but the app passes the interpolation
key "number"; update the translation key
components.footerUtilityImagesSlot.defaultAlt (and the equivalent French key) to
use the placeholder {{number}} so the runtime interpolation receives the correct
variable name.
In `@packages/visual-editor/locales/components/ro/visual-editor.json`:
- Line 9: The "breadcrumb" translation value in the locales JSON is incorrect
("Pescăruș" = seagull); update the value for the "breadcrumb" key in
packages/visual-editor/locales/components/ro/visual-editor.json to a correct
Romanian term such as "Traseu de navigare", "Navigare" or leave as "Breadcrumb"
(choose the preferred term used elsewhere for consistency) so the UI label
correctly reflects the navigation breadcrumb element.
In `@packages/visual-editor/locales/platform/ja/visual-editor.json`:
- Line 481: The translation key locationsWithinDistanceOf_one uses non-matching
placeholder names {{距離}} and {{ユニット}} which i18next won't replace; update the
value for locationsWithinDistanceOf_one to use the same interpolation
placeholders as locationsWithinDistanceOf_other (e.g., {{distance}} and
{{unit}}) and preserve spacing/order and plural form so interpolation works
consistently across both keys.
In `@packages/visual-editor/package.json`:
- Line 85: The package.json dependency for i18next-cli is invalid (currently
"^1.42.0"); confirm whether version 1.42.0 exists in the npm registry and if not
update the i18next-cli entry to a valid published version (e.g., "^1.36.1") or
pin to the exact published release; edit the "i18next-cli" dependency in
package.json (alongside the existing "i18next" entry) to a registry-valid semver
and run npm/yarn install to verify resolution.
In `@packages/visual-editor/scripts/propagatePlatformToComponents.mjs`:
- Around line 10-16: The loadJsonSafe function currently swallows all errors and
returns {} for any failure; change loadJsonSafe to only treat missing files as
empty by catching the fs.readFile/JSON.parse error, checking the error code
(e.g., err.code === 'ENOENT') and returning {} only for that case, and
rethrowing (or propagate) any other errors so malformed JSON or read-permission
issues surface; update references to loadJsonSafe accordingly so callers still
get the parsed object when successful.
🟡 Minor comments (35)
packages/visual-editor/locales/platform/hu/visual-editor.json-244-244 (1)
244-244:⚠️ Potential issue | 🟡 MinorLocalize the new
linkTargetlabel.This value is still English in the Hungarian file.
📝 Suggested translation
- "linkTarget": "Link Target", + "linkTarget": "Hivatkozás célja",packages/visual-editor/locales/components/pl/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorTypo in translation value: "Breatcrumb" should be a proper Polish translation.
The value
"Breatcrumb"appears to be a typo of the English word "Breadcrumb" rather than an actual Polish translation. This should be translated to Polish, e.g.,"Ścieżka nawigacji"(navigation path) or"Nawigacja okruszkowa"(breadcrumb navigation).🐛 Proposed fix
- "breadcrumb": "Breatcrumb", + "breadcrumb": "Ścieżka nawigacji",packages/visual-editor/locales/components/et/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorPossible mistranslation: "Riivsaia" is the culinary breadcrumb.
"Riivsaia" in Estonian refers to breadcrumbs used in cooking (food item), not the navigation UI concept. For navigation breadcrumbs, consider using a term that conveys the path/trail concept, such as "Teekond" (path), "Jäljerida" (trail), or simply retaining "Breadcrumb" as a recognized UI term.
packages/visual-editor/locales/components/sv/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorFix Swedish typo for breadcrumb label.
Line 9 looks misspelled (“Brödsmum”); likely intended “Brödsmulor”.
✏️ Suggested fix
- "breadcrumb": "Brödsmum", + "breadcrumb": "Brödsmulor",packages/visual-editor/locales/components/lv/visual-editor.json-35-37 (1)
35-37:⚠️ Potential issue | 🟡 MinorTranslation inconsistency: "hours" translated as "Laiks" (time) instead of "Stundas" (hours).
Line 35 translates
"hours"as"Laiks", which means "time" in Latvian. However, line 36 correctly uses "Stundu" (genitive of "Stundas") in"hoursSection": "Stundu sadaļa". This inconsistency suggests"hours"should be"Stundas"to match the section key and accurately represent business hours.Proposed fix
- "hours": "Laiks", + "hours": "Stundas",packages/visual-editor/locales/components/hr/visual-editor.json-35-37 (1)
35-37:⚠️ Potential issue | 🟡 MinorAmbiguous and potentially incorrect translations for section labels.
A few translation concerns:
- Line 35: "Sate" uses the accusative case, which is unusual for a standalone label. Consider "Sati" (nominative) or "Radno vrijeme" (working hours).
- Lines 36-37: Both "hoursSection" and "informationSection" translate to the identical "Odjeljak" (Section), losing semantic distinction. Consider "Odjeljak s radnim vremenom" and "Informacijski odjeljak" to preserve context.
packages/visual-editor/locales/components/hr/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorPotentially incorrect translation for "breadcrumb".
"Krušnica" means "breadbox" in Croatian, not the UI navigation concept of breadcrumbs. For navigation breadcrumbs, consider using "Navigacijska staza" (navigation path) or "Breadcrumb" (borrowed term), which are more commonly understood in Croatian UI contexts.
packages/visual-editor/locales/components/sk/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorLikely mistranslation: "Strúhanka" is the culinary term for breadcrumbs.
"Strúhanka" refers to bread crumbs used in cooking (for breading food). For UI navigation breadcrumbs, consider using "Navigačná cesta" (navigation path) or "Drobečková navigácia", which are more appropriate for the navigation context.
packages/visual-editor/locales/components/sk/visual-editor.json-35-37 (1)
35-37:⚠️ Potential issue | 🟡 MinorPotential translation inconsistencies.
A few translations may need review:
Line 36:
"hoursSection": "Čas"— "Čas" means "Time", but the key suggests "Hours Section". Consider "Otváracie hodiny" (Opening hours) for consistency with"hours": "Hodiny".Line 60:
"phone": "Telefonovať"— This is the verb infinitive "To phone/call". If used as a noun label, "Telefón" would be more appropriate. If it's a call-to-action, "Zavolať" (Call) might work better.Lines 37, 75: Multiple keys (
informationSection,servicesSection) translate to the same generic "Sekcia", which may cause ambiguity if displayed in different UI contexts.Also applies to: 60-60
packages/visual-editor/locales/platform/hr/visual-editor.json-244-244 (1)
244-244:⚠️ Potential issue | 🟡 MinorUntranslated text in Croatian locale.
The value "Link Target" is English and should be translated to Croatian for consistency. Consider using "Cilj veze" or "Odredište veze".
Suggested fix
- "linkTarget": "Link Target", + "linkTarget": "Cilj veze",packages/visual-editor/locales/platform/it/visual-editor.json-483-484 (1)
483-484:⚠️ Potential issue | 🟡 MinorInconsistent capitalization between singular and plural forms.
The singular form uses lowercase
posizionewhile the plural form uses uppercaseLocalità. For consistency, both should use the same casing (typically lowercase in Italian for common nouns in mid-sentence context).📝 Suggested fix
- "locationWithCount_one": "{{count}} posizione", - "locationWithCount_other": "{{count}} Località", + "locationWithCount_one": "{{count}} posizione", + "locationWithCount_other": "{{count}} località",packages/visual-editor/locales/components/nb/visual-editor.json-25-25 (1)
25-25:⚠️ Potential issue | 🟡 MinorFix the typo and verify new section labels are fully localized.
I see a spacing typo in
coreInfoSection, andpromoMediais still in English. While you’re here, please confirm the new section labels (hours,hoursSection,informationSection,services,servicesSection) align with your Norwegian terminology.🔧 Proposed fix for the typo
- "coreInfoSection": "Kjerneinfo -seksjon", + "coreInfoSection": "Kjerneinfo-seksjon",Also applies to: 35-37, 60-63, 74-75
packages/visual-editor/locales/components/ja/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 Minor“パン塊” is an incorrect breadcrumb term.
For breadcrumb navigation, “パンくず” or “パンくずリスト” is the common UI wording in Japanese. Consider aligning to that.
✍️ Suggested wording
- "breadcrumb": "パン塊", + "breadcrumb": "パンくず",packages/visual-editor/locales/platform/ro/visual-editor.json-451-451 (1)
451-451:⚠️ Potential issue | 🟡 MinorFix hyphen spacing in “Heading”.
There’s an extra space around the hyphen that will render awkwardly.
📝 Proposed fix
- "Heading": "Îndreptându -se", + "Heading": "Îndreptându-se",packages/visual-editor/locales/platform/tr/visual-editor.json-323-326 (1)
323-326:⚠️ Potential issue | 🟡 MinorAlign “HoursTable” translation with existing label.
components.hoursTableuses “Saatler Tablosu”, but the option value is “Saat Tablosu”. Consider matching to avoid inconsistent UI wording.✏️ Suggested translation tweak
- "HoursTable": "Saat Tablosu", + "HoursTable": "Saatler Tablosu",packages/visual-editor/locales/platform/tr/visual-editor.json-206-208 (1)
206-208:⚠️ Potential issue | 🟡 MinorUse the correct accusative form for “expand footer.”
“Altbilgi genişlet” is ungrammatical; the natural UI verb is “Altbilgiyi genişlet”.
✏️ Suggested translation tweak
- "expandFooter": "Altbilgi genişlet", + "expandFooter": "Altbilgiyi genişlet",packages/visual-editor/locales/platform/tr/visual-editor.json-479-484 (1)
479-484:⚠️ Potential issue | 🟡 MinorUse singular noun after numbers in Turkish.
For counted quantities, Turkish keeps the noun singular (e.g., “5 konum”, not “5 konumlar”). Also consider consistent casing between
_oneand_other.✏️ Suggested translation tweak
- "locationWithCount_one": "{{count}} Konum", - "locationWithCount_other": "{{count}} konumlar", + "locationWithCount_one": "{{count}} konum", + "locationWithCount_other": "{{count}} konum",packages/visual-editor/locales/platform/tr/visual-editor.json-44-45 (1)
44-45:⚠️ Potential issue | 🟡 MinorDifferentiate verb “close” from state “closed.”
With the new
closedkey, bothcloseandclosedtranslate to “Kapalı”. Ifcloseis a button/action, the more natural verb is “Kapat”, while “Kapalı” fits the state. Please confirm intent.✏️ Suggested translation tweak
- "close": "Kapalı", + "close": "Kapat", "closed": "Kapalı",packages/visual-editor/locales/platform/cs/visual-editor.json-403-403 (1)
403-403:⚠️ Potential issue | 🟡 MinorPrefer the imperative form for “showCTA”.
“Zobrazit …” is infinitive; the imperative “Zobrazte …” aligns better with the Czech style guideline for action labels. Based on learnings: In Czech translations for the visual editor, prefer imperative verb forms that align with the English phrasing (e.g., use 'Naplňte nádobu' for 'Fill Container') rather than adjective+noun constructions.✏️ Suggested update
- "showCTA": "Zobrazit výzvu k akci", + "showCTA": "Zobrazte výzvu k akci",packages/visual-editor/locales/platform/cs/visual-editor.json-451-451 (1)
451-451:⚠️ Potential issue | 🟡 Minor“Heading” is better translated as “Nadpis”.
“Záhlaví” maps to “Header” and can confuse with existing header labels.✏️ Suggested update
- "Heading": "Záhlaví", + "Heading": "Nadpis",packages/visual-editor/locales/platform/cs/visual-editor.json-45-45 (1)
45-45:⚠️ Potential issue | 🟡 MinorUse sentence case for the “closed” status label.
Uppercase “ZAVŘENO” is inconsistent with other status strings and can read as shouting. Consider “Zavřeno” unless UI styling uppercases it.✏️ Suggested update
- "closed": "ZAVŘENO", + "closed": "Zavřeno",packages/visual-editor/locales/components/nl/visual-editor.json-35-37 (1)
35-37:⚠️ Potential issue | 🟡 MinorUse compound form to match Dutch conventions and align with similar translations in this file.
"Uren sectie" (two words) is not standard Dutch spelling. The compound form "urensectie" follows Dutch rules for compound nouns and aligns with "Dienstensectie" (servicesSection) already in the file.✏️ Proposed change
- "hoursSection": "Uren sectie", + "hoursSection": "Urensectie",packages/visual-editor/locales/components/nl/visual-editor.json-60-63 (1)
60-63:⚠️ Potential issue | 🟡 MinorUse idiomatic Dutch compound forms for consistency.
"Sectie Fotogalerij" should be "Fotogalerijsectie" and "Promo media" should be "Promomedia" per Dutch compound noun conventions (samenstellingen schrijf je aaneen). Note that "Promobanner" on line 62 already uses the correct compound form, establishing the pattern.✏️ Proposed changes
- "photoGallerySection": "Sectie Fotogalerij", + "photoGallerySection": "Fotogalerijsectie", ... - "promoMedia": "Promo media", + "promoMedia": "Promomedia",packages/visual-editor/locales/platform/et/visual-editor.json-483-484 (1)
483-484:⚠️ Potential issue | 🟡 MinorChange
locationWithCount_otherfrom nominative plural to partitive singular.Estonian grammar requires partitive singular after numerals greater than 1 (e.g., "kaks asukohta", "kolm asukohta"). The current nominative plural form "asukohad" is grammatically incorrect; it should be the partitive singular "asukohta".
✏️ Suggested fix
- "locationWithCount_other": "{{count}} asukohad", + "locationWithCount_other": "{{count}} asukohta",packages/visual-editor/locales/platform/sk/visual-editor.json-483-484 (1)
483-484:⚠️ Potential issue | 🟡 MinorAlign singular/plural noun for location counts.
The singular “umiestnenie” doesn’t match the plural “lokality.” Consider “lokalita/lokality.”Suggested wording
- "locationWithCount_one": "{{count}} umiestnenie", - "locationWithCount_other": "{{count}} lokality", + "locationWithCount_one": "{{count}} lokalita", + "locationWithCount_other": "{{count}} lokality",packages/visual-editor/locales/platform/sk/visual-editor.json-207-207 (1)
207-207:⚠️ Potential issue | 🟡 MinorPrefer an imperative form for the expand action.
“Rozširovať” reads like an ongoing action; UI commands elsewhere use an imperative (“Zobraziť”, “Skryť”). Consider “Rozšíriť pätu” to match “Rozšírená päta.”Suggested wording
- "expandFooter": "Rozširovať pätu", + "expandFooter": "Rozšíriť pätu",packages/visual-editor/locales/platform/sk/visual-editor.json-451-451 (1)
451-451:⚠️ Potential issue | 🟡 MinorTranslate “Heading” as a noun.
“Hlavný” is an adjective; for a component label, “Nadpis” is clearer.Suggested wording
- "Heading": "Hlavný", + "Heading": "Nadpis",packages/visual-editor/locales/platform/sk/visual-editor.json-467-467 (1)
467-467:⚠️ Potential issue | 🟡 MinorUse a noun for “Link.”
“Prepojiť” is a verb, while nearby labels use the noun “odkaz” (e.g., “linkLabel”).Suggested wording
- "Link": "Prepojiť", + "Link": "Odkaz",packages/visual-editor/scripts/generateTranslations.mjs-74-76 (1)
74-76:⚠️ Potential issue | 🟡 MinorTighten context-marker stripping to avoid deleting legitimate bracketed text.
The current regex removes any bracketed content, which can truncate translations that legitimately include brackets. Target the specific
[[context: ...]]marker instead.🐛 Suggested fix
function removeEmbeddedContext(text) { - return text.replace(/\[+.*?\]+/g, "").trim(); + return text + .replace(/\s*\[\[context:.*?]]\s*/g, " ") + .replace(/\s{2,}/g, " ") + .trim(); }packages/visual-editor/locales/components/it/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorIncorrect translation: "Pane" means "Bread", not "Breadcrumb".
The Italian translation for
breadcrumbis incorrect. "Pane" literally means "Bread" in Italian. For a navigation breadcrumb, the correct translation would be "Percorso di navigazione" (navigation path) or "Briciole di pane" (literal breadcrumbs, commonly used in UI contexts).Suggested fix
- "breadcrumb": "Pane", + "breadcrumb": "Percorso di navigazione",packages/visual-editor/locales/components/fi/visual-editor.json-37-37 (1)
37-37:⚠️ Potential issue | 🟡 MinorIncorrect translation: "Tiedonsiirto" means "Data transfer", not "Information Section".
The Finnish translation for
informationSectionis incorrect. "Tiedonsiirto" means "Data transfer" in Finnish. The correct translation for "Information Section" would be "Tiedot-osio" or "Tietoja-osio".Suggested fix
- "informationSection": "Tiedonsiirto", + "informationSection": "Tiedot-osio",packages/visual-editor/locales/components/cs/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorIncorrect translation: "Strouha" means "ditch/gutter", not "Breadcrumb".
The Czech translation for
breadcrumbis incorrect. "Strouha" means "ditch" or "gutter" in Czech. For navigation breadcrumbs, the correct translation would be "Drobečková navigace" (breadcrumb navigation) or simply retain "Breadcrumb" as many Czech applications do.Suggested fix
- "breadcrumb": "Strouha", + "breadcrumb": "Drobečková navigace",packages/visual-editor/locales/components/fr/visual-editor.json-21-23 (1)
21-23:⚠️ Potential issue | 🟡 MinorInterpolation variable
{{numéro}}is incorrect — must be{{number}}.The code passes
numberas the interpolation parameter (line 85 in FooterUtilityImagesSlot.tsx), but the French locale uses{{numéro}}. This mismatch will cause the French translation to display literally as "Image utilitaire {{numéro}}" instead of interpolating the image number. The English locale correctly uses{{number}}.packages/visual-editor/locales/platform/zh-TW/visual-editor.json-479-484 (1)
479-484:⚠️ Potential issue | 🟡 MinorAlign count phrasing between
_oneand_other.
_othercurrently drops the classifier, yielding “2位置”. Match the_onephrasing for consistency.🛠️ Suggested fix
- "locationsNear_other": "“{{name}}”附近有{{count}}位置", + "locationsNear_other": "“{{name}}”附近有 {{count}} 個位置", ... - "locationWithCount_other": "{{count}}位置", + "locationWithCount_other": "{{count}} 個位置",packages/visual-editor/locales/components/zh-TW/visual-editor.json-42-47 (1)
42-47:⚠️ Potential issue | 🟡 MinorFix inconsistent count wording between
_oneand_other.
_oneuses 「個位置」 while_otherdrops the classifier, producing outputs like “2位置”. Align the_otherstrings with the_oneformat.🛠️ Suggested fix
- "locationWithCount_other": "{{count}}位置", + "locationWithCount_other": "{{count}} 個位置", ... - "locationsNear_other": "“{{name}}”附近有{{count}}位置", + "locationsNear_other": "“{{name}}”附近有 {{count}} 個位置",
🧹 Nitpick comments (16)
packages/visual-editor/locales/components/tr/visual-editor.json (2)
25-37: Minor capitalization inconsistency in section labels.There's inconsistent capitalization between section translations:
- Title case:
"coreInfoSection": "Çekirdek Bilgi Bölümü","hoursSection": "Saatler Bölümü"- Sentence case:
"informationSection": "Bilgi bölümü"Consider aligning to a consistent style (likely title case to match the majority).
💅 Suggested fix for consistency
- "informationSection": "Bilgi bölümü", + "informationSection": "Bilgi Bölümü",
62-63: Minor capitalization inconsistency in promo labels.Similar inconsistency here:
"promoBanner": "Promosyon Banner'ı"(title case)"promoMedia": "Promosyon medyası"(sentence case)💅 Suggested fix for consistency
- "promoMedia": "Promosyon medyası", + "promoMedia": "Promosyon Medyası",packages/visual-editor/src/components/Locator.tsx (1)
83-93: Pluralization fallback may produce grammatically incorrect text.The
defaultValueuses the singular form ("mile", "kilometer") regardless ofcount. If translation keys are missing, i18next will return the singular default even whencount > 1, producing strings like "5 mile" instead of "5 miles".Consider using a pluralized fallback or ensuring the translation keys always exist:
🔧 Proposed fix with pluralized fallback
const translateDistanceUnit = ( t: (key: string, options?: Record<string, unknown>) => string, unit: "mile" | "kilometer", count: number ) => { if (unit === "mile") { - return t("mile", { count, defaultValue: "mile" }); + return t("mile", { count, defaultValue: count === 1 ? "mile" : "miles" }); } - return t("kilometer", { count, defaultValue: "kilometer" }); + return t("kilometer", { count, defaultValue: count === 1 ? "kilometer" : "kilometers" }); };packages/visual-editor/locales/components/lv/visual-editor.json (2)
9-9: Consider using a UI-appropriate term for "breadcrumb"."Rīvmaize" is the literal Latvian translation for breadcrumbs (the food item). For navigation breadcrumbs in UI contexts, some locales use an adapted term or keep the English "breadcrumb" to preserve the metaphor. This might confuse users expecting a navigation-related term.
Please verify with a native Latvian speaker or the localization team whether "Rīvmaize" is the preferred UI term for navigation breadcrumbs, or if an alternative like "Navigācijas ceļš" (navigation path) would be clearer.
60-63: "promoMedia" left untranslated.
"promoMedia": "Promo Media"remains in English. If this is intentional (e.g., brand term), this is fine. Otherwise, consider translating to Latvian such as "Reklāmas mediji" for consistency with other translated keys like"promoBanner": "Reklāmas reklāmkarogs".packages/visual-editor/locales/platform/fi/visual-editor.json (3)
131-132: Duplicate keys with different casing at root level.Both
ctaandCTAexist at the same nesting level with identical values. This creates ambiguity for developers choosing which key to use, and one may become orphaned over time. If these serve distinct purposes (e.g., component name vs. field label), consider documenting the distinction or using different key paths.The same pattern appears with
link/Linkat lines 466-467.
190-191: Duplicate field keys:ctaVariantvsCTAVariant.Similar to root-level duplicates,
fields.ctaVariant(line 190) andfields.CTAVariant(line 191) both exist with nearly identical translations (only whitespace differs:"CTA -variantti"vs"CTA-variantti"). Consider consolidating to a single key.
324-325: PascalCase keys infields.optionsbreak convention.
HoursStatusandHoursTableuse PascalCase while surrounding options likehour12,hour24, andimageuse camelCase. This suggests these may be component type identifiers extracted differently by the new tooling.packages/visual-editor/locales/platform/hr/visual-editor.json (1)
483-484: Consider adding_fewplural form for complete Croatian pluralization.Croatian uses different plural forms: "lokacija" (1), "lokacije" (2-4), "lokacija" (5+). The current setup handles 1 and 5+ correctly, but displaying "2 lokacija" instead of "2 lokacije" would be grammatically incorrect.
If i18next is configured for Croatian plural rules, consider adding:
"locationWithCount_few": "{{count}} lokacije"packages/visual-editor/locales/platform/lt/visual-editor.json (1)
324-325: Duplicate keys underoptions:HoursStatusandHoursTable.These PascalCase keys duplicate existing keys at
components.hoursStatus(line 95) andcomponents.hoursTable(line 96) with identical translations. If intentional for different namespaces, this is acceptable; otherwise, consider referencing the existing keys.packages/visual-editor/locales/components/hu/visual-editor.json (3)
9-9: Confirm breadcrumb term matches your HU glossary.“Zsemlemorzsa” is very literal; if your UI standard uses “morzsamenü” (or similar), consider aligning for consistency.
🔤 Example adjustment (if this matches your glossary)
- "breadcrumb": "Zsemlemorzsa", + "breadcrumb": "Morzsamenü",
35-37: Consider aligning “hours” terminology with standard business-hours wording.If your product glossary prefers “Nyitvatartás”, these two keys might read more naturally.
🔤 Example adjustment (if this matches your glossary)
- "hours": "Órák", - "hoursSection": "Órás szakasz", + "hours": "Nyitvatartás", + "hoursSection": "Nyitvatartás szakasz",
60-63: Align promo banner wording with existing “szalaghirdetés” usage.
heroBanneruses “szalaghirdetés”, so keepingpromoBannerconsistent may improve UX consistency.🔤 Example adjustment
- "promoBanner": "Promó banner", + "promoBanner": "Promóciós szalaghirdetés",packages/visual-editor/scripts/generateTranslations.mjs (2)
93-115: Add request timeout to prevent hanging on stalled API calls.The
fetchcall lacks a timeout and can hang indefinitely if the Google Translate API becomes unresponsive, freezing the CLI. Node 18+ (which this package supports) has globalfetchavailable, so no polyfill is needed—only a timeout.⏱️ Add a request timeout
async function translateText(text, targetLang) { const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${defaultLng}&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}`; - const res = await fetch(url); + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), 15000); + let res; + try { + res = await fetch(url, { signal: controller.signal }); + } finally { + clearTimeout(timeout); + }
198-221: Batch requests to avoid triggering the unofficial endpoint's rate-limiting.The
translate.googleapis.com/translate_a/singleendpoint (gtx client) is unofficial and uses dynamic rate limiting—it can return 429 errors or temporarily block your IP if too many requests arrive concurrently. Batching helps prevent hitting these thresholds.🔧 Batch requests with a small concurrency window
- await Promise.allSettled( - keysToTranslate.map(async (key) => { + const BATCH_SIZE = 5; + for (let i = 0; i < keysToTranslate.length; i += BATCH_SIZE) { + const batch = keysToTranslate.slice(i, i + BATCH_SIZE); + await Promise.allSettled( + batch.map(async (key) => { let english = defaultJson[key]; const context = extractContextFromKey(key, defaultKeySet); @@ - }) - ); + }) + ); + }packages/visual-editor/i18next-cli.platform.config.ts (1)
47-47: Platform config includes additional translation functionsptandmsg.The platform config extracts from functions
["t", "*.t", "i18next.t", "pt", "msg"]while the components config only uses["t", "*.t", "i18next.t"]. Ensure this difference is intentional and thatptandmsgare platform-specific translation helpers.
packages/visual-editor/locales/components/ja/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/ro/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/scripts/propagatePlatformToComponents.mjs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@packages/visual-editor/scripts/generateTranslations.mjs`:
- Around line 154-160: The loadJsonSafe function currently swallows all
read/parse errors by returning {}, which hides corrupted JSON; update
loadJsonSafe to catch the error into a variable, treat only ENOENT as a benign
case (return {}), but rethrow any other errors (including JSON.parse failures)
so callers can handle or fail fast; locate the async function loadJsonSafe and
change its try/catch to inspect err.code === 'ENOENT' before returning {} and
otherwise throw err.
- Around line 101-103: The removeEmbeddedContext function is too aggressive:
replace the broad regex /\[+.*?\]+/g with a marker-specific pattern so only the
translation context marker is stripped; update removeEmbeddedContext to use a
dedicated regex constant (e.g. match only "[[context...]]" or "[context:...]"
depending on project convention) such as /\[\[context:.*?\]\]/g or
/\[context:.*?\]/g and trim the result, and ensure the function references that
regex (removeEmbeddedContext) so legitimate bracketed text like "[beta]" is
preserved.
- Around line 212-280: In translateFile, currently failures only increment
failCount and still call saveJson causing partial writes; after the
Promise.allSettled completes check failCount and if > 0 prevent writing (or
abort) by skipping saveJson and logging/throwing an error so no partial
translations are persisted. Concretely: after the await Promise.allSettled(...)
block inspect failCount and if it's non‑zero and not isDryRun, log a clear error
including type/lng and either throw or continue to the next language instead of
calling saveJson; ensure the finalConsole log reflects that the file was not
saved when failures occurred.
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/components/fr/visual-editor.json`:
- Line 9: Replace the incorrect French translation for the "breadcrumb" key in
the locales JSON: update the value of the "breadcrumb" property (in
packages/visual-editor/locales/components/fr/visual-editor.json) from
"Chapelure" to the standard UI term "Fil d'Ariane" so the breadcrumb navigation
label uses the correct French UX phrasing.
In `@packages/visual-editor/locales/components/ja/visual-editor.json`:
- Line 9: The "breadcrumb" translation value currently reads "パン塊" (wrong
meaning); update the JSON entry for the "breadcrumb" key in
packages/visual-editor/locales/components/ja/visual-editor.json to use the
correct Japanese UI term "パンくずリスト" (or alternatively "Breadcrumb" if you prefer
to match the Romanian style) so the label accurately represents breadcrumb
navigation.
In `@packages/visual-editor/locales/platform/ja/visual-editor.json`:
- Around line 479-484: Unify the Japanese plural forms so _one and _other are
identical: update "locationWithCount_other" to match "locationWithCount_one" by
using the more natural counter phrase "{{count}} 件の場所"; locate the two keys
"locationWithCount_one" and "locationWithCount_other" in the visual-editor.json
and replace the _other value accordingly so both read "{{count}} 件の場所".
In `@packages/visual-editor/locales/platform/ro/visual-editor.json`:
- Line 451: Replace the incorrect Romanian value for the "Heading" key
(currently "Îndreptându -se") with the correct UI term "Titlu" (or "Rubrică" to
match existing "headingLevel": "Nivel de rubrică"); also remove the spurious
space before any hyphen if present (fix the hyphenation artifact). Update the
"Heading" entry so it reads simply "Titlu" to align with "headingLevel" and
other UI label translations.
- Around line 131-132: The cta/CTA and link/Link keys are ambiguous in Romanian
and mirror each other; either give them semantically distinct translations to
match how they’re used (e.g., distinguish the UI label used by CtaWrapper.tsx's
pt("cta","CTA") from the group label used by CTAGroup.tsx's pt("CTA","CTA")), or
consolidate usage by updating the source to a single key and removing the
duplicate in the locale. Locate the keys "cta"/"CTA" and "link"/"Link" in
packages/visual-editor/locales/platform/ro/visual-editor.json and: 1) if keeping
both keys, replace the duplicate values with different, context-appropriate
Romanian strings that reflect the different UI contexts referenced by
CtaWrapper.tsx and CTAGroup.tsx; or 2) if consolidating, change the source
references (pt calls in CtaWrapper.tsx and CTAGroup.tsx) to use one canonical
key and remove the redundant locale entry.
In `@packages/visual-editor/scripts/checkInterpolationVariables.mjs`:
- Around line 306-335: The code currently calls autoFixSingleVariableMismatch
and, if it returns null for a single-variable mismatch, falls through without
reporting; update the logic around the autoFixSingleVariableMismatch call (the
block using CHECK_ONLY, autoFixSingleVariableMismatch, localeFlat, fixedEntries,
and issues) so that when details.mismatchCount > 0 and either CHECK_ONLY is true
or autoFixSingleVariableMismatch returned null (i.e., no safe fix), you push an
issue entry into the issues array with the same fields currently used (instance,
locale, file, line via findLineNumberForKey, key, expected, actual,
mismatchCount); alternatively change the later condition to check
details.mismatchCount > 0 instead of > 1 to ensure single-variable mismatches
that couldn't be fixed are reported.
🧹 Nitpick comments (8)
packages/visual-editor/locales/platform/fr/visual-editor.json (1)
68-68: Inconsistent key casing: PascalCase keys mixed with camelCase siblings.
DirectoryGrid(line 68),Video(line 124),HoursStatus(line 324), andHoursTable(line 325) use PascalCase while all surrounding keys in the same objects use camelCase (e.g.,directory,videoSection,hoursStatus). If these are extracted directly from React component names, consider normalizing them to camelCase in the i18next-cli config (e.g., via a key transformation) to keep the locale files consistent.Example normalization
- "DirectoryGrid": "Grille de répertoire", + "directoryGrid": "Grille de répertoire", ... - "Video": "Vidéo", + "video": "Vidéo", ... - "HoursStatus": "Statut des heures", - "HoursTable": "Tableau des heures", + "hoursStatus": "Statut des heures", + "hoursTable": "Tableau des heures",(Corresponding source code
t()calls would need to be updated to match.)Also applies to: 124-124, 324-325
packages/visual-editor/locales/platform/pt/visual-editor.json (1)
68-68: PascalCase keys break the prevailing camelCase convention.
DirectoryGrid(line 68),Video(line 124),HoursStatus(line 324),HoursTable(line 325), andHeading(line 451) all use PascalCase while the rest of the file is consistently camelCase. This is likely auto-extracted from React component names by i18next-cli. If so, this is expected, but worth confirming the extraction config is intentional and consistent across all locales.Also applies to: 124-124, 324-325, 451-451
packages/visual-editor/locales/platform/et/visual-editor.json (1)
68-68: PascalCase keys mixed with camelCase siblings.
DirectoryGrid(Line 68) andVideo(Line 124) withincomponents, andHoursStatus/HoursTable(Lines 324–325) withinoptions, break the camelCase convention used by all their sibling keys. This is likely an artifact of how the new i18next-cli extraction maps source-code identifiers to translation keys. Not a functional issue, but worth noting for consistency.Also applies to: 124-124, 324-325
packages/visual-editor/locales/platform/ro/visual-editor.json (1)
68-68: PascalCase keys (DirectoryGrid,Video,CTAVariant,HoursStatus,HoursTable) break the camelCase convention used by the rest of this file.The vast majority of keys in this file follow camelCase (e.g.,
directoryRootLinkLabel,hoursStatus,hoursTable,ctaVariant). These PascalCase additions appear to be auto-extracted component/type names. Notably, some of these duplicate existing camelCase keys in other sections (e.g.,components.hoursStatusat line 95 vsoptions.HoursStatusat line 324).If these keys are generated by the new i18next-cli extraction, it may be worth configuring the key naming to enforce consistent casing.
Also applies to: 124-124, 191-191, 324-325
packages/visual-editor/scripts/propagatePlatformToComponents.mjs (1)
37-49: Consider extracting shared utilities (flatten,unflatten,sortObject,loadJsonSafe) into a common module.These functions are duplicated nearly verbatim across
propagatePlatformToComponents.mjs,checkInterpolationVariables.mjs, andgenerateTranslations.mjs. A sharedscripts/utils.mjswould reduce maintenance surface and ensure bug fixes propagate consistently (e.g., theloadJsonSafeerror-handling fix in this file isn't applied in the other two scripts).Also applies to: 54-70, 75-86
packages/visual-editor/scripts/checkInterpolationVariables.mjs (1)
289-292: Double file read:localePathis read twice — once raw and once parsed.Line 291 reads the raw file content for line-number lookup, then line 292 reads and parses the same file again via
loadJsonSafe. Consider reading once and reusing.♻️ Proposed optimization
- const localeRaw = await fs.readFile(localePath, "utf-8").catch(() => ""); - const localeFlat = flatten(await loadJsonSafe(localePath)); + let localeRaw = ""; + let localeFlat = {}; + try { + localeRaw = await fs.readFile(localePath, "utf-8"); + localeFlat = flatten(JSON.parse(localeRaw)); + } catch (error) { + if (error?.code !== "ENOENT") throw error; + }packages/visual-editor/scripts/generateTranslations.mjs (2)
155-178: Relies on an unofficial, undocumented Google Translate endpoint.
translate.googleapis.com/translate_a/single?client=gtxis not a public API — it's subject to rate limiting, CAPTCHAs, and can break without notice. For a CI/development tool this may be acceptable, but be aware of the fragility.Additionally,
Promise.allSettledon line 275 fires all key translations concurrently with no concurrency limit or rate throttling, which increases the chance of hitting rate limits for locales with many missing keys.♻️ Add basic concurrency limiting
Consider batching translations (e.g., 5 at a time) to avoid hammering the endpoint:
// Simple serial or batched approach for (const key of keysToTranslate) { // translate one at a time, or use a small batch with Promise.all }
203-215:flattenusesfor...ininstead ofObject.keys(), inconsistent with other scripts.
for (const key in obj)iterates inherited enumerable properties, unlikeObject.keys(obj)used in the other two scripts'flattenimplementations. ForJSON.parseoutput this is benign, but it's an inconsistency that could surprise if the input shape ever changes.♻️ Align with other scripts
- for (const key in obj) { + for (const key of Object.keys(obj)) {
packages/visual-editor/locales/components/fr/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/ja/visual-editor.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 20
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/visual-editor/locales/platform/sv/visual-editor.json (1)
28-28:⚠️ Potential issue | 🟡 MinorFix invalid Swedish translation for breadcrumb navigation key.
"Brödsmum" is not valid Swedish. The correct translation is "Brödsmula" (singular form, matching the key name). This affects user-facing breadcrumb navigation text.
Proposed fix
- "breadcrumb": "Brödsmula", + "breadcrumb": "Brödsmula",packages/visual-editor/scripts/generateTranslations.ts (1)
180-205:⚠️ Potential issue | 🟡 MinorUnofficial Google Translate endpoint with no timeout or rate limiting.
- The
client=gtxendpoint is an undocumented, unofficial Google Translate API. It can be rate-limited or blocked without notice.fetchhas noAbortSignaltimeout — a hung request will stall the pipeline indefinitely.Consider adding a timeout:
Proposed timeout addition
const translateText = async ( text: string, targetLang: string ): Promise<string> => { const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${DEFAULT_LANGUAGE}&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}`; - const response = await fetch(url); + const response = await fetch(url, { + signal: AbortSignal.timeout(10_000), + });
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/components/ja/visual-editor.json`:
- Around line 44-47: Unify the Japanese singular/plural variants so they are
identical for each key: make locationsNear_one and locationsNear_other the same
string, and make locationsWithinDistanceOf_one and
locationsWithinDistanceOf_other the same string; choose a single
particle/phrase, consistent spacing around interpolation tokens (e.g.,
"「{{name}}」付近の {{count}} か所の場所" or preferred equivalent), and use the same
counter word (件 or か所) in both forms so translators and runtime output do not
diverge when count changes.
In `@packages/visual-editor/locales/platform/cs/visual-editor.json`:
- Around line 323-324: The JSON contains duplicated keys with inconsistent
casing: "hoursTable" (components) vs "HoursTable" (fields.options) and
"hoursStatus" vs "HoursStatus"; decide whether both variants are required or
consolidate them—either make the two "hoursTable"/"HoursTable" values identical
(e.g., both "TABULKA HODINY" or both "Tabulka hodin") and do the same for
"hoursStatus"/"HoursStatus", or remove the redundant keys so only the canonical
key (prefer the existing "hoursTable" and "hoursStatus" in components) remains;
update the translations accordingly in visual-editor.json to ensure consistent
casing/values for the keys HoursTable/hoursTable and HoursStatus/hoursStatus.
- Around line 189-190: The JSON contains duplicate translation keys "ctaVariant"
and "CTAVariant" with identical values; remove the redundant key or consolidate
them depending on runtime usage: search the codebase for references to
CTAVariant and ctaVariant (case-sensitive) and if only one form is used keep
that single key (prefer the existing "ctaVariant"), otherwise keep both but
ensure translations stay synchronized and add a comment explaining why both
forms are required; update the file to remove the duplicate entry (or add the
explanatory comment) and run the provided ripgrep checks to verify no callers
break.
In `@packages/visual-editor/locales/platform/da/visual-editor.json`:
- Line 239: The Danish locale entry for the key "linkLabel" currently contains
English text ("Link Label"); update the value for "linkLabel" in the
visual-editor.json Danish file to a proper Danish translation (e.g.,
"Link-etiket" or another agreed translation) or explicitly mark it as
untranslated/TO_TRANSLATE if you want to flag it for later review; reference the
nearby key "linkTarget" to match localization style and ensure the JSON string
remains valid.
In `@packages/visual-editor/locales/platform/fi/visual-editor.json`:
- Around line 481-482: Update the Finnish pluralization strings for the location
count: change the translation value for "locationWithCount_other" from the
nominative plural to the partitive singular used after numerals, i.e., replace
the current "{{count}} sijainnit" with "{{count}} sijaintia"; ensure the keys
"locationWithCount_one" and "locationWithCount_other" remain unchanged and
consistent with nearby entries like "{{count}} sijaintia lähellä kohdetta
{{name}}".
In `@packages/visual-editor/locales/platform/fr/visual-editor.json`:
- Around line 239-244: The translation for the key "linkType" is inconsistent
("Type de liaison") with adjacent keys like "linkLabel" and "linkTarget" which
use "lien"; update the value for linkType to "Type de lien" so all three keys
(linkType, linkLabel, linkTarget) use the same terminology and ensure
consistency across the locale file.
- Line 402: The translation for the key "showCTA" is inconsistent — replace its
value "Afficher l'incitation à l'action" with the acronym form used elsewhere;
update the "showCTA" entry to use "Afficher le CTA" so it matches keys like
"cta" and "showPrimaryCTA".
In `@packages/visual-editor/locales/platform/hr/visual-editor.json`:
- Line 243: The entry for the key "linkTarget" is still in English; replace its
value with the Croatian translation to match the surrounding keys (e.g., change
"Link Target" to "Odredište veze" for the "linkTarget" key) so the locale file
remains fully translated and consistent with "linkLabel" and "linkType".
In `@packages/visual-editor/locales/platform/hu/visual-editor.json`:
- Around line 189-190: The locale file contains near-duplicate keys ctaVariant
and CTAVariant with inconsistent values (one has an extra space before the
hyphen); update them so they use the same normalized translation string (e.g.,
"CTA-változat") and consistent spacing, and if both keys are required by the
code ensure both entries have identical values, otherwise remove or consolidate
the duplicate key to the canonical identifier (ctaVariant or CTAVariant) used by
the source code.
- Line 243: Replace the English value for the JSON key "linkTarget" with the
correct Hungarian translation; locate the "linkTarget" entry in
packages/visual-editor/locales/platform/hu/visual-editor.json and change "Link
Target" to a Hungarian string such as "Hivatkozás célja" (or another approved
Hungarian translation) ensuring the file remains valid JSON and preserves
surrounding commas/formatting.
In `@packages/visual-editor/locales/platform/it/visual-editor.json`:
- Around line 481-482: The translation keys locationWithCount_one and
locationWithCount_other have inconsistent capitalization ("{{count}} posizione"
vs "{{count}} Località"); update locationWithCount_other to match the singular
style by changing "{{count}} Località" to "{{count}} località" so both forms use
the same lowercase capitalization.
In `@packages/visual-editor/locales/platform/nb/visual-editor.json`:
- Line 244: The JSON key "linkType" currently has an English value ("Link
Type"); replace that value with the correct Norwegian translation (e.g.,
"Koblingstype" or "Linktype") so the locale entry for "linkType" is in
Norwegian; update the value for the "linkType" key in the visual-editor.nb
locale JSON to the chosen Norwegian string.
In `@packages/visual-editor/locales/platform/nl/visual-editor.json`:
- Line 611: The Dutch translation for the key theme.fontWeight.fontWeight is
incorrect—"Lettertype" means "Font" not "Font Weight"; update the value for the
"fontWeight" key (the one nested under theme.fontWeight / the JSON entry
currently "Lettertype") to a correct Dutch term such as "Lettergewicht" or
"Tekstdikte" so it correctly reflects "Font Weight".
In `@packages/visual-editor/locales/platform/pl/visual-editor.json`:
- Around line 481-482: The pluralization for the key "locationWithCount" only
defines `_one` and `_other`, which is incorrect for Polish; add `_few` and
`_many` variants so i18next/CLDR plural rules can select correct forms (e.g.,
`_few` => "{{count}} lokalizacje", `_many` => "{{count}} lokalizacji") alongside
the existing `_one` and `_other`; apply the same pattern to any other Polish
plural keys (e.g., "kilometer", "mile", "totalReviews", "locationsNear") to
ensure counts map to one/few/many/other correctly.
In `@packages/visual-editor/locales/platform/sk/visual-editor.json`:
- Line 450: The JSON value for the "heading" key is mistranslated as
"Smerovanie" (routing); update the value to the correct Slovak term "Nadpis" for
the "heading" key in this file and also search for the "sectionHeading" key
(mentioned at line 391) and replace its value "Smerovanie sekcie" with "Nadpis
sekcie" if appropriate to keep consistency; ensure you only change the string
values for the keys "heading" and "sectionHeading" (no other keys or
formatting).
- Around line 481-482: Change the inconsistent Slovak wording so both keys use
the same root "lokácia"/"lokality": update locationWithCount_one to use
"{{count}} lokácia" (singular) and keep/update locationWithCount_other to
"{{count}} lokality" (plural) so the singular and plural forms are consistent
and use the same concept.
In `@packages/visual-editor/locales/platform/sv/visual-editor.json`:
- Line 68: Remove the unused PascalCase locale keys HoursStatus and HoursTable
from the visual-editor JSON to avoid duplicate entries—keep the camelCase keys
used by the code (components.hoursStatus and components.hoursTable) and retain
intentional PascalCase keys like DirectoryGrid and Video; locate the two
PascalCase entries named "HoursStatus" and "HoursTable" in the file and delete
those lines so only the camelCase variants remain.
In `@packages/visual-editor/locales/platform/zh-TW/visual-editor.json`:
- Around line 481-482: The two plural keys locationWithCount_one and
locationWithCount_other are inconsistent (one uses " {{count}} 個位置" with a space
and classifier, the other uses "{{count}}位置" without them); update the
translations so both plural forms match (e.g., set locationWithCount_other to
the same string as locationWithCount_one or vice versa) to ensure consistent
pluralization and display across zh-TW; edit the entries for
locationWithCount_one and locationWithCount_other in the visual-editor.json
accordingly.
In `@packages/visual-editor/locales/platform/zh/visual-editor.json`:
- Around line 481-482: The two translation keys locationWithCount_one and
locationWithCount_other are inconsistent; make both identical by using the same
Chinese phrase with the classifier — update locationWithCount_other to match
locationWithCount_one (i.e., both should be "{{count}} 个位置") so both plural
forms are the same.
- Around line 189-190: Remove the duplicate top-level locale keys "ctaVariant"
and "CTAVariant": either delete both if unused, or consolidate by keeping a
single canonical key (preferably "fields.ctaVariant") and move/rename the
translated value there; then run a quick search for usages of "ctaVariant" or
"CTAVariant" to update any callers to the canonical key and ensure msg()/i18n
lookups still resolve correctly.
🧹 Nitpick comments (15)
packages/visual-editor/locales/platform/fi/visual-editor.json (1)
68-68: Inconsistent key casing: PascalCase keys among camelCase siblings.
"DirectoryGrid"and"Video"use PascalCase while all surrounding keys incomponentsuse camelCase (e.g.,directoryCard,videoSection). The same pattern appears forCTAVariant(Line 190),HoursStatus(Line 323), andHoursTable(Line 324). If these map directly to component/option names in code, this may be intentional — but it's worth confirming the convention so lookups don't silently miss due to casing mismatches.,
#!/bin/bash # Check if PascalCase keys like DirectoryGrid, Video, HoursStatus, HoursTable, CTAVariant # are used consistently across all locale files in this directory tree echo "=== PascalCase keys in platform locale files ===" rg -n '"(DirectoryGrid|Video|CTAVariant|HoursStatus|HoursTable)"' --type json -g '*/locales/platform/*' | head -40 echo "" echo "=== Check component code referencing these keys ===" rg -n 'DirectoryGrid|HoursStatus|HoursTable' --type ts --type tsx -g '!**/locales/**' -g '!node_modules/**' | head -30Also applies to: 124-124
packages/visual-editor/locales/platform/it/visual-editor.json (1)
68-68: PascalCase keys mixed with camelCase siblings.
DirectoryGrid(Line 68),Video(Line 124),HoursStatus(Line 323), andHoursTable(Line 324) use PascalCase, while surrounding keys are camelCase (directory,videoSection,hour12,hour24). This is likely driven by the new i18next-cli extracting component/enum names verbatim, but it creates an inconsistent convention within the same JSON object.If PascalCase is the intended convention going forward for component-derived keys, consider documenting it. Otherwise, normalizing to camelCase would keep the file consistent.
Also applies to: 124-124, 323-324
packages/visual-editor/locales/platform/lt/visual-editor.json (1)
68-68: Inconsistent key casing: PascalCase keys among camelCase siblings.
"DirectoryGrid"(Line 68) and"Video"(Line 124) use PascalCase, while all surrounding sibling keys incomponentsuse camelCase (e.g.,directory,videoSection,aboutSection). The same pattern appears infields.optionswith"HoursStatus"/"HoursTable"(Lines 323–324). This likely reflects the i18next-cli extracting raw component/type names. Consider normalizing to camelCase for consistency, or documenting the convention if PascalCase is intentional for component-name keys.Also applies to: 124-124
packages/visual-editor/locales/platform/da/visual-editor.json (1)
68-68: Normalize PascalCase keys to camelCase for consistency.Keys
DirectoryGrid(line 68),Video(line 124),HoursStatus(line 323), andHoursTable(line 324) use PascalCase while the file overwhelmingly uses camelCase (e.g.,directory,videoSection,hoursStatus,hoursTable). Note that camelCase equivalents already exist:hoursStatus(line 95) andhoursTable(line 96), creating redundancy. Either standardize all component/field names to camelCase to match the file convention, or document the rationale for the mixed convention.packages/visual-editor/locales/platform/pl/visual-editor.json (1)
28-28: Pre-existing typo: "Breatcrumb" → "Breadcrumb".
"Breatcrumb"(Line 28) and"Breatcrumbs"(Line 60) appear to be typos — the English loanword should be "Breadcrumb"/"Breadcrumbs". Not introduced in this PR, but worth fixing while the locale files are being reworked.packages/visual-editor/locales/platform/de/visual-editor.json (1)
68-68: PascalCase keys in locale file correspond to source code identifiers and appear intentional, but confirm this pattern is expected for future consistency.
DirectoryGrid(line 68),Video(line 124),HoursStatusandHoursTable(lines 323-324), andCTAVariant(line 190) use PascalCase while all sibling keys in their respective objects use camelCase. These keys correspond to source code component/type names (DirectoryGrid type in defaultLayoutData.ts, CTAVariant type in atoms/cta.tsx, HoursStatusAtom/HoursTableAtom in LocatorResultCard.tsx), suggesting the naming is intentional to match source identifiers. Verify that this convention is documented or enforced for future locale additions to maintain consistency in the file.Also,
ctaVariant(line 189) andCTAVariant(line 190) coexist with slightly different translation values ("CTA -Variante" vs "CTA-Variante") — they appear to serve different purposes (field label vs type name), which is fine, but be aware both exist in the file.packages/visual-editor/locales/platform/et/visual-editor.json (1)
68-68: PascalCase keys introduced within otherwise camelCase objects.New keys like
DirectoryGrid,Video,HoursStatus, andHoursTableuse PascalCase while siblings use camelCase (e.g.,directory,videoSection,hoursTable). This is likely intentional (matching component/enum names in code), but the mix could cause confusion—especially"hoursTable"(line 96) vs"HoursTable"(line 324) which live in different nested objects but look like near-duplicates.Also applies to: 124-124, 323-324
packages/visual-editor/locales/platform/hr/visual-editor.json (1)
68-68: Inconsistent key casing: PascalCase keys (DirectoryGrid,Video) among camelCase siblings.These likely mirror React component names, but they break the naming convention used by every other key in the
componentsobject. The same pattern appears infields.optionswithHoursStatus/HoursTable(Lines 323–324). If this is intentional for the new i18next-cli extraction, no action needed—just flagging for awareness.Also applies to: 124-124
packages/visual-editor/locales/platform/cs/visual-editor.json (1)
68-68: PascalCase keysDirectoryGridandVideobreak the camelCase convention used by all surrounding keys.Every other key in the
componentsobject uses camelCase (e.g.,aboutSection,bannerSection,hoursStatus). These two PascalCase keys stand out and may confuse future contributors or cause lookup misses if code elsewhere expects camelCase.If i18next-cli is extracting these from PascalCase component names, consider adding a key transformation in the extraction config to normalize to camelCase.
Also applies to: 124-124
packages/visual-editor/locales/platform/fr/visual-editor.json (1)
68-68: PascalCase keysDirectoryGridandVideobreak thecomponentsnaming convention.Every other key in the
componentsobject uses camelCase (e.g.,directory,videoSection,aboutSection). These two PascalCase keys appear to come from the i18next-cli extracting component names verbatim. If this is intentional, consider documenting the convention; otherwise, align them with the existing camelCase pattern.Also applies to: 124-124
packages/visual-editor/scripts/checkInterpolationVariables.mjs (1)
22-101: Utility functions duplicated fromjsonUtils.ts.
loadJsonSafe,saveJson,flatten,unflatten,sortObject, andgetLocalesmirror their TypeScript counterparts insrc/utils/i18n/jsonUtils.ts. This is understandable since the.mjsscript runs withnodedirectly and can't import.tsfiles without a build step, but it creates a maintenance surface — changes to one copy must be mirrored in the other.Consider running this script via
tsx(likepropagatePlatformToComponents.ts) to share the implementations, or add a comment noting the dependency.packages/visual-editor/scripts/generateTranslations.ts (2)
254-282: Unbounded parallelism — all keys translated concurrently per locale.
Promise.allSettledfires everytranslateTextcall in parallel with no concurrency cap. For locales with many missing keys, this can trigger Google's rate limiter and cause most requests to fail.Consider batching with a concurrency limit (e.g., via a simple semaphore or
p-limit).Example with p-limit
+import pLimit from "p-limit"; + +const limit = pLimit(5); + await Promise.allSettled( keysToTranslate.map(async (key) => { + return limit(async () => { const english = defaultJson[key]; // ... translation logic ... + }); }) );
45-56: Misleading error when--typeflag is present but value is missing.If
--typeis the last argv element,process.argv[index + 1]isundefined, producing the errorUnsupported --type "undefined". A clearer check would distinguish "missing value" from "wrong value."Suggested improvement
const getTypeArg = (): TranslationType => { const index = process.argv.findIndex((arg) => arg === "--type"); - const raw = index >= 0 ? process.argv[index + 1] : "platform"; + if (index < 0) return "platform"; + + const raw = process.argv[index + 1]; + if (!raw || raw.startsWith("-")) { + throw new Error(`--type requires a value. This script only supports "--type platform".`); + } if (raw !== "platform") {packages/visual-editor/src/utils/i18n/jsonUtils.ts (1)
46-61:flattencoerces non-object leaf values toString— arrays become comma-joined strings.
String([1, 2])produces"1,2", which is lossy. This is fine for i18n string values but worth noting if the JSON ever contains non-string leaves beyondnull/undefined.packages/visual-editor/locales/platform/en/visual-editor.json (1)
68-68: PascalCase keys (DirectoryGrid,Video) break the camelCase convention used by sibling entries.Under
components, all other keys use camelCase (e.g.,aboutSection,videoSection).DirectoryGridandVideouse PascalCase, presumably matching React component names. This is fine if intentional but consider aligning the convention for consistency across the i18n surface.Also applies to: 124-124
packages/visual-editor/locales/components/ja/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/platform/zh-TW/visual-editor.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 6
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 (3)
packages/visual-editor/locales/platform/cs/visual-editor.json (1)
28-28:⚠️ Potential issue | 🟡 MinorSame mistranslation:
"breadcrumb": "Strouha"— see components file comment.Same issue as in the components locale file. "Strouha" is not the correct Czech for navigational "breadcrumb." Line 60 (
components.breadcrumbs) correctly uses "Strouhanka."Proposed fix
- "breadcrumb": "Strouha", + "breadcrumb": "Drobečková navigace",packages/visual-editor/locales/platform/lv/visual-editor.json (1)
28-28:⚠️ Potential issue | 🟡 Minor
"breadcrumb"translated as"Rīvmaize"(food breadcrumbs) — likely a machine-translation error."Rīvmaize" is the Latvian word for culinary breadcrumbs. For the UI navigation concept, the English loanword "Breadcrumb" (or a descriptive term like "Navigācijas ceļš") is more appropriate. The same issue appears at line 60 (
components.breadcrumbs).Proposed fix
- "breadcrumb": "Rīvmaize", + "breadcrumb": "Navigācijas ceļš",And at line 60:
- "breadcrumbs": "Navigācijas ceļš", + "breadcrumbs": "Navigācijas ceļi",packages/visual-editor/locales/platform/hr/visual-editor.json (1)
461-491:⚠️ Potential issue | 🟡 MinorIncorrect Croatian
_fewplural forms for unit nouns.Croatian uses distinct forms for counts 2–4 (
_few). Currently both_fewand_otherare identical, which produces incorrect grammar:
Key Current _fewCorrect _fewkilometer_few(Line 462)"kilometara" "kilometra" mile_few(Line 490)"milja" "milje" Croatian counting: 2 kilometra (gen. sg.), 5 kilometara (gen. pl.); 2 milje (nom. pl.), 5 milja (gen. pl.).
Proposed fix
"kilometer_one": "kilometar", - "kilometer_few": "kilometara", + "kilometer_few": "kilometra", "kilometer_other": "kilometara","mile_one": "milja", - "mile_few": "milja", + "mile_few": "milje", "mile_other": "milja",
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/components/fi/visual-editor.json`:
- Line 37: Update the Finnish translation for the JSON key "informationSection"
in visual-editor.json: replace the incorrect value "Tiedonsiirto" with the
correct term "Tieto-osio" so the label reads appropriately for Finnish users;
locate the "informationSection" key in the file and change its string value
accordingly.
In `@packages/visual-editor/locales/components/fr/visual-editor.json`:
- Around line 54-56: The translation key "mile_many" in the locale file is
incorrect ("kilomètres"); update the value for "mile_many" to the correct French
word "miles" so it matches "mile_one" and "mile_other" and avoids showing
kilometers where miles are intended; locate the key "mile_many" in the
visual-editor.json and replace its string accordingly.
In `@packages/visual-editor/locales/components/hr/visual-editor.json`:
- Line 38: Update the Croatian `_few` plural variants to use the nominative
plural (counts 2–4) instead of the genitive plural; specifically change the keys
locationWithCount_few, locationsNear_few, locationsWithinDistanceOf_few,
mile_few, totalReviews_few and the kilometer_few entry to their correct
nominative-plural forms (e.g., "{{count}} lokacije" for locationWithCount_few,
"{{count}} lokacije u blizini…" for locationsNear_few, "{{count}} lokacije
unutar…" for locationsWithinDistanceOf_few, "milje" for mile_few, "{{count}}
recenzije" for totalReviews_few, and use "kilometra" for kilometer_few where
appropriate); verify other mentioned keys (lines 43,46,49,54,96) and replace
their `_few` values similarly with the nominative plural endings (-ije/-je for
feminine -ija/-ja nouns and -a for neuter/masculine as appropriate).
In `@packages/visual-editor/locales/components/it/visual-editor.json`:
- Line 9: The Italian translation for the key "breadcrumb" is incorrect ("Pane"
means bread); update the value for the "breadcrumb" key in the visual-editor
locale to a proper navigation term such as "Breadcrumb", "Percorso di
navigazione", or simply "Percorso" so it reflects the UI concept of navigation
breadcrumbs rather than the food item.
In `@packages/visual-editor/locales/platform/fr/visual-editor.json`:
- Around line 490-491: The "mile_many" translation is incorrect ("kilomètres");
update the JSON entry for the key "mile_many" to use the correct French word
"miles" to match the other plural forms (see "mile_one" and "mile_other"); edit
the value for "mile_many" in the visual-editor localization JSON so it equals
"miles" and run any i18n/locale validations or tests to ensure no formatting
errors.
In `@packages/visual-editor/scripts/generateTranslations.ts`:
- Around line 334-361: The current Promise.allSettled over translationTargets
fires all translateText calls in parallel causing rate-limits; change this to a
bounded-concurrency loop or use a limiter like p-limit to run at most N (e.g.,
5) translations concurrently. Keep the per-item logic
(maskInterpolationVariables, embedContextInText, removeEmbeddedContext,
unmaskInterpolationVariables), preserve updating cache.set(key.trim(),
translated), successCount/failCount increments, and the console logs/error
handling, but schedule translateText(...) through the limiter (or process
translationTargets in async batches) so translateText, cache updates and
counters occur inside the limited task function. Ensure Promise.allSettled
awaits the queued limited tasks so the script still waits for all translations
to finish.
🟡 Minor comments (47)
packages/visual-editor/locales/components/pl/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorTypo: "Breatcrumb" → "Breadcrumb".
Missing the letter 'd'. This will be user-visible in the UI.
✏️ Proposed fix
- "breadcrumb": "Breatcrumb", + "breadcrumb": "Breadcrumb",packages/visual-editor/locales/components/es/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 Minor"Migaja de pan" is an unusual choice for breadcrumb navigation.
The literal translation "Migaja de pan" (a single bread crumb/morsel) is not the standard UI term in Spanish. The common terms are "Migas de pan" (plural) or, more idiomatically for web navigation, "Ruta de navegación." Consider aligning with typical Spanish UI conventions.
packages/visual-editor/locales/components/es/visual-editor.json-46-48 (1)
46-48:⚠️ Potential issue | 🟡 MinorInconsistent word order in
locationsNear_manycompared to sibling plural forms.The
_manyvariant places the count after the noun ("Ubicaciones {{count}} cerca de..."), while_oneand_otherplace it before ("{{count}} ubicación/ubicaciones cerca de..."). This will produce visually jarring text if the_manyform is ever resolved.Proposed fix
- "locationsNear_many": "Ubicaciones {{count}} cerca de \"{{name}}\"", + "locationsNear_many": "{{count}} ubicaciones cerca de \"{{name}}\"",packages/visual-editor/locales/components/es/visual-editor.json-96-98 (1)
96-98:⚠️ Potential issue | 🟡 MinorInconsistent term across
totalReviewsplural forms.
totalReviews_manyuses "opiniones" while_oneuses "reseña" and_otheruses "reseñas". These are different words ("opinions" vs. "reviews"). Plural variants of the same key should use the same term to avoid a jarring switch in vocabulary based on count.Proposed fix
- "totalReviews_many": "{{count}} opiniones", + "totalReviews_many": "{{count}} reseñas",packages/visual-editor/locales/components/ro/visual-editor.json-25-25 (1)
25-25:⚠️ Potential issue | 🟡 MinorInconsistent use of definite vs. indefinite article in section labels.
The new section-related keys mix "Secțiune de …" (indefinite) and "Secțiunea …" (definite):
Key Value Article hoursSection"Secțiune de ore" indefinite informationSection"Secțiune de informații" indefinite coreInfoSection"Secțiunea de informații de bază" definite photoGallerySection"Secțiunea Galerie foto" definite servicesSection"Secțiunea Servicii" definite Pick one form consistently. Since these are UI section headings, the definite article ("Secțiunea …") is typically more natural in Romanian.
Proposed fix (align to definite article)
- "hoursSection": "Secțiune de ore", + "hoursSection": "Secțiunea de ore", - "informationSection": "Secțiune de informații", + "informationSection": "Secțiunea de informații",Also applies to: 35-37, 65-68, 79-80
packages/visual-editor/locales/components/ro/visual-editor.json-49-49 (1)
49-49:⚠️ Potential issue | 🟡 MinorWording in
locationsWithinDistanceOf_fewdiverges from sibling plural forms.The
_fewform uses "în {{distance}} {{unit}} din" while_one(line 50) uses "la {{distance}} {{unit}} de" and_other(line 51) uses "pe o rază de {{distance}} {{unit}} de". While some variation across plural forms can be natural, the preposition combination "în…din" vs "la…de" / "pe o rază de…de" feels inconsistent and could confuse users. Consider aligning the phrasing across plural variants.packages/visual-editor/locales/components/ro/visual-editor.json-20-24 (1)
20-24:⚠️ Potential issue | 🟡 MinorUtility image alt text — translation is acceptable.
"Imagine utilitar {{number}}" conveys "Utility image {{number}}". Grammatically, "utilitară" (feminine adjective to agree with "imagine") would be more correct than "utilitar" (masculine/neuter), but this is a minor grammatical nit.
Optional grammar fix
- "defaultAlt": "Imagine utilitar {{number}}" + "defaultAlt": "Imagine utilitară {{number}}"packages/visual-editor/locales/components/lt/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorLikely incorrect machine translation for "breadcrumb".
"Komprumbas" does not appear to be a valid Lithuanian word. The literal translation for "breadcrumb" would be "Duonos trupinys" (or "trupiniai" for plural). For a UI navigation context, it's common to use "Naršymo kelias" (navigation path) or simply leave it as the loanword "Breadcrumb." This looks like a Google Translate artifact from the new automated translation pipeline.
Suggested fix
- "breadcrumb": "Duonos komprumbas", + "breadcrumb": "Naršymo kelias",packages/visual-editor/locales/components/it/visual-editor.json-36-36 (1)
36-36:⚠️ Potential issue | 🟡 MinorIncorrect Italian word order for "hoursSection".
"Ore sezione" reverses the expected Italian noun–modifier order. Other section keys in this file follow the correct pattern — e.g.,
"servicesSection": "Sezione Servizi"(Line 80) and"coreInfoSection": "Sezione Informazioni fondamentali"(Line 25).Proposed fix
- "hoursSection": "Ore sezione", + "hoursSection": "Sezione orari",packages/visual-editor/locales/components/it/visual-editor.json-43-51 (1)
43-51:⚠️ Potential issue | 🟡 MinorInconsistent terminology across plural forms for location-related keys.
The
_manyand_otherplural variants use different Italian words for the same concept:
Key _many_otherlocationWithCount"posizioni" "località" locationsNear"luoghi" "località" locationsWithinDistanceOf"posizioni" "località" In Italian, both
_manyand_otherare plural forms (CLDR rules), so they should use consistent vocabulary. This looks like a machine translation artifact. Pick one term (e.g., "località" or "posizioni") and use it consistently across all plural variants.packages/visual-editor/locales/platform/nb/visual-editor.json-445-446 (1)
445-446:⚠️ Potential issue | 🟡 Minor"Misligholde" is a mistranslation of "default" in a UI context.
"Misligholde" means "to default on a debt/obligation" (i.e., fail to pay). For a UI label meaning "the preset/standard option," the correct Norwegian term is "Standard". This same mistranslation appears elsewhere in the file (lines 140, 273, 563) but those are pre-existing; this changed line perpetuates the error.
Proposed fix
- "fontSizeDefaultLabel": "Misligholde", + "fontSizeDefaultLabel": "Standard",packages/visual-editor/locales/platform/nb/visual-editor.json-238-243 (1)
238-243:⚠️ Potential issue | 🟡 MinorInconsistent translation of "link" prefix across sibling keys.
linkLabel→ "Koblingsetikett" andlinkType→ "Koblingstype" both use the Norwegian root "Kobling", butlinkTargeton Line 242 uses the English loanword "Link" → "Linkmål". For consistency, this should also use "Kobling".Proposed fix
- "linkTarget": "Linkmål", + "linkTarget": "Koblingsmål",packages/visual-editor/locales/components/zh-TW/visual-editor.json-25-25 (1)
25-25:⚠️ Potential issue | 🟡 MinorNew keys use Simplified Chinese–style "信息" instead of Traditional Chinese "資訊".
Lines 25 and 37 use "信息" (common in zh-CN) where zh-TW convention prefers "資訊." While the existing unchanged line 10 (
businessInformation) already uses "信息," new keys added to this file are an opportunity to use the correct regional variant.Proposed fix
- "coreInfoSection": "核心信息部分", + "coreInfoSection": "核心資訊部分",- "informationSection": "信息部分", + "informationSection": "資訊部分",Also applies to: 37-37
packages/visual-editor/locales/components/zh-TW/visual-editor.json-35-36 (1)
35-36:⚠️ Potential issue | 🟡 Minor"hours" is translated as the time unit ("小時") instead of business/operating hours ("營業時間").
In the context of a location page, "hours" refers to business hours (營業時間), not the time unit (小時). The same issue applies to "hoursSection" → should be "營業時間部分" rather than "小時部分". The AI summary mentions Google Translate integration for automated translation, which likely caused this mistranslation.
Proposed fix
- "hours": "小時", - "hoursSection": "小時部分", + "hours": "營業時間", + "hoursSection": "營業時間部分",packages/visual-editor/locales/components/sk/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorLikely mistranslation: "Strúhanka" is the culinary term for breadcrumbs, not the UI navigation concept.
"Strúhanka" refers to food-coating breadcrumbs. For breadcrumb navigation in Slovak, a more appropriate translation would be something like "Navigačná cesta" or simply keeping it as "Breadcrumb," which is commonly used in Slovak tech/UI contexts. This looks like a machine-translation artifact.
packages/visual-editor/locales/components/fr/visual-editor.json-49-51 (1)
49-51:⚠️ Potential issue | 🟡 MinorInconsistent quotation style and phrasing across plural variants.
locationsWithinDistanceOf_manyuses French guillemets« »and the preposition "dans", while_oneuses\"\"with "à" and_otheruses\"\"with "dans un rayon de". Plural variants should only differ in grammatical number, not in punctuation style or phrasing — users will see different formatting depending on the count.Consider aligning all three variants to use the same quote style (preferably
« »for proper French typography) and consistent phrasing.packages/visual-editor/locales/components/zh/visual-editor.json-44-45 (1)
44-45:⚠️ Potential issue | 🟡 MinorInconsistent wording between
locationsNear_oneandlocationsNear_other.
_oneuses "位置" while_otheruses "地点" for "location(s)." These are synonyms, but the inconsistency suggests the translations weren't reviewed for uniformity. Since_oneis never resolved forzh(per CLDR), only the_otherform matters here—but consider aligning them if these files are maintained by hand or used as a reference.packages/visual-editor/locales/platform/zh/visual-editor.json-476-477 (1)
476-477:⚠️ Potential issue | 🟡 MinorInconsistent wording between
locationsNear_oneandlocationsNear_other.
_oneuses "位置" (location) while_otheruses "地点" (place). Since Chinese has no grammatical plural distinction, these two forms will both be displayed and should use identical wording.Proposed fix
"locationsNear_one": ""{{name}}"附近有 {{count}} 个位置", - "locationsNear_other": ""{{name}}"附近有 {{count}} 个地点", + "locationsNear_other": ""{{name}}"附近有 {{count}} 个位置",packages/visual-editor/locales/components/lv/visual-editor.json-80-80 (1)
80-80:⚠️ Potential issue | 🟡 MinorInconsistent "section" translation:
nodaļavssadaļa.
servicesSectionuses"nodaļa"(department), while all other*Sectionkeys in this file use"sadaļa"(section):hoursSection→"Stundu sadaļa",informationSection→"Informācijas sadaļa",photoGallerySection→"Foto galerijas sadaļa". Use"sadaļa"for consistency.Suggested fix
- "servicesSection": "Pakalpojumu nodaļa", + "servicesSection": "Pakalpojumu sadaļa",packages/visual-editor/locales/components/lv/visual-editor.json-35-36 (1)
35-36:⚠️ Potential issue | 🟡 Minor
hourstranslated as "Laiks" (time) — likely should be "Stundas" or "Darba laiks".
"Laiks"means "time" in general, not "hours." This is a business-hours context, and inconsistently,hoursSectionon the next line uses"Stundu sadaļa"(hours section). Consider"Darba laiks"(business hours) or"Stundas"for consistency.Suggested fix
- "hours": "Laiks", + "hours": "Darba laiks",packages/visual-editor/locales/components/lv/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 Minor"breadcrumb" translated as food item rather than navigation concept.
"Rīvmaize"is the literal Latvian word for breadcrumbs (food). In a UI navigation context, this may confuse users. Latvian web conventions typically use"Navigācijas ceļš"(navigation path) or sometimes retain "Breadcrumb" as a loanword. Please verify with a native speaker or Latvian UI localization reference.packages/visual-editor/locales/components/lv/visual-editor.json-67-68 (1)
67-68:⚠️ Potential issue | 🟡 MinorTranslation quality issues: redundancy and untranslated value.
Two problems in these adjacent keys:
- Line 67 —
"Reklāmas reklāmkarogs"is redundant;"reklāmkarogs"already means "advertising banner." Consider just"Reklāmkarogs"or"Akciju reklāmkarogs"(promo banner).- Line 68 —
"Promo Media"is left entirely in English. All other keys in this file are translated to Latvian. This looks like a machine-translation miss.Suggested fix
- "promoBanner": "Reklāmas reklāmkarogs", - "promoMedia": "Promo Media", + "promoBanner": "Akciju reklāmkarogs", + "promoMedia": "Reklāmas mediji",packages/visual-editor/locales/platform/ro/visual-editor.json-68-68 (1)
68-68:⚠️ Potential issue | 🟡 MinorMixed-language translation: "Director Grid".
"Grid" is left in English while "Director" is Romanian. Elsewhere in this file, "grid" is translated — e.g., line 89:
"gridSection": "Secțiune Grila". Consider using"Grilă Director"for consistency.Proposed fix
- "directoryGrid": "Director Grid", + "directoryGrid": "Grilă Director",packages/visual-editor/locales/platform/fi/visual-editor.json-124-124 (1)
124-124:⚠️ Potential issue | 🟡 MinorInconsistent key casing:
"Video"should be"video".All other keys in the
componentsobject use camelCase (e.g.,videoSection,directoryGrid,testimonialCard)."Video"with an uppercaseVbreaks this convention and may cause lookup failures if consuming code expects"video".Proposed fix
- "Video": "Video", + "video": "Video",packages/visual-editor/locales/platform/fi/visual-editor.json-445-446 (1)
445-446:⚠️ Potential issue | 🟡 MinorMistranslation: "Laiminlyönti" means "neglect", not "default".
"Laiminlyönti" is the Finnish word for "neglect/default on an obligation" (legal/financial sense). The correct translation for a UI default value label is "Oletus" — which is already correctly used elsewhere in this file (e.g., Line 140:
"default": "Oletus"). This looks like a Google Translate error confusing the two English meanings of "default".The same mistranslation also exists in unchanged lines (273, 563) — worth fixing those too.
Proposed fix
- "fontSizeDefaultLabel": "Laiminlyönti", + "fontSizeDefaultLabel": "Oletus",packages/visual-editor/locales/components/fi/visual-editor.json-75-75 (1)
75-75:⚠️ Potential issue | 🟡 Minor"Palvelusosasto" means "service department" (organizational), not a UI "services section".
In Finnish, "osasto" refers to a department (e.g., hospital ward, store department), while "osio" is the correct term for a section of a page or UI. Consider "Palvelut-osio".
🌐 Proposed fix
- "servicesSection": "Palvelusosasto", + "servicesSection": "Palvelut-osio",packages/visual-editor/locales/components/fi/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorIncorrect Finnish UI term for "breadcrumb".
"Leivänmuru" is a literal translation meaning a physical bread crumb. The standard Finnish UI term for breadcrumb navigation is "murupolku" (crumb path).
🌐 Proposed fix
- "breadcrumb": "Leivänmuru", + "breadcrumb": "Murupolku",packages/visual-editor/locales/components/fi/visual-editor.json-63-63 (1)
63-63:⚠️ Potential issue | 🟡 Minor"Promootio" translates to "Promotion", missing the "media" aspect of
promoMedia.Consider "Promomedia" to retain both concepts.
🌐 Proposed fix
- "promoMedia": "Promootio", + "promoMedia": "Promomedia",packages/visual-editor/locales/components/fi/visual-editor.json-25-25 (1)
25-25:⚠️ Potential issue | 🟡 MinorSpurious space before hyphen in compound word.
Finnish compound words with a hyphen don't have a space before the hyphen. "Ydintiedot -osio" → "Ydintiedot-osio".
🌐 Proposed fix
- "coreInfoSection": "Ydintiedot -osio", + "coreInfoSection": "Ydintiedot-osio",packages/visual-editor/locales/components/cs/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorMistranslation:
"breadcrumb": "Strouha"is incorrect Czech."Strouha" doesn't mean "breadcrumb" in the navigational sense — it appears to be a truncated/garbled machine translation. The platform file (Line 60 in
components) correctly uses "Strouhanka" for"breadcrumbs". For the singular key, consider using "Drobečková navigace" (the standard Czech UI term) or at minimum "Strouhanka" to stay consistent with the plural form.Proposed fix
- "breadcrumb": "Strouha", + "breadcrumb": "Drobečková navigace",packages/visual-editor/locales/components/hr/visual-editor.json-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorQuestionable Croatian translation for "breadcrumb".
"Krušnica"does not appear to be a standard Croatian term for breadcrumb navigation. In Croatian web UI, the breadcrumb trail is commonly referred to as "navigacijski put" (navigation path), "breadcrumb" (kept as-is), or "putanja" (path). This looks like it may be a machine-translation artifact. Please verify with a native Croatian speaker.packages/visual-editor/locales/components/hr/visual-editor.json-35-37 (1)
35-37:⚠️ Potential issue | 🟡 MinorTranslation quality issues: incorrect case and incomplete translations.
Three concerns here:
"hours": "Sate"— "Sate" is the accusative form. For a standalone UI label, the nominative "Sati" is expected."hoursSection": "Odjeljak"and"informationSection": "Odjeljak"— These translate to just "Section" with no qualifier, unlike other similar keys in this file (e.g.,"servicesSection": "Odjeljak za usluge","photoGallerySection": "Odjeljak fotogalerije"). These should include context, e.g., "Odjeljak radnog vremena" and "Odjeljak informacija".This is consistent with the PR description mentioning Google Translate integration in the new translate script — these appear to be machine-translated without post-editing.
Suggested fix
- "hours": "Sate", - "hoursSection": "Odjeljak", - "informationSection": "Odjeljak", + "hours": "Sati", + "hoursSection": "Odjeljak radnog vremena", + "informationSection": "Odjeljak informacija",packages/visual-editor/locales/platform/da/visual-editor.json-445-446 (1)
445-446:⚠️ Potential issue | 🟡 Minor
"Misligholdelse"is a mistranslation of "default" in UI context."Misligholdelse" means "default" in the legal/financial sense (breach, non-compliance). The correct Danish UI term for a preset/standard value is "Standard". This same mistranslation also appears at lines 140, 273, and 563 — likely a systematic machine-translation error.
Proposed fix (this line + pre-existing occurrences)
- "fontSizeDefaultLabel": "Misligholdelse", + "fontSizeDefaultLabel": "Standard",Also fix pre-existing occurrences outside the changed lines:
Line 140: "default": "Standard" Line 273: "default": "Standard" Line 563: "spacingDefaultLabel": "Standard"packages/visual-editor/locales/platform/es/visual-editor.json-645-646 (1)
645-646:⚠️ Potential issue | 🟡 MinorInconsistent translation: "opiniones" vs "reseñas" for reviews.
Line 645 (
_many) uses "opiniones" (opinions) while line 646 (_other) uses "reseñas" (reviews). Although_manyis never selected for Spanish, these should use the same term for consistency. "Reseñas" is the correct translation for "reviews" in this context.Proposed fix
- "totalReviews_many": "{{count}} opiniones", + "totalReviews_many": "{{count}} reseñas",packages/visual-editor/locales/platform/es/visual-editor.json-124-124 (1)
124-124:⚠️ Potential issue | 🟡 MinorInconsistent key casing:
"Video"should be"video".The key uses PascalCase while all sibling keys in the
componentsobject use camelCase (e.g.,timestamp,videoSection,hoursStatus). Other"video"keys elsewhere in the file (lines 366, 431) also use lowercase. This inconsistency exists in the English source locale as well, so both locales should be corrected to use"video"for consistency.packages/visual-editor/locales/platform/sk/visual-editor.json-478-481 (1)
478-481:⚠️ Potential issue | 🟡 MinorInconsistent terminology in
locationsNearplural forms.The
_oneform uses "umiestnenie" (placement/positioning) while the_few/_many/_otherforms use "miest" (from "miesto" = place/location). These should share the same root word, consistent with howlocationWithCountwas corrected.Proposed fix
- "locationsNear_one": "{{count}} umiestnenie blízko „{{name}}"", + "locationsNear_one": "{{count}} miesto blízko „{{name}}"",packages/visual-editor/locales/platform/tr/visual-editor.json-480-481 (1)
480-481:⚠️ Potential issue | 🟡 MinorTurkish pluralization: nouns after numerals should not take the plural suffix.
In Turkish, when a noun is preceded by a number, it remains singular (e.g., "5 konum", not "5 konumlar"). The
_otherform should use the singular noun, same as_one. Additionally,_onecapitalizes "Konum" while_otherlowercases "konumlar" — these should be consistent.Proposed fix
- "locationWithCount_one": "{{count}} Konum", - "locationWithCount_other": "{{count}} konumlar", + "locationWithCount_one": "{{count}} konum", + "locationWithCount_other": "{{count}} konum",packages/visual-editor/locales/platform/fr/visual-editor.json-480-482 (1)
480-482:⚠️ Potential issue | 🟡 MinorInconsistent quoting style across
locationsWithinDistanceOfplural variants.Line 480 (
_one) and line 482 (_other) wrap{{name}}in escaped double-quotes (\"{{name}}\"), but the new_manyvariant on line 481 uses French guillemets (« {{name}} »). This will produce visually different output depending on the count.Proposed fix — align with sibling entries
- "locationsWithinDistanceOf_many": "{{count}} emplacements dans {{distance}} {{unit}} de « {{name}} »", + "locationsWithinDistanceOf_many": "{{count}} emplacements dans {{distance}} {{unit}} de \"{{name}}\"",packages/visual-editor/locales/platform/hu/visual-editor.json-445-446 (1)
445-446:⚠️ Potential issue | 🟡 Minor
fontSizeis mistranslated;fontSizeDefaultLabeluses a misleading word for "Default".
- Line 445:
"Betűkészlet"means "font family / font set" in Hungarian, not "font size." The correct translation is "Betűméret". The same mistranslation appears at Line 608 (theme.fontSize), which was not changed in this PR but carries the same error.- Line 446:
"Mulasztás"literally means "negligence / omission." While it can loosely be used for "default" in legal contexts, the standard Hungarian UI term is"Alapértelmezett"(already used at Line 140). The same issue exists at Line 273 (options.default) and Line 563 (spacingDefaultLabel).Proposed fix
- "fontSize": "Betűkészlet", - "fontSizeDefaultLabel": "Mulasztás", + "fontSize": "Betűméret", + "fontSizeDefaultLabel": "Alapértelmezett",packages/visual-editor/locales/platform/hu/visual-editor.json-124-124 (1)
124-124:⚠️ Potential issue | 🟡 MinorChange
"Video"to"video"to match the camelCase/lowercase convention.All other single-word component keys in this section use lowercase (
address,phone,team,testimonial,timestamp), while compound keys use camelCase (aboutSection,videoSection)."Video"is the only single-word key using PascalCase and should be lowercase"video"for consistency.packages/visual-editor/locales/platform/lv/visual-editor.json-205-205 (1)
205-205:⚠️ Potential issue | 🟡 MinorUse imperative verb form for
"expandFooter".Per the established Latvian translation convention, UI action labels should use the imperative form to match the English intent. "Paplašināt kājeni" is the infinitive; the imperative would be "Paplašiniet kājeni". Based on learnings, in Latvian translations for the visual editor, prefer imperative verb forms that align with the English UI (e.g., use 'Aizpildiet konteineru' for 'Fill Container').
Proposed fix
- "expandFooter": "Paplašināt kājeni", + "expandFooter": "Paplašiniet kājeni",packages/visual-editor/locales/platform/hr/visual-editor.json-124-125 (1)
124-125:⚠️ Potential issue | 🟡 MinorInconsistent key casing:
"Video"should be"video".All sibling keys under
componentsuse camelCase (directoryGrid,bodyText,videoSection, etc.), but this key starts with an uppercaseV. If the code referencescomponents.video(lowercase), the translation will silently miss.Proposed fix
- "Video": "Video", + "video": "Video",packages/visual-editor/locales/platform/hr/visual-editor.json-644-646 (1)
644-646:⚠️ Potential issue | 🟡 MinorInconsistent word and incorrect
_fewform fortotalReviews.Two issues:
- Word mismatch:
_oneuses "pregled" while_few/_otheruse "recenzija" — these should use the same word across all plural forms._fewgrammar: if using "recenzija" (feminine), counts 2–4 require "recenzije", not "recenzija".Proposed fix (using "recenzija" consistently)
- "totalReviews_one": "{{count}} pregled", - "totalReviews_few": "{{count}} recenzija", + "totalReviews_one": "{{count}} recenzija", + "totalReviews_few": "{{count}} recenzije", "totalReviews_other": "{{count}} recenzija",packages/visual-editor/locales/platform/hr/visual-editor.json-477-485 (1)
477-485:⚠️ Potential issue | 🟡 MinorCroatian
_fewplural for "lokacija" should be "lokacije".For feminine noun "lokacija", counts 2–4 require the nominative plural "lokacije". All three
_fewentries currently duplicate the_otherform ("lokacija"), producing incorrect grammar for counts like 2, 3, 4.Affected keys:
locationsNear_few(Line 478),locationsWithinDistanceOf_few(Line 481),locationWithCount_few(Line 484).Proposed fix
- "locationsNear_few": "{{count}} lokacija u blizini \"{{name}}\"", + "locationsNear_few": "{{count}} lokacije u blizini \"{{name}}\"",- "locationsWithinDistanceOf_few": "{{count}} lokacija unutar {{distance}} {{unit}} od \"{{name}}\"", + "locationsWithinDistanceOf_few": "{{count}} lokacije unutar {{distance}} {{unit}} od \"{{name}}\"",- "locationWithCount_few": "{{count}} lokacija", + "locationWithCount_few": "{{count}} lokacije",packages/visual-editor/scripts/generateTranslations.ts-356-358 (1)
356-358:⚠️ Potential issue | 🟡 MinorInconsistent log prefix —
typeis missing from the error log.Success logs on Line 354 use
[${type}/${locale}]but the error log on Line 358 uses[${locale}].Suggested fix
- console.error(`[${locale}] Failed to translate key "${key}":`, error); + console.error(`[${type}/${locale}] Failed to translate key "${key}":`, error);packages/visual-editor/scripts/generateTranslations.ts-185-187 (1)
185-187:⚠️ Potential issue | 🟡 MinorContext markers may survive in translated output if the MT engine alters them.
Google Translate can transliterate or translate the
[[context: …]]marker (e.g.,[[contexto: dirección]]in Spanish, or bracket substitution in CJK languages). The current regex requires the literal wordcontextand ASCII]], so mangled markers will leak into the final translation string.Consider using a more robust sentinel (e.g., an XML-like tag
<x-ctx>…</x-ctx>which MT engines tend to pass through) or validate post-translation that no residual markers remain:💡 Quick fallback: warn when removal is a no-op
const removeEmbeddedContext = (text: string): string => { - return text.replace(/\s*\[\[\s*context:\s*[\s\S]*?\]\]/gi, "").trim(); + const cleaned = text.replace(/\s*\[\[\s*context:\s*[\s\S]*?\]\]/gi, "").trim(); + // Warn if markers may have been mangled by MT + if (cleaned.includes("[[") || cleaned.includes("]]")) { + console.warn(`Possible residual context marker in: "${cleaned}"`); + } + return cleaned; };packages/visual-editor/locales/platform/it/visual-editor.json-462-463 (1)
462-463:⚠️ Potential issue | 🟡 Minor
_manyplural keys are unused for Italian cardinal plurals.Italian CLDR rules define cardinal plural categories as
oneandotheronly. The_manycategory applies exclusively to ordinal plurals (for numbers 8, 11, 80, 800) and is not relevant in cardinal contexts. These keys—kilometer_many,locationsNear_many,locationsWithinDistanceOf_many,locationWithCount_many,mile_many, andtotalReviews_many—will never be selected by i18next's plural resolver for theitlocale and represent dead translations.
🧹 Nitpick comments (17)
packages/visual-editor/locales/components/ja/visual-editor.json (1)
20-24: Minor katakana spacing inconsistency.Line 22 uses a half-width space in "ユーティリティ イメージ", while other compound katakana terms elsewhere in this file are written without spaces (e.g., "ヒーローバナー", "ヒーローヘッダー", "フォトギャラリーセクション"). Consider removing the space for consistency.
🌐 Proposed fix
- "defaultAlt": "ユーティリティ イメージ {{number}}" + "defaultAlt": "ユーティリティイメージ {{number}}"packages/visual-editor/locales/components/pt/visual-editor.json (1)
38-38:_manyplural forms are unused for Portuguese.Portuguese CLDR plural rules only define
oneandothercategories — the_manyform is never selected at runtime by i18next. These keys are harmless but effectively dead code. If the new i18next-cli tooling is auto-generating them, it may be worth configuring it to skip_manyfor Romance languages to keep locale files lean.Also applies to: 43-43, 46-46, 49-49, 54-54, 96-96
packages/visual-editor/locales/components/es/visual-editor.json (1)
38-40:_manyplural form is unused in Spanish.Per CLDR plural rules, Spanish only uses
oneandothercategories — there is nomanycategory. Keys likekilometer_many,locationWithCount_many,mile_many, andtotalReviews_manywill never be selected by i18next for theeslocale. They are harmless but add dead entries. If these were auto-generated by the new i18next-cli tooling across all locales, this is understandable, but worth being aware of.Also applies to: 43-45, 54-56, 96-98
packages/visual-editor/locales/components/lt/visual-editor.json (1)
70-73: Minor translation inconsistencies in "promo" keys.
promoBanner: "Reklaminė reklamjuostė" is somewhat redundant ("promotional ad-banner").promoMedia: "Promo žiniasklaida" mixes the untranslated English loanword "Promo" with Lithuanian, whilepromoBanneruses a fully Lithuanian translation.Consider aligning both — e.g., "Reklaminė medžiaga" or "Reklaminė žiniasklaida" for
promoMedia, and simplifyingpromoBannerto "Reklamjuostė" to avoid redundancy.packages/visual-editor/locales/components/lv/visual-editor.json (1)
25-25: VerifycoreInfoSectiontranslation.
"Pamatinformācija"means "basic information" — which is a reasonable rendering of "core info." Just noting that other*Sectionkeys include the word"sadaļa"(section) in their value (e.g.,"Stundu sadaļa","Informācijas sadaļa"). If this key is meant to label a section header consistently with those, consider"Pamatinformācijas sadaļa".packages/visual-editor/locales/platform/fi/visual-editor.json (1)
238-243: Finnish grammar: "Linkki kohde" should be a compound or genitive form.Line 243 correctly uses a compound word (
"Linkkityyppi"), and Line 238 correctly uses the genitive ("Linkin etiketti"). Line 242's"Linkki kohde"(two bare nouns) is not grammatical Finnish — it should be"Linkkikohde"(compound) or"Linkin kohde"(genitive) to match the pattern.Proposed fix
- "linkTarget": "Linkki kohde", + "linkTarget": "Linkin kohde",packages/visual-editor/locales/components/fi/visual-editor.json (2)
61-61: Inconsistent "section" suffix across keys.
photoGallerySectionuses "osa" (part) — "Valokuvagalleriaosa" — while other section keys likehoursSection("Tuntien osio") and the correctedservicesSection/coreInfoSectionuse "osio". Consider using "osio" consistently: "Valokuvagalleria-osio".
1-97: Consider a native-speaker review pass on machine-translated strings.Multiple translations in this file exhibit patterns typical of automated translation (literal translations, incorrect compound words, semantic drift). The
informationSection→ "Tiedonsiirto" error is the most critical, but several others (breadcrumb,servicesSection,promoMedia,coreInfoSectionspacing) also need correction. If these translations were generated via the new Google Translate integration, a native Finnish speaker review pass would catch these before they reach users.packages/visual-editor/locales/platform/da/visual-editor.json (1)
322-323: Inconsistent capitalization:"Timer Status"vs"Timer tabel".Danish doesn't use title case — only the first word is capitalized. Line 323 is correct (
"Timer tabel"), but line 322 should follow the same convention.Proposed fix
- "hoursStatus": "Timer Status", + "hoursStatus": "Timer status",packages/visual-editor/locales/platform/es/visual-editor.json (1)
462-462:_manyplural forms are unused for Spanish.Spanish (per CLDR/Unicode) only has two plural categories:
oneandother. i18next will never resolve the_manykey for theeslocale. These entries at lines 462, 478, 481, 484, 490, and 645 are dead weight. If the new i18next-cli is auto-generating them, consider configuring it to only emit plural forms relevant to the target language.Also applies to: 478-478, 481-481, 483-485, 490-490, 645-645
packages/visual-editor/locales/platform/tr/visual-editor.json (1)
238-243: Minor casing inconsistency across sibling field translations.
linkLabel→ "Bağlantı Etiketi",linkTarget→ "Bağlantı Hedefi" (both title-cased), butlinkType→ "Bağlantı türü" (lowercase). Consider aligning to the same convention.Proposed fix (align to title case)
- "linkType": "Bağlantı türü", + "linkType": "Bağlantı Türü",packages/visual-editor/locales/platform/ja/visual-editor.json (1)
28-28: Breadcrumb translation corrected to proper UI term.パンくずリスト is the correct Japanese term for breadcrumb navigation. However, note that on line 60 (unchanged),
components.breadcrumbsis still"パン粉"— which literally means "panko" (food breadcrumbs), not a navigation breadcrumb. Consider updating that value in a follow-up to maintain consistency.packages/visual-editor/locales/platform/en-GB/visual-editor.json (1)
124-124: Same PascalCase"Video"inconsistency as in the sv locale.This is the root source locale — the key here propagates to all other platform locale files. Renaming to
"video"here will need a corresponding update to any code referencingcomponents.Videoand to the propagation/extraction config so this doesn't resurface.Proposed fix
- "Video": "Video", + "video": "Video",packages/visual-editor/locales/platform/sv/visual-editor.json (1)
124-124:"Video"is PascalCase while all other keys in thecomponentssection use camelCase.The inconsistency is confirmed: every sibling key uses camelCase (
directoryGrid,hoursStatus,videoSection, etc.). For consistency with the rest of the components section, rename this to"video".Note: A search of the codebase found no references to this key, so it may be unused or orphaned. Renaming will not break existing code, but consider whether it should be retained at all.
Proposed fix
- "Video": "Video", + "video": "Video",packages/visual-editor/locales/platform/lv/visual-editor.json (1)
1-656: Several other translations appear to be machine-generated with semantic errors.A few examples beyond the changed lines (but worth a pass during this tooling migration):
- Line 44:
"close": "Tuvs"— "Tuvs" means "near" (proximity), not "close" (to shut). Should be "Aizvērt".- Line 47:
"closeMenu": "Aizvērt ēdienkarti"— "ēdienkarte" means "food menu", not a navigation menu. Should be "Aizvērt izvēlni".- Line 503:
"openMenu": "Atvērta ēdienkarte"— same "food menu" issue.- Line 635:
"uppercase": "Lielie cilvēki"— "Big people" instead of "Lielie burti" (uppercase letters).These aren't on changed lines so they may pre-date this PR, but since the PR is swapping i18n tooling and touching this file, it may be a good opportunity to run a quality check on the Latvian translations.
packages/visual-editor/scripts/generateTranslations.ts (1)
241-266: No timeout or retry logic on translation requests.
fetchhas no timeout, so a hanging request will block the script indefinitely. Additionally, there's no retry for transient network/API failures — a single 429 or 5xx will permanently skip that key.Consider adding an
AbortSignal.timeout()and a simple retry with backoff:💡 Suggested improvement
const translateText = async ( text: string, - targetLang: string + targetLang: string, + retries = 2 ): Promise<string> => { const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${DEFAULT_LANGUAGE}&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}`; - const response = await fetch(url); + const response = await fetch(url, { signal: AbortSignal.timeout(10_000) }); if (!response.ok) { + if (retries > 0 && (response.status === 429 || response.status >= 500)) { + await new Promise((r) => setTimeout(r, 1000 * (3 - retries))); + return translateText(text, targetLang, retries - 1); + } throw new Error( `Google Translate API error: ${response.status} for text: "${text}"` ); }Also note that
translate.googleapis.comwithclient=gtxis an unofficial, undocumented API that may be rate-limited or discontinued without notice. If this script is part of CI or runs frequently, consider switching to the official Cloud Translation API.packages/visual-editor/locales/platform/pt/visual-editor.json (1)
462-462: Remove unnecessary_manyplural forms from Portuguese locale — they are never used by CLDR rules.Portuguese only has two CLDR plural categories:
one(for 0 and 1) andother(for all other values). Themanycategory does not exist for Portuguese. These keys will never be resolved at runtime, even though i18next silently ignores them.While not a functional issue, they add noise to the locale file and can confuse translators. Consider checking if the i18next-cli extraction tooling is unconditionally emitting
_manyforms for all languages regardless of CLDR support.
packages/visual-editor/locales/components/fi/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/fr/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/hr/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/it/visual-editor.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 12
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/components/fi/visual-editor.json`:
- Line 63: The translation for the locale key promoMedia currently reads
"Promootio" which omits the "media" meaning; update the value for promoMedia in
the visual-editor JSON to a Finnish string that includes media (e.g.,
"Promootiomedia" or "Markkinointimedia") so the key accurately reflects
promotional media content; ensure you only change the RHS string for the
promoMedia key and keep JSON formatting intact.
- Line 9: Replace the incorrect Finnish string value for the "breadcrumb" key in
the visual editor locale (packages/visual-editor locales file) from "Leivänmuru"
to the established UI term "Murupolku"; also update the same "breadcrumb" key in
the platform locale file where the same incorrect value appears so both locale
entries use "Murupolku" consistently.
In `@packages/visual-editor/locales/components/fr/visual-editor.json`:
- Around line 49-51: The three plural keys locationsWithinDistanceOf_many,
locationsWithinDistanceOf_one and locationsWithinDistanceOf_other use
inconsistent quoting and wording; update all three to the same French phrasing
and quote style (for example: use guillemets « {{name}} » consistently) and
standardize the preposition/phrase (e.g. "{{count}} emplacement(s) à
{{distance}} {{unit}} de « {{name}} »" or "{{count}} emplacements dans un rayon
de {{distance}} {{unit}} de « {{name}} »") so the displayed message is identical
across plural forms.
In `@packages/visual-editor/locales/components/hr/visual-editor.json`:
- Around line 35-37: Update the Croatian translations for the keys "hours",
"hoursSection", and "informationSection": replace the nominative form for
"hours" from "Sate" to "Sati", and make the two section labels unambiguous by
changing "hoursSection" to "Odjeljak radnog vremena" and "informationSection" to
"Odjeljak s informacijama" so each key clearly matches its English meaning.
- Line 9: Replace the incorrect Croatian translation value for the "breadcrumb"
key in visual-editor.json: change "Krušnica" to the correct standard term
"Krušne mrvice" (or the exact string used elsewhere in the codebase for the
component label) so the breadcrumb label is consistent and accurate across
locales.
In `@packages/visual-editor/locales/platform/fi/visual-editor.json`:
- Line 242: The Finnish translation for the JSON key "linkTarget" is
grammatically incorrect; replace the value "Linkki kohde" with a correct form
(use the compound "Linkkikohde" to match the style of "Linkkityyppi") so the
"linkTarget" entry reads the proper Finnish compound word.
- Line 446: The Finnish translation uses "Laiminlyönti" incorrectly for default
settings; update the keys fontSizeDefaultLabel and spacingDefaultLabel to use
"Oletus" instead of "Laiminlyönti", and fix the options.default entry (the JSON
key "default") to "Oletus" as well so all default-setting labels use the correct
Finnish word; locate the entries by their JSON keys (fontSizeDefaultLabel,
spacingDefaultLabel, options.default) and replace the value string with
"Oletus".
- Line 124: The "Video" JSON key uses PascalCase while sibling keys use
camelCase; rename the "Video" key to camelCase (e.g., "video") in this file and
the corresponding English locale so it matches siblings like "videoSection",
"aboutSection", and "address", and update any code references that read the old
"Video" key (search for "Video" in the codebase) to use the new "video" key.
In `@packages/visual-editor/locales/platform/fr/visual-editor.json`:
- Around line 478-482: The translations for the plural key
locationsWithinDistanceOf_many are inconsistent: replace the French guillemets
and the phrasing so it matches the other variants (locationsWithinDistanceOf_one
and locationsWithinDistanceOf_other); specifically, change
locationsWithinDistanceOf_many to use escaped double quotes around {{name}}
(\"{{name}}\") and include the phrase "dans un rayon de {{distance}} {{unit}}
de" so all plural forms use the same wording and quoting style.
- Line 124: The "Video" key in the components object is using PascalCase while
its siblings use camelCase; rename the key "Video" to "video" in the components
object (e.g., in packages/visual-editor/locales/platform/fr/visual-editor.json)
and mirror the same change across the other locale files where the PascalCase
copy exists so the localization keys are consistently camelCase; verify and
update any code or tests that reference the old "Video" key to use "video".
In `@packages/visual-editor/locales/platform/hr/visual-editor.json`:
- Line 462: The locale entry for the key "kilometer_few" is incorrect: replace
its value "kilometara" with the correct Croatian few-form "kilometra" (so
"kilometer_few" = "kilometra") and ensure the _few form now differs from the
genitive plural used in "kilometer_other"/"_other" to match the components file
fix.
- Around line 322-323: The translation for components.hoursTable is inconsistent
and grammatically incorrect ("Sate stol"); update the components.hoursTable
entry to match the correct and consistent translation used by options.hoursTable
("Tablica sati") so both keys (components.hoursTable and options.hoursTable) use
the same phrase and correct grammar.
🧹 Nitpick comments (3)
packages/visual-editor/locales/platform/it/visual-editor.json (1)
462-463:_manyplural keys are unused for Italian locale.Italian's CLDR plural rules only define
oneandothercategories — there is nomanycategory. Keys likekilometer_many,locationsNear_many,locationsWithinDistanceOf_many,locationWithCount_many,mile_many, andtotalReviews_manywill never be selected by i18next for theitlocale. These are likely artifacts of the new i18next-cli extraction/propagation tooling.Not a bug (they're silently ignored), but they add noise to the locale file. Consider whether the propagation script should be locale-aware for plural categories.
Also applies to: 478-479, 481-482, 483-485, 490-491, 645-646
packages/visual-editor/locales/platform/hr/visual-editor.json (2)
242-242:linkTargetnow translated — minor style note.The past-review concern about this value being English is resolved. The neighboring keys follow a
"<noun> veze"pattern ("linkLabel": "Oznaka veze","linkType": "Vrsta veze"), whilelinkTargetis just"Odredište". For consistency,"Odredište veze"would align better, but this is a nitpick.
124-124: Update the translation key from"Video"to"video"to match camelCase convention.The
"Video"key is explicitly defined in the Video component (src/components/contentBlocks/Video.tsx, line 53) with uppercase casing, which breaks the camelCase naming convention used throughout thecomponentssection (e.g.,videoSection,directoryGrid,heroImage,gallery,footer). Change"components.Video"to"components.video"in the component configuration and update all locale files accordingly.
packages/visual-editor/locales/components/fi/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/fi/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/fr/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/hr/visual-editor.json
Outdated
Show resolved
Hide resolved
packages/visual-editor/locales/components/hr/visual-editor.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
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/components/de/visual-editor.json`:
- Around line 18-19: The German locale strings for visual-editor use a hardcoded
weekday "Donnerstag" in the keys closesAtTime and closesAtTimeWeek; update both
values to use a placeholder for the weekday (e.g., replace "Donnerstag" with a
variable like {{dayOfWeek}} or remove the hardcoded day) so the message is
dynamic and matches closesAtTimeWeek's intended interpolation, ensuring the JSON
keys closesAtTime and closesAtTimeWeek contain the correct placeholders.
In `@packages/visual-editor/locales/platform/de/visual-editor.json`:
- Around line 48-49: The German locale strings are hardcoding "Donnerstag";
update the JSON keys "closesAtTime" to remove the hardcoded day so it only
contains the time placeholder, and update "closesAtTimeWeek" to remove
"Donnerstag" and use the existing {{dayOfWeek}} variable instead; apply the same
change in both locales files where these keys appear so the output becomes e.g.
"Schließt um {{time}} Uhr" and "Schließt um {{time}} Uhr {{dayOfWeek}}".
🟡 Minor comments (25)
packages/visual-editor/locales/platform/es/visual-editor.json-644-646 (1)
644-646:⚠️ Potential issue | 🟡 MinorInconsistent word in
totalReviews_manyvs the other plural forms.
_oneuses "reseña" and_otheruses "reseñas", but_manyuses "opiniones" (opinions). All three should use the same root word for a consistent user experience.Proposed fix
- "totalReviews_many": "{{count}} opiniones", + "totalReviews_many": "{{count}} reseñas",packages/visual-editor/locales/platform/es/visual-editor.json-477-479 (1)
477-479:⚠️ Potential issue | 🟡 MinorInconsistent word order in
locationsNear_many.The
_oneform (line 477) uses"{{count}} ubicación cerca de ..."and the_otherform (line 479) uses"{{count}} ubicaciones cerca de ..."— both place{{count}}first. The_manyform on line 478 reverses this to"Ubicaciones {{count}} cerca de ...". This looks like a machine-translation artifact.Proposed fix
- "locationsNear_many": "Ubicaciones {{count}} cerca de \"{{name}}\"", + "locationsNear_many": "{{count}} ubicaciones cerca de \"{{name}}\"",packages/visual-editor/locales/platform/da/visual-editor.json-446-446 (1)
446-446:⚠️ Potential issue | 🟡 MinorMistranslation: "Misligholdelse" is the wrong sense of "default".
"Misligholdelse" translates to "default" in the legal/financial sense (breach of obligation, failure to pay), not "default" as in "the preset/standard option." The correct Danish term here would be "Standard".
This same mistranslation appears on other (unchanged) lines as well (e.g.,
"default"on line 140,options.defaulton line 273,spacingDefaultLabelon line 563), suggesting a systemic machine-translation error for the word "default."Proposed fix for the changed line
- "fontSizeDefaultLabel": "Misligholdelse", + "fontSizeDefaultLabel": "Standard",packages/visual-editor/locales/platform/lt/visual-editor.json-238-243 (1)
238-243:⚠️ Potential issue | 🟡 MinorInconsistent translation casing/grammar on
linkTarget.
linkLabelandlinkTypeboth use the genitive form "Nuorodos" + lowercase noun (e.g., "Nuorodos etiketė", "Nuorodos tipas"), butlinkTargetuses nominative "Nuoroda" + capitalized "Tikslas". This looks like a machine-translation artifact.Suggested fix for consistency
- "linkTarget": "Nuoroda Tikslas", + "linkTarget": "Nuorodos tikslas",packages/visual-editor/locales/platform/zh/visual-editor.json-476-477 (1)
476-477:⚠️ Potential issue | 🟡 MinorInconsistent wording between
locationsNear_oneandlocationsNear_other.
_oneuses "位置" while_otheruses "地点". Since Chinese has no grammatical plural distinction, these two forms should be identical (similar to the fix applied tolocationWithCountat lines 480–481).Proposed fix
"locationsNear_one": ""{{name}}"附近有 {{count}} 个位置", - "locationsNear_other": ""{{name}}"附近有 {{count}} 个地点", + "locationsNear_other": ""{{name}}"附近有 {{count}} 个位置",packages/visual-editor/locales/platform/fi/visual-editor.json-205-205 (1)
205-205:⚠️ Potential issue | 🟡 MinorVerb form: prefer imperative "Laajenna" over infinitive "Laajentaa" for a UI action.
Finnish UI labels for toggle/action fields conventionally use the imperative mood. "Laajentaa alatunnistetta" (infinitive: "to expand the footer") reads awkwardly; "Laajenna alatunniste" (imperative: "Expand footer") is more natural and consistent with standard Finnish UI conventions.
🌐 Proposed fix
- "expandFooter": "Laajentaa alatunnistetta", + "expandFooter": "Laajenna alatunniste",packages/visual-editor/locales/platform/nl/visual-editor.json-322-323 (1)
322-323:⚠️ Potential issue | 🟡 MinorInconsistent translations with identical keys elsewhere in this file.
- Line 322:
"hoursStatus": "Uurstatus"uses singular "Uur", butcomponents.hoursStatusat line 95 is"Urenstatus"(plural).- Line 323:
"hoursTable": "Uren tabel"is two words, butcomponents.hoursTableat line 96 is"Urentafel"(one word, different noun).These refer to the same UI concepts and should use consistent translations. Dutch compound nouns are typically written as a single word.
Proposed fix to align with existing translations
- "hoursStatus": "Uurstatus", - "hoursTable": "Uren tabel", + "hoursStatus": "Urenstatus", + "hoursTable": "Urentafel",packages/visual-editor/locales/platform/nl/visual-editor.json-242-242 (1)
242-242:⚠️ Potential issue | 🟡 MinorIncorrect Dutch translation: "Doel koppelen" is a verb phrase ("to link a target"), not a noun.
The key
linkTargetrepresents a UI label (noun), but "Doel koppelen" reads as an imperative/infinitive verb phrase. For consistency with"linkLabel": "Linklabel"and"linkType": "Linktype"on adjacent lines, this should be a compound noun.Proposed fix
- "linkTarget": "Doel koppelen", + "linkTarget": "Linkdoel",packages/visual-editor/locales/platform/tr/visual-editor.json-480-481 (1)
480-481:⚠️ Potential issue | 🟡 MinorTurkish plural form
konumlaris incorrect when preceded by a count.In Turkish, nouns remain singular when preceded by a numeral (e.g., "5 konum", not "5 konumlar"). The
_otherform should use the same singular noun as_one. This is consistent with how other count-based keys in this file handle Turkish plurals:
kilometer_other:"kilometre"(not"kilometreler")mile_other:"mil"(not"miller")locationsNear_other: uses"konum"(not"konumlar")Also, there's an inconsistent capitalization between
"Konum"(line 480) and"konumlar"(line 481).Proposed fix
- "locationWithCount_one": "{{count}} Konum", - "locationWithCount_other": "{{count}} konumlar", + "locationWithCount_one": "{{count}} Konum", + "locationWithCount_other": "{{count}} Konum",packages/visual-editor/locales/platform/hu/visual-editor.json-445-446 (1)
445-446:⚠️ Potential issue | 🟡 Minor
fontSizemistranslated as "Betűkészlet" (Font family/set) instead of "Betűméret" (Font size)."Betűkészlet" means "font set" or "font family" in Hungarian, not "font size." The correct translation is "Betűméret". The same error also exists on line 608 under
theme.fontSize.Proposed fix
- "fontSize": "Betűkészlet", + "fontSize": "Betűméret",And similarly for line 608:
- "fontSize": "Betűkészlet", + "fontSize": "Betűméret",packages/visual-editor/locales/platform/nb/visual-editor.json-322-323 (1)
322-323:⚠️ Potential issue | 🟡 MinorMinor inconsistency: "Timerbord" vs "Timetabell" for
hoursTable.The new entry at line 323 translates
hoursTableas"Timetabell", but the existingcomponents.hoursTableat line 96 uses"Timerbord"."Timetabell"is the better translation — consider updating line 96 to match.Proposed fix
At line 96 (outside the changed range):
- "hoursTable": "Timerbord", + "hoursTable": "Timetabell",packages/visual-editor/locales/platform/fr/visual-editor.json-653-653 (1)
653-653:⚠️ Potential issue | 🟡 Minor
videoThumbnailtranslation is garbled."Vide-gigantes" is not a valid French translation for "Video Thumbnail". The correct translation would be "Miniature vidéo" or "Vignette vidéo".
Proposed fix
- "videoThumbnail": "Vide-gigantes", + "videoThumbnail": "Miniature vidéo",packages/visual-editor/locales/platform/fr/visual-editor.json-28-28 (1)
28-28:⚠️ Potential issue | 🟡 MinorInconsistency:
breadcrumbvsbreadcrumbstranslations.Line 28 correctly uses "Fil d'Ariane" (the standard French term for navigation breadcrumbs), but the existing
components.breadcrumbskey at line 60 uses "Chapelure" — which means food breadcrumbs. These should be consistent; both navigation-related breadcrumb keys should use "Fil d'Ariane".Proposed fix (line 60)
- "breadcrumbs": "Chapelure", + "breadcrumbs": "Fil d'Ariane",packages/visual-editor/locales/platform/zh-TW/visual-editor.json-610-610 (1)
610-610:⚠️ Potential issue | 🟡 Minor
fontWeighttranslation is a literal calque."字體重量" literally means "font mass/weight (physical)". The conventional zh-TW translation for the CSS/typography concept of font weight is "字體粗細" (font thickness), which is widely used in UI/design contexts.
Proposed fix
- "fontWeight": "字體重量" + "fontWeight": "字體粗細"packages/visual-editor/locales/platform/zh-TW/visual-editor.json-322-323 (1)
322-323:⚠️ Potential issue | 🟡 MinorMinor translation inconsistency between
hoursStatusandhoursTable.
hoursStatustranslates "hours" as "小時" (literal time unit), yielding "小時狀態", whilehoursTableuses the more natural "營業時間" (business hours), yielding "營業時間表". In the context of store operating hours, "營業狀態" would be more idiomatic forhoursStatusand consistent withhoursTable.Proposed fix
- "hoursStatus": "小時狀態", + "hoursStatus": "營業狀態", "hoursTable": "營業時間表",packages/visual-editor/locales/platform/ro/visual-editor.json-68-68 (1)
68-68:⚠️ Potential issue | 🟡 Minor"Director Grid" mixes Romanian and English — "Grid" left untranslated.
Line 89 uses "Grila" (Romanian for "Grid") in
"gridSection": "Secțiune Grila". For consistency, consider translating this to"Grilă Director"or similar.Proposed fix
- "directoryGrid": "Director Grid", + "directoryGrid": "Grilă Director",packages/visual-editor/locales/platform/pl/visual-editor.json-461-464 (1)
461-464:⚠️ Potential issue | 🟡 MinorIncorrect Polish plural form for
kilometer_many.
"kilometer_many": "kilometry"(line 463) is grammatically wrong. The_manycategory in Polish covers counts like 0, 5–21, 25–31 …, which require the genitive plural: "kilometrów", not the nominative plural "kilometry". The_otherform (line 464, used for fractional counts) should also be "kilometrów" (or "kilometra" for genitive singular, depending on style).
Suffix Example counts Correct form _one1 kilometr✓_few2, 3, 4 kilometry✓_many0, 5–21 kilometrów✗ (currently "kilometry")_otherfractional kilometrów✗ (currently "kilometry")Proposed fix
"kilometer_one": "kilometr", "kilometer_few": "kilometry", - "kilometer_many": "kilometry", - "kilometer_other": "kilometry", + "kilometer_many": "kilometrów", + "kilometer_other": "kilometrów",packages/visual-editor/locales/components/fi/visual-editor.json-75-75 (1)
75-75:⚠️ Potential issue | 🟡 Minor"Palvelusosasto" means "service department", not "services section".
Two issues: (1) "osasto" means department/ward (organizational unit), while "osio" is the Finnish term for a content section; (2) "palvelus-" has a military/obligatory connotation, whereas "palvelu-" is the standard modifier for services. The translation should be "Palveluosio".
🌐 Proposed fix
- "servicesSection": "Palvelusosasto", + "servicesSection": "Palveluosio",packages/visual-editor/locales/components/fi/visual-editor.json-25-25 (1)
25-25:⚠️ Potential issue | 🟡 MinorInconsistent spacing in "Ydintiedot -osio".
The space before the hyphen (" -osio") doesn't follow Finnish compound word conventions and is inconsistent with other entries in this file (e.g.,
"Tieto-osio"on Line 37 uses no space). Should be"Ydintiedot-osio"or"Ydintietojen osio".🌐 Proposed fix
- "coreInfoSection": "Ydintiedot -osio", + "coreInfoSection": "Ydintiedot-osio",packages/visual-editor/locales/components/fi/visual-editor.json-35-35 (1)
35-35:⚠️ Potential issue | 🟡 Minor"Tuntia" uses partitive case; standalone labels should use nominative "Tunnit".
"Tuntia" is the partitive form (used in expressions like "2 tuntia"). For a standalone UI label meaning "Hours", the nominative plural "Tunnit" is standard in Finnish. If this refers specifically to business/opening hours, "Aukioloajat" would be even more precise.
🌐 Proposed fix
- "hours": "Tuntia", + "hours": "Tunnit",packages/visual-editor/locales/platform/sk/visual-editor.json-486-489 (1)
486-489:⚠️ Potential issue | 🟡 MinorInconsistent root word across plural forms of
locationWithCount.The
_oneform uses "lokácia" and_otheruses "lokality" (both from the "lokácia" root — correct), but_fewand_manyuse "miest" which derives from "miesto" (place). All forms should use the same root word.The correct Slovak declensions of "lokácia" are: singular "lokácia", few "lokácie", genitive plural "lokácií".
Proposed fix
"locationWithCount_one": "{{count}} lokácia", - "locationWithCount_few": "{{count}} miest", - "locationWithCount_many": "{{count}} miest", + "locationWithCount_few": "{{count}} lokácie", + "locationWithCount_many": "{{count}} lokácií", "locationWithCount_other": "{{count}} lokality",packages/visual-editor/locales/platform/sk/visual-editor.json-478-478 (1)
478-478:⚠️ Potential issue | 🟡 MinorInconsistent "location" terminology: "umiestnenie" vs "miesto" vs "lokácia".
Line 478 (
locationsNear_one) uses "umiestnenie" (placement/positioning), line 482 (locationsWithinDistanceOf_one) uses "miesto" (place), and lines 486-489 (locationWithCount) use "lokácia/lokality." All three keys represent the concept of a physical location and should use a consistent term — ideally "miesto" or "lokácia" throughout.Proposed fix (using "miesto" to match the _few/_many/_other forms on lines 479-481)
- "locationsNear_one": "{{count}} umiestnenie blízko „{{name}}"", + "locationsNear_one": "{{count}} miesto blízko „{{name}}"",packages/visual-editor/locales/platform/lv/visual-editor.json-483-485 (1)
483-485:⚠️ Potential issue | 🟡 MinorInconsistent wording in
locationWithCountplural group.
_zeroand_oneuse "atrašanās vietas/vieta" (locations), but_otheruses just "vietas" (places), dropping "atrašanās". This looks like a machine-translation artifact. For consistency,_othershould match:Proposed fix
"locationWithCount_zero": "{{count}} atrašanās vietas", "locationWithCount_one": "{{count}} atrašanās vieta", - "locationWithCount_other": "{{count}} vietas", + "locationWithCount_other": "{{count}} atrašanās vietas",packages/visual-editor/locales/platform/cs/visual-editor.json-486-489 (1)
486-489:⚠️ Potential issue | 🟡 MinorInconsistent word choice across
locationWithCountplural forms.
_oneand_otheruse"umístění"(placement/location), while_fewand_manyuse"míst"(places). Czech users will see the noun change depending on count, which reads oddly. Pick one term consistently — likely"míst"/"místo"/"místa"to match the_few/_manyforms and align withlocationsNear(Lines 479–481).Proposed fix to unify the noun
- "locationWithCount_one": "{{count}} umístění", + "locationWithCount_one": "{{count}} místo", "locationWithCount_few": "{{count}} míst", "locationWithCount_many": "{{count}} míst", - "locationWithCount_other": "{{count}} umístění", + "locationWithCount_other": "{{count}} míst",packages/visual-editor/locales/platform/cs/visual-editor.json-478-478 (1)
478-478:⚠️ Potential issue | 🟡 MinorSame noun inconsistency in
locationsNear.
_oneuses"umístění"while the other plural forms (Lines 479–481) use"míst". For the same reason aslocationWithCount, consider aligning:Proposed fix
- "locationsNear_one": "{{count}} umístění poblíž „{{name}}"", + "locationsNear_one": "{{count}} místo poblíž „{{name}}"",
🧹 Nitpick comments (6)
packages/visual-editor/locales/platform/ja/visual-editor.json (1)
609-611: Nit: "フォント重量" is a literal translation; consider "フォントウェイト".In web/CSS contexts, the katakana transliteration "フォントウェイト" is more commonly used in Japanese UI than the literal "フォント重量" (which reads as physical weight). Other keys in this file already use katakana transliterations for CSS terms (e.g., "フォントサイズ" for font size on line 445).
Proposed fix
"fontWeight": { - "fontWeight": "フォント重量" + "fontWeight": "フォントウェイト" },packages/visual-editor/locales/platform/zh/visual-editor.json (2)
322-323: Inconsistent translation style for "hours" betweenhoursStatusandhoursTable.
hoursStatusis translated literally as "小时状态" (hour status) whilehoursTableuses the more natural "营业时间表" (business hours table). For consistency and naturalness, consider using "营业时间状态" or at least "时间状态" forhoursStatus, matching the style ofhoursTable.Proposed fix
- "hoursStatus": "小时状态", + "hoursStatus": "营业时间状态", "hoursTable": "营业时间表",
610-610: Literal translation forfontWeight."字体重量" (font weight/mass) reads awkwardly in Chinese UI contexts. The standard term is "字体粗细" (font thickness), which is widely used in design tools and browser DevTools Chinese localizations.
Proposed fix
- "fontWeight": "字体重量" + "fontWeight": "字体粗细"packages/visual-editor/locales/platform/nb/visual-editor.json (1)
446-446:"Misligholde"is a questionable translation for "Default".
"Misligholde"literally means "to neglect / default on an obligation," not "default" in the software-settings sense."Standard"would be more natural. This is a pre-existing pattern (lines 140, 273, 563) so not blocking, but worth cleaning up across the file in a follow-up.packages/visual-editor/locales/platform/de/visual-editor.json (1)
1-650: Several translation values left in English — verify if intentional.Multiple keys have untranslated English values in this German locale file:
- Line 25:
"base": "Base"- Line 31:
"callToAction": "Call to Action"(also lines 61, 170)- Line 94:
"heroSection": "Hero Section"- Line 93:
"heroImage": "Hero Image"- Line 90:
"header": "Header"(and similar Header/Footer usages)Some of these (e.g., "Call to Action", "Header", "Footer", "Hero") may be intentional loanwords commonly used in German web/marketing contexts. If so, no action needed. If the intent is full localization, these should be translated.
packages/visual-editor/locales/platform/it/visual-editor.json (1)
322-323: Minor inconsistency in "hours" terminology.Line 322 translates "hours" as "orari" (
"Stato degli orari") while Line 323 uses "ore" ("Tabella delle ore"). In Italian, "orari" (schedules/timetables) is more appropriate for business hours context, while "ore" (time units) is slightly different. Consider aligning both:Proposed fix
"hoursStatus": "Stato degli orari", - "hoursTable": "Tabella delle ore", + "hoursTable": "Tabella degli orari",
packages/visual-editor/locales/components/de/visual-editor.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/platform/de/visual-editor.json`:
- Line 534: The value for the JSON key "secondaryHeaderLinks" has incorrect
German adjective agreement ("Erweiterter Header-Links"); update the value to the
correct plural form "Erweiterte Header-Links" so the adjective agrees with the
plural noun.
- Line 379: The translation value for the key "primaryFooter" uses the feminine
form "Primäre Footer" which is inconsistent with other entries like "Erweiterter
Footer"; update the value of the "primaryFooter" JSON entry to the masculine
form "Primärer Footer" so it matches the other footer translations.
- Line 388: The German translation for the key "secondaryHeading" uses incorrect
adjective declension; change the value from "Erweiterter Überschrift" to the
grammatically correct feminine form "Erweiterte Überschrift" for the noun
"Überschrift" (key: secondaryHeading).
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/platform/de/visual-editor.json`:
- Line 510: The translation for the key "primaryHeaderLinks" uses a singular
adjective ("Primärer") but must agree with the plural noun "Header-Links";
update the value for "primaryHeaderLinks" to use the plural adjective form
(e.g., "Primäre Header-Links") so it matches the plural noun, mirroring the fix
applied for "Erweiterte Header-Links".
- Line 380: The German translation for the key "primaryHeading" uses the wrong
adjective declension ("Primärer Überschrift"); change the string value for
"primaryHeading" to the feminine form "Primäre Überschrift" so it matches the
feminine noun "Überschrift" (consistent with the fix applied to "Erweiterte
Überschrift").
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@packages/visual-editor/locales/platform/de/visual-editor.json`:
- Line 211: The translation for the key footerSocialIcons uses "Ikonen" which is
uncommon in German UI; update the value for footerSocialIcons to use the more
appropriate term "Symbole" (e.g., "Footer soziale Symbole") or "Icons" to match
UI terminology and be consistent with the other key named icons.
- Line 96: The translation for components.hoursTable ("Geschäftszeiten") is
inconsistent with fields.options.hoursTable ("Stundentabelle"); update
fields.options.hoursTable to match components.hoursTable by replacing
"Stundentabelle" with "Geschäftszeiten" (or intentionally choose a different
term if the UI context requires a distinction), ensuring both keys
(components.hoursTable and fields.options.hoursTable) use the same German string
for consistency.
🧹 Nitpick comments (3)
packages/visual-editor/scripts/checkInterpolationVariables.ts (3)
122-132: Static analysis ReDoS warning — low risk here but worth a minor hardening.The
leafKeyis derived from translation JSON keys (not arbitrary user input), andescapeRegexneutralises special characters, so the practical ReDoS risk is negligible. Still, sincefindLineNumberForKeyis only used for diagnostic line numbers, a simpleindexOf-based approach would sidestep the concern entirely and be slightly simpler.♻️ Suggested simplification
const findLineNumberForKey = (fileContent: string, key: string): number => { const leafKey = key.split(".").pop() ?? key; - const keyPattern = new RegExp(`"${escapeRegex(leafKey)}"\\s*:`, "g"); - const match = keyPattern.exec(fileContent); - - if (!match) { + const needle = `"${leafKey}"`; + const idx = fileContent.indexOf(needle); + if (idx === -1) { return 1; } - - return fileContent.slice(0, match.index).split("\n").length; + return fileContent.slice(0, idx).split("\n").length; };This trades the strict
\s*:suffix match for a simpler substring lookup, which is fine for a best-effort line hint. If you need the colon check, the current code is acceptable given the controlled input.
193-200: Potentialundefinedaccess after array guards — add non-null assertions or destructure.
unexpectedIndexes[0]andmissing[0]are typed as potentiallyundefinedin strict TypeScript, even though the length-1 guard at lines 172 and 189 makes them safe at runtime. Downstream usage on lines 199–200 (actualExpressions[targetIndex],replacementVariable) would propagateundefinedsilently if the invariant were ever broken.♻️ Suggested hardening
- const targetIndex = unexpectedIndexes[0]; - const replacementVariable = missing[0]; + const targetIndex = unexpectedIndexes[0]!; + const replacementVariable = missing[0]!;Or use a runtime assertion:
const targetIndex = unexpectedIndexes[0]; const replacementVariable = missing[0]; if (targetIndex === undefined || replacementVariable === undefined) { return null; // defensive: shouldn't happen given prior guards }
255-258: English locale is validated against itself — skip it to avoid wasted I/O.
getSubdirectoryNames(instanceDir)returns all locale subdirectories including"en". The comparison will always yieldmismatchCount === 0for English vs. English, so it's harmless, but it reads and parses the file unnecessarily and makes the intent less clear.Also, the locale file is read twice: once as raw text (line 257) and once parsed via
loadJsonSafe(line 258). You could avoid the duplicate I/O by parsing the raw content directly.♻️ Suggested changes
+ const locales = (await getSubdirectoryNames(instanceDir)).filter( + (l) => l !== PRIMARY_LOCALE + ); - const locales = await getSubdirectoryNames(instanceDir);To deduplicate the file read:
const localeRaw = await fs.readFile(localePath, "utf-8").catch(() => ""); - const localeFlat = flatten(await loadJsonSafe(localePath)); + const localeFlat = flatten( + localeRaw ? JSON.parse(localeRaw) : {} + );(Adjust error handling to taste —
loadJsonSafemay have additional safety you want to preserve.)
This swaps from i18n-scanner to i18next-cli because:
This also removes the insertI18n script because it was clunky and not always accurate. We should add the correct translation functions manually when necessary.