# General Translation Knowledge Base: Conviene creare un sistema i18n in autonomia o usare General Translation?
URL: https://generaltranslation.com/it/kb/general-translation-vs-in-house-i18n.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Un sistema i18n fatto in casa (un dizionario per lingua e un piccolo helper t()) va bene per una o due lingue e pochi testi. Man mano che l'app cresce, ti ritrovi a ricostruire regole del plurale, fallback e sincronizzazione dei file, e le traduzioni vanno comunque prodotte. Le librerie open source di General Translation si occupano del rendering, mentre General Translation genera e aggiorna le traduzioni a partire dal tuo codice.
Category: Internazionalizzazione
Last updated: 2026-10-16
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-16

Puoi implementare l&#39;internazionalizzazione (i18n) da solo: un oggetto di messaggi per ogni lingua, un helper `t()` che cerca una chiave e inserisce le variabili, un selettore dell&#39;impostazione regionale e le API `Intl` integrate per numeri e date. Con una o due lingue e qualche decina di stringhe, spesso non serve altro, ed è proprio ciò che un agente di programmazione tende a scrivere quando gli chiedi di aggiungere una lingua. A crescere insieme all&#39;app è tutto ciò che ruota attorno all&#39;helper: regole del plurale, chiavi mancanti, file di lingua da mantenere allineati al codice e, prima ancora, ogni singola traduzione da produrre. Le librerie open source di General Translation si occupano della parte di run-time di questo lavoro, mentre General Translation genera e aggiorna le traduzioni a partire dal tuo codice.

## Quando basta un sistema i18n fatto in casa

* **Nessuna dipendenza di terze parti.** Il dizionario e l&#39;helper sono tuoi e hai il pieno controllo su ogni riga di codice.
* **La formattazione la gestisce la piattaforma.** `Intl.NumberFormat`, `Intl.DateTimeFormat`, `Intl.PluralRules` e `Intl.Locale` sono [integrati nei browser moderni e in Node.js](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) e formattano valute, date e categorie di plurale in base all&#39;impostazione regionale.
* **Testi brevi e stabili.** Per un prototipo, uno strumento interno o un sito con una sola lingua aggiuntiva, curata da un collega, non serve altro.
* **Lingue che formano il plurale come l&#39;inglese.** Sia l&#39;inglese sia il tedesco usano solo [`one` e `other`](https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html).

## Cosa smette di funzionare man mano che il progetto cresce

Ecco una tipica prima versione, con l&#39;aggiunta di un dizionario polacco:

```js title="i18n.mjs"
const messages = {
  en: {
    greeting: 'Hello, {name}!',
    files: { one: '{count} file', other: '{count} files' },
    checkout: 'Checkout',
  },
  pl: {
    greeting: 'Cześć, {name}!',
    files: { one: '{count} plik', other: '{count} pliki' },
    // "checkout" non è stato ancora tradotto
  },
};

export function t(locale, key, vars = {}) {
  let message = messages[locale][key];
  if (typeof message === 'object') {
    message = vars.count === 1 ? message.one : message.other;
  }
  return message.replace(/\{(\w+)\}/g, (_, name) => vars[name]);
}

console.log(t('pl', 'greeting', { name: 'Ania' }));
console.log([1, 2, 5].map((count) => t('pl', 'files', { count })).join(', '));
console.log(t('pl', 'checkout'));
```

Eseguendolo con Node.js 24:

```text title="Output"
Cześć, Ania!
1 plik, 2 pliki, 5 pliki
TypeError: Cannot read properties of undefined (reading 'replace')
```

Emergono due bug contemporaneamente. &quot;5 pliki&quot; è sbagliato (in polacco si dice &quot;5 plików&quot;) e la chiave `checkout` non tradotta fa andare in crash il rendering. La piattaforma offre gli strumenti per risolverli entrambi:

```js title="intl.mjs"
// Categorie di plurale per lingua
for (const locale of ['en', 'ja', 'pl', 'ar']) {
  console.log(locale, new Intl.PluralRules(locale).resolvedOptions().pluralCategories.join(' '));
}
const pl = new Intl.PluralRules('pl');
console.log([1, 2, 5, 22].map((n) => `${n} → ${pl.select(n)}`).join(', '));

// Valute e date
const date = new Date(Date.UTC(2026, 9, 16));
for (const locale of ['en-US', 'de-DE', 'ja-JP']) {
  const price = new Intl.NumberFormat(locale, { style: 'currency', currency: 'EUR' }).format(1234.5);
  const day = new Intl.DateTimeFormat(locale, { dateStyle: 'long', timeZone: 'UTC' }).format(date);
  console.log(locale, price, day);
}

// Direzione del testo
console.log(new Intl.Locale('ar').getTextInfo().direction);
```

```text title="Output"
en one other
ja other
pl one few many other
ar zero one two few many other
1 → one, 2 → few, 5 → many, 22 → few
en-US €1,234.50 October 16, 2026
de-DE 1.234,50 € 16. Oktober 2026
ja-JP €1,234.50 2026年10月16日
rtl
```

Ogni correzione è piccola, ma sommate fanno la differenza:

* **Plurali.** `n === 1` non funziona per il polacco (quattro categorie) né per l&#39;arabo (sei), quindi l&#39;helper deve usare [`Intl.PluralRules`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules) e ogni dizionario deve contenere una stringa per ciascuna categoria. (Vedi [Come gestisco i plurali in React?](/kb/how-to-handle-plurals-in-react))
* **Ordine delle parole.** I segnaposto come `{name}` permettono a ogni lingua di spostare il valore. La concatenazione no: `t('by') + ' ' + author` mette il nome alla fine, ma in giapponese si scrive &quot;Ana 著&quot;.
* **Formattazione.** `{count}` inserisce il numero così com&#39;è, quindi l&#39;helper deve usare anche [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) per mostrare 12,500 come &quot;12 500&quot; in polacco.
* **Chiavi mancanti.** L&#39;helper ha bisogno di una catena di fallback (lingua di destinazione, poi lingua sorgente, poi la chiave), altrimenti gli utenti vedono `undefined` o l&#39;app va in crash.
* **Mantenere i file sincronizzati.** Nulla ti segnala che a `pl` manca `checkout` o che contiene ancora il testo del mese scorso, finché non se ne accorge un utente.
* **Lingue con scrittura da destra a sinistra.** L&#39;arabo e l&#39;ebraico richiedono `lang` e `dir="rtl"` sulla pagina, oltre a un layout speculare.
* **Motori di ricerca.** Un selettore che salva la scelta nello stato o in un cookie lascia tutte le lingue sullo stesso URL, mentre Google consiglia un URL per ogni lingua ([Gestire i siti multilingue](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites)). (Vedi [Come configuro la SEO per un&#39;app Next.js multilingue?](/kb/multilingual-nextjs-seo))
* **Le traduzioni.** Nessun helper elimina questo costo: qualcuno deve scrivere &quot;plików&quot; e tutte le altre stringhe in ogni lingua, e ricominciare ogni volta che il testo inglese cambia.

Quando l&#39;helper gestisce le categorie di plurale, i fallback e la formattazione dei numeri, hai di fatto scritto il nucleo di una libreria i18n, e le traduzioni ti mancano ancora.

## Cosa fa invece General Translation

General Translation conserva ciò che funziona dell&#39;approccio artigianale (testi leggibili e la formattazione nativa della piattaforma) e si occupa delle parti destinate a crescere. Con `gt-react` (o `gt-next` per Next.js), i testi restano nel componente, all&#39;interno di [`<T>`](/docs/react/reference/components/t), quindi non c&#39;è nessun dizionario né helper da mantenere:

```tsx title="Inbox.tsx"
import { T, Plural, Num, Var } from 'gt-react';

export function Inbox({ name, count }: { name: string; count: number }) {
  return (
    <T>
      <h1>Welcome back, <Var>{name}</Var></h1>
      <Plural
        n={count}
        singular={<p>You have <Num>{count}</Num> unread message.</p>}
        plural={<p>You have <Num>{count}</Num> unread messages.</p>}
      />
    </T>
  );
}
```

[`<Plural>`](/docs/react/reference/components/plural) sceglie un branch in base alle regole del plurale CLDR di ciascuna impostazione regionale, le stesse su cui si basa `Intl.PluralRules`, quindi non c&#39;è nessun `n === 1` da sbagliare. [`<Num>`](/docs/react/reference/components/num) formatta il conteggio secondo l&#39;impostazione regionale del lettore e il valore in [`<Var>`](/docs/react/reference/components/var) non viene mai inviato all&#39;API di General Translation. Ecco il componente renderizzato sul server con `gt-react` 11.4.12, con una traduzione spagnola inserita a mano nel template di [`gt generate`](/docs/cli/reference/commands/generate) a scopo illustrativo (senza i separatori di testo di React):

```html title="Output"
<!-- en, count = 12500 -->
<h1>Welcome back, Ana</h1><p>You have 12,500 unread messages.</p>
<!-- es, count = 12500 -->
<h1>Hola de nuevo, Ana</h1><p>Tienes 12.500 mensajes sin leer.</p>
```

Quando un&#39;impostazione regionale non ha una traduzione per un blocco, [`<T>`](/docs/react/reference/components/t) renderizza il contenuto di origine, non `undefined` né un errore.

La differenza più importante è che le traduzioni le produce General Translation:

* **Generate con il contesto.** [`npx gt translate`](/docs/cli/reference/commands/translate) invia ogni blocco [`<T>`](/docs/react/reference/components/t) con i relativi elementi, variabili, branch del plurale ed eventuali note di [`context`](/docs/react/reference/components/t#context), e scrive un file per ogni impostazione regionale. Un Glossario fissa la terminologia e i prompt personalizzati definiscono il tono in tutti i progetti che condividono un gruppo di contesto. (Vedi [Definire il contesto per le traduzioni](/docs/platform/dashboard/guides/defining-context-for-translations).)
* **Sempre sincronizzate.** Ogni esecuzione traduce i contenuti nuovi e modificati e riutilizza le traduzioni esistenti per il resto. Eseguilo in CI, oppure lascia che [Locadex](/docs/platform/locadex/quickstart), l&#39;agente IA di General Translation, apra pull request in base ai trigger che preferisci. Per le app Next.js e React, Locadex può anche racchiudere i testi esistenti in [`<T>`](/docs/react/reference/components/t).
* **Revisionate da persone.** Il tuo team modifica le traduzioni nella Dashboard. (Vedi [Revisionare e modificare le traduzioni](/docs/platform/dashboard/guides/reviewing-translations).)
* **Direzione e routing.** [`useLocaleDirection`](/docs/react/reference/hooks/use-locale-direction) restituisce `'rtl'` per l&#39;arabo e, tramite il suo [middleware](/docs/react/nextjs/app-router-middleware), `gt-next` può servire ogni impostazione regionale su un URL dedicato.

Le librerie JavaScript sono rilasciate con licenza MIT e funzionano senza un account General Translation se le traduzioni le fornisci tu. Un&#39;app configurata per caricare tutte le traduzioni dal proprio bundle non effettua alcuna chiamata a General Translation a runtime. Per generare le traduzioni, usa il servizio in hosting, con [prezzi basati sull&#39;utilizzo](https://generaltranslation.com/pricing).

All&#39;estremo opposto, Profound distribuisce la propria piattaforma e la propria documentazione in oltre 47 impostazioni regionali con General Translation. (Vedi [distribuzioni in produzione](https://generaltranslation.com/enterprise).)

## Soluzione fatta in casa, libreria o General Translation a confronto

|                               | Dizionario e helper fatti in casa                    | Libreria open source, come i18next                                                                     | General Translation                                                                                                                                                                     |
| ----------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Dipendenze                    | Nessuna                                              | La libreria più i binding per il framework, come `react-i18next`                                       | `gt-react` o `gt-next`, più la CLI `gt`                                                                                                                                                 |
| Plurali                       | Il tuo codice di selezione e ogni forma in ogni file | Selezione CLDR; le forme vengono fornite da persone o da un servizio di traduzione collegato           | [`<Plural>`](/docs/react/reference/components/plural) seleziona la forma con le regole CLDR; la traduzione genera le forme di ogni lingua di destinazione a partire dai branch che scrivi |
| Numeri, date, valute          | API `Intl` da chiamare manualmente                   | Formattatori integrati basati su `Intl`                                                                | [`<Num>`](/docs/react/reference/components/num), [`<Currency>`](/docs/react/reference/components/currency) e [`<DateTime>`](/docs/react/reference/components/datetime)                  |
| Traduzioni mancanti           | Dipende dal comportamento del tuo helper             | [Ripiega su una lingua configurata, poi mostra la chiave](https://www.i18next.com/principles/fallback) | Renderizza il contenuto di origine                                                                                                                                                      |
| Sincronizzazione delle lingue | A mano o con uno script tuo                          | Strumenti di estrazione e un servizio di traduzione da collegare                                       | Ogni esecuzione di [`npx gt translate`](/docs/cli/reference/commands/translate) traduce i contenuti nuovi e modificati                                                                  |
| Chi traduce                   | Persone o un servizio che integri                    | Persone o un servizio di traduzione collegato                                                          | L&#39;IA, con il contesto JSX contrassegnato, il Glossario e i prompt personalizzati; il tuo team revisiona le traduzioni nella dashboard                                               |
| Costo                         | Il tuo tempo e gli eventuali servizi che integri     | Libreria gratuita; la traduzione è a parte                                                             | Librerie JavaScript gratuite; [traduzione a consumo](https://generaltranslation.com/pricing)                                                                                            |

## Quando realizzarla da soli

Realizzala da solo quando supporti una o due lingue, i testi sono pochi e stabili, le tue lingue gestiscono il plurale come l&#39;inglese e le traduzioni le scrive un collega, oppure quando si tratta di un prototipo. Aggiungi una libreria open source come i18next quando ti servono regole del plurale e fallback e disponi già di traduttori o di un sistema di gestione delle traduzioni. Usa General Translation quando aggiungi più lingue, i testi cambiano a ogni rilascio o nessuno nel team dovrebbe occuparsi delle forme plurali del polacco: General Translation genera le traduzioni tenendo conto del contesto del tuo codice e mantiene aggiornata ogni lingua a ogni build. (Vedi [General Translation vs. i18next, react-intl e next-intl](/kb/general-translation-vs-i18n-libraries).)

## Mantieni il tuo dizionario e lascia che sia la CLI a tradurlo

Non serve riscrivere il tuo helper per smettere di tradurre a mano. Sposta i messaggi di ciascuna lingua in un file JSON (`locales/en.json`, `locales/es.json`), mantieni la tua `t()` e fai puntare `gt.config.json` a questi file tramite il segnaposto `[locale]`:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": [
    "es"
  ],
  "files": {
    "json": {
      "include": [
        "locales/[locale].json"
      ]
    }
  }
}
```

[`npx gt translate --dry-run`](/docs/cli/reference/commands/translate) indica `locales/en.json` come sorgente, mentre un&#39;esecuzione completa genera `locales/es.json`. In questo esempio i messaggi in inglese e in spagnolo hanno la stessa struttura di chiavi e segnaposto semplici come `{name}`. Un file associato `locales/en.metadata.json` permette di aggiungere contesto o limiti di caratteri per ogni chiave. Consulta [JSON](/docs/cli/reference/formats/json-files) e [Metadati associati alle chiavi](/docs/cli/reference/keyed-metadata). La ricerca delle chiavi e la selezione del plurale restano a carico del tuo helper: verificale entrambe sull&#39;output in spagnolo renderizzato.

Per abbandonare l&#39;helper, racchiudi un componente alla volta in [`<T>`](/docs/react/reference/components/t), oppure continua a usare le chiavi con [`useTranslations`](/docs/react/guides/translating-with-dictionaries). Se il lavoro è affidato a un agente di programmazione, forniscigli le [istruzioni per agenti](/docs/overview/for-coding-agents) di General Translation invece di chiedergli un helper `t()`. Inizia con l&#39;[Avvio rapido Next.js](/docs/react/nextjs-quickstart) o con la [Guida rapida per SPA React](/docs/react/react-spa-quickstart).

## Punti chiave

* Un dizionario, un helper `t()` e le API `Intl` integrate bastano per una o due lingue, pochi testi e plurali che funzionano come in inglese.
* Man mano che l&#39;app cresce, tocca a te gestire la selezione dei plurali, i fallback, la formattazione, la sincronizzazione dei file, il supporto right-to-left, gli URL per impostazione regionale e il processo con cui vengono prodotte le traduzioni.
* Le librerie di General Translation si occupano del lavoro a run-time, General Translation genera le traduzioni usando il tuo codice come contesto e, se scegli di mantenere un dizionario JSON scritto a mano, la CLI può tradurlo.

## Related questions

- [General Translation vs. i18next, react-intl e next-intl: quale libreria i18n scegliere?](https://generaltranslation.com/it/kb/general-translation-vs-i18n-libraries.mdx): Le librerie open source come i18next, react-intl e next-intl non traducono nulla. Si limitano a visualizzare le traduzioni che fornisci in un file di catalogo per ciascuna lingua, scritte da te, dai tuoi traduttori o da un servizio esterno. Anche le librerie di General Translation sono open source e svolgono lo stesso compito, ma General Translation si occupa anche della traduzione, usando il tuo codice come contesto.
- [Come si gestiscono i plurali in React?](https://generaltranslation.com/it/kb/how-to-handle-plurals-in-react.mdx): Non inserire la logica del plurale direttamente nel codice con controlli come n === 1. Per le app solo in inglese basta un semplice helper, ma le app multilingue richiedono regole del plurale locale-aware, che un componente i18n come `<Plural>` di gt-react o gt-next gestisce per ogni lingua.
- [Come si configura la SEO per un'app Next.js multilingue?](https://generaltranslation.com/it/kb/multilingual-nextjs-seo.mdx): Assegna a ogni lingua un URL dedicato, imposta l'attributo lang del tag html, fai puntare l'URL canonical di ogni pagina alla pagina stessa, aggiungi le alternative hreflang per ogni lingua, traduci titoli e descrizioni ed elenca tutte le versioni linguistiche nella sitemap.
- [Posso fare i18n senza file di traduzione?](https://generaltranslation.com/it/kb/i18n-without-translation-files.mdx): Sì. Con gt-react o gt-next, i contenuti restano inline nei tuoi componenti, all'interno di un componente `<T>`, e le traduzioni vengono generate come output in fase di compilazione. Non ci sono quindi chiavi né file JSON per ogni impostazione regionale da scrivere e mantenere sincronizzati.
- [Alternative a Google Translate: General Translation vs. Google Translate](https://generaltranslation.com/it/kb/general-translation-vs-google-translate.mdx): Google Translate è un modo rapido per tradurre testi occasionali, ma pubblicare un prodotto in un'altra lingua richiede anche che ogni stringa sia tradotta nel suo contesto, con termini coerenti, variabili e plurali corretti, una revisione e un processo di rilascio. General Translation comprende il contesto di ogni stringa nel tuo codice e automatizza l'intero flusso di lavoro di localizzazione, dal codice alla revisione fino a ogni rilascio.

## Previous and next questions

- Previous question: [Alternative a Transifex: General Translation vs. Transifex](https://generaltranslation.com/it/kb/general-translation-vs-transifex.mdx)
- Next question: [Cosa devo verificare prima di lanciare un'app multilingue?](https://generaltranslation.com/it/kb/multilingual-app-launch-checklist.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/it/kb/sitemap.md) for every article.
