#15609·activepieces

[i18n] French translations in production: what is still broken, and a fix for each (supersedes #13530)

Author: bst1nCreated Sep 17, 2026Updated Sep 17, 2026

I opened #13530 in June. I've re-checked every point against the current state (latest l10n_main export and Crowdin project settings, 2026-09-17). Two claims there were inaccurate, several problems got worse, and there are new ones. This issue replaces it with verified facts and one concrete fix per problem.

Summary

# Problem Fix
1 No translation has reached main since 2026-06-20 Rotate CROWDIN_PRS, alert on stale l10n PRs
2 Broken machine translations still ship in 100+ pieces Roll back + CI check on technical identifiers
3 The Custom API Call block is translated separately in every piece Exclude it from translation extraction
4 The piece docs teach the workflow that Crowdin overwrites Update the docs page, CONTRIBUTING and PR template
5 Unreviewed and untranslated strings ship as-is Document proofreader access, review export settings

1. No translation has reached main since 2026-06-20

The last merged Crowdin PR is #13815 (2026-06-20). #13894 then stayed open until 2026-09-08, because the required Lint PR check rejects the title "New Crowdin updates". Its replacement #15370 is still open: the Auto Merge Crowdin PRs Action run of 2026-09-10 failed with HttpError: Bad credentials.

Nothing alerted anyone for almost three months. → Rotate CROWDIN_PRS, and fail a scheduled job when the newest l10n PR is older than N days.

2. Broken machine translations still ship

From the latest l10n_main export (757 fr.json):

Source Shipped French Pieces
PUT "EFFACER" (= erase) 133
GET / POST / DELETE "OBTENIR" / "POSTER" / "SUPPRIMER" 133
HEAD "TÊTE" 121
First Name "First Name" (left untranslated) 96
Text "Texte du texte" ("text of the text") 53
Page Size "Nombre d'élément" 29
Table "Tableau" (grid view, not a database table) 14
Upsert Row "Lignée supérieure" ("upper lineage") 3

The HTTP methods are the worst: picking "EFFACER" in the method dropdown sends a PUT. → Add a CI check that technical identifiers (HTTP methods, JSON, placeholders) stay verbatim, and roll back the existing damage.

3. The Custom API Call block is translated separately in every piece

createCustomApiCallAction (packages/pieces/common) is extracted into each piece's translation.json, so Crowdin holds 479 separate French copies of the same form, each pre-translated independently. They disagree: Headers is "En-têtes" in 209 pieces and "Headers" in 267.

This is a technical form for raw HTTP calls, and its vocabulary is English. #15248 (2026-09-07) redesigned it (Timeout, Return Error as Output, URL, JSON Body…). Pieces depend on pieces-common via workspace:*, so every regeneration of a piece's translation.json pushes the new labels as new strings — ~479 pieces × 8 languages, all pre-translated again. → Exclude the block from extraction (generateTranslationFileFromPiece / pieceTranslation.pathsToValuesToTranslate) or mark it do-not-translate, and reset the existing translations.

4. The piece docs teach the workflow that Crowdin overwrites

docs/build-pieces/piece-reference/i18n.mdx tells piece authors to copy translation.json to fr.json and translate it themselves; Crowdin appears only as a tip. Crowdin's sync later replaces that file, so the work is silently lost. CONTRIBUTING.md and the PR template don't mention translations at all. (Correction to #13530: docs/about/i18n.mdx does describe Crowdin, since 2023.) → Make Crowdin the only documented path on that page, and add one line to CONTRIBUTING.md and the PR template.

5. Unreviewed and untranslated strings ship as-is

Current project settings: AI pre-translation is on for all 8 languages, TM pre-translation auto-approves 100% matches, and exportApprovedOnly and skipUntranslatedStrings are both false. Untranslated strings therefore ship as English copies — the Outseta fr.json on main contains "Account Created": "Account Created" — and unreviewed AI output ships as if reviewed.

Approval is the only lock. (Correction to #13530: translators can approve — I was granted proofreader rights — but nothing documents how to ask for them.) → Document how to request proofreader access for a locale, and confirm pre-translation never replaces an existing human translation.

Related

  • #15586 — auth texts of pieces with several auth methods are never translated (30 pieces)

I maintain 14 pieces and keep their French approved in Crowdin. Happy to help test any of these changes.

Source: activepieces/activepieces