Files
upstream-mirror e7da97194a
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
2026-09-17 23:28:13 +05:00

145 lines
5.7 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Traduzioni
description: Distribuisci la tua app in più lingue — traduci le etichette del manifest e le stringhe dell'interfaccia utente tramite un unico catalogo delle localizzazioni.
icon: language
---
Le app di Twenty sono scritte in **inglese**: le stringhe nel tuo sorgente e nel manifest
sono il testo sorgente in inglese, `en` è la locale di origine da cui traduci e
qualsiasi locale lasciato non tradotto usa quella come fallback.
La tua app ha due tipi di testo traducibile, e entrambi passano attraverso lo stesso
catalogo `locales/`:
* **Etichette del manifest** — nomi di oggetti e campi, titoli delle viste, voci di menu e
altre stringhe dichiarate nei metadati della tua app.
* **String dei front-component** — il testo dell’interfaccia utente renderizzato dai tuoi front component React.
Contrassegni le stringhe traducibili, le estrai in cataloghi per locale,
traduci tali cataloghi e la build serve la lingua corretta per l’utente
corrente — senza cablaggi aggiuntivi.
## Contrassegnare le stringhe dei front-component
Importa gli helper di traduzione da `twenty-sdk/front-component`:
```tsx
import { Trans, t, msg, useTranslate } from 'twenty-sdk/front-component';
const STATUSES = [
{ id: 'draft', label: msg('Draft') },
{ id: 'sent', label: msg('Sent') },
];
const Card = ({ count, name }: { count: number; name: string }) => {
const { t } = useTranslate();
return (
<section>
{/* Static text — reactive to the user's locale */}
<Trans>Loading postcard…</Trans>
{/* Disambiguate identical sources with a context */}
<Trans context="card-title">Untitled</Trans>
{/* Interpolation: pass values explicitly */}
<p>{t('Hi {name}', { name })}</p>
<p>{t('Saved {count} cards', { count })}</p>
{/* Resolve a lazily-declared descriptor */}
<ul>{STATUSES.map((s) => <li key={s.id}>{t(s.label)}</li>)}</ul>
</section>
);
};
```
### Quando usare cosa
* **`Trans`** — testo statico in JSX. Usa le prop `message` e `values` per
l'interpolazione, come in `Trans message="Hi {name}" values={{ name }}`;
l'interpolazione direttamente nei figli non è estraibile staticamente.
* **`useTranslate().t`** — stringhe dinamiche all’interno di un componente. Esegue il re-render quando
l’utente cambia lingua. Preferiscilo all’interno del render.
* **`t(...)`** (importato direttamente) — traduzione eager utilizzabile **ovunque**,
inclusi gestori di eventi, helper e nello scope del modulo — non solo all’interno del render.
* **`msg(...)`** — un descrittore lazy per stringhe dichiarate come dati (costanti,
configurazione). Risolvilo in un secondo momento con `t(descriptor)`.
### Contesto
Passa `context` per distinguere stringhe sorgente identiche che si traducono
in modo diverso:
```tsx
t({ message: 'Open', context: 'door' });
t({ message: 'Open', context: 'window' });
<Trans context="card-title">Untitled</Trans>
```
Le stringhe contestuali compaiono nei cataloghi delle impostazioni locali come un gruppo indicizzato dal loro
contesto: `"\<context>": { "\<message>": "\<translation>" }`. Le etichette del manifest sono
contestuali per costruzione — ognuna porta con sé il ruolo di metadato che svolge
(`objectMetadata.labelSingular`, `fieldMetadata.label`, `view.name`, …), quindi
la stessa parola può essere tradotta in modo diverso come nome di oggetto e come nome di vista.
## Estrazione e traduzione
Esegui il comando di estrazione dalla directory della tua app:
```bash
twenty dev:translations-extract # collect strings into locales/en.json
twenty dev:translations-extract --locale fr-FR # also scaffold a target locale
```
L'estrazione raccoglie sia le etichette del manifest sia le stringhe `t()`/`msg()`/`Trans`
dal tuo sorgente front-component in `locales/\<locale>.json`, indicizzate per
stringa sorgente. Compila le traduzioni:
```json
// locales/fr-FR.json
{
"Loading postcard…": "Chargement de la carte…",
"Hi {name}": "Bonjour {name}",
"Saved {count} cards": "{count} cartes enregistrées",
"door": {
"Open": "Ouvrir"
},
"objectMetadata.labelSingular": {
"Postcard": "Carte postale"
}
}
```
Le stringhe prive di contesto sono voci piatte; le stringhe contestuali — inclusa ogni
etichetta del manifest — sono annidate sotto la loro chiave di contesto.
I segnaposto come `{name}` vengono sostituiti a runtime — mantienili nella
traduzione. Qualsiasi stringa lasciata vuota fa fallback al testo sorgente.
## Come viene eseguito
`twenty dev:build` compila i cataloghi e serve la lingua corretta per l’utente
corrente: le etichette del manifest vengono risolte lato server e i cataloghi dei
front-component vengono inclusi in ogni bundle di componente. A runtime un componente legge la
locale dal proprio contesto di esecuzione (la lingua corrente dell’host) e risolve
ogni stringa rispetto al proprio catalogo, facendo fallback alla sorgente quando
una traduzione manca. Cambiare lingua nell'host esegue nuovamente il render delle stringhe `Trans` e
`useTranslate().t` in tempo reale.
Le etichette del manifest vengono compilate a ogni sincronizzazione — `twenty dev:build`, `twenty apply`
e anche il monitoraggio continuo di `twenty dev` — quindi è sufficiente modificare un file di lingua e
sincronizzare per vedere il nuovo testo. I cataloghi dei componenti Front vengono incorporati in
ogni bundle di componenti al momento della build, quindi modificarne uno significa comunque
rieseguire `twenty dev:build` (e ridistribuire).
I figli di testo di `Trans` possono estendersi su più righe — gli spazi bianchi vengono compressi
nello stesso modo in cui JSX li comprime, quindi entrambe queste varianti vengono estratte con la chiave `Welcome back`:
```tsx
<Trans>Welcome back</Trans>
<Trans>
Welcome
back
</Trans>
```