Indietro

Smetti di racchiudere le stringhe nelle chiamate di funzione

Ernest McCarter avatarErnest McCarter
gt-reacti18ntagged-templatemacrodeveloper-experience

Il problema con t("Hello, {name}", { name })

Se hai mai internazionalizzato un'app React, avrai scritto qualcosa di simile:

const gt = useGT();

return <p>{gt("Hello, {name}! You have {count} items.", { name, count })}</p>;

Funziona. Ma è macchinoso. Stai scrivendo a mano la sintassi di ICU MessageFormat, duplicando ogni nome di variabile nell'oggetto dei parametri e recuperando t da un Hook che richiede il contesto React. Per qualcosa che dovrebbe essere solo un sottile livello sopra le stringhe esistenti, c'è fin troppo codice accessorio.

E c'è di peggio. Nel momento in cui ti serve una traduzione al di fuori di un componente React — in una funzione di utilità, in un gestore di eventi, in un'azione server — devi ricorrere a soluzioni alternative, perché lì gli Hook non funzionano.

Le template literal dovrebbero funzionare senza problemi

Ecco come appare lo stesso codice con la macro t:

import { t } from "gt-react/browser";

return <p>{t`Hello, ${name}! You have ${count} items.`}</p>;

Ecco tutto. La sintassi standard dei template literal di JavaScript. Nessun placeholder ICU, nessun oggetto parametri, nessun Hook, nessun provider di contesto. Scrivi la stringa come scriveresti qualsiasi template literal, e il compilatore fa il resto.

In fase di build, il compilatore GT trasforma:

t`Hello, ${name}!`

in:

t("Hello, {0}!", { "0": name })

Il tagged template literal è puro zucchero sintattico: il comportamento in runtime è identico a quello di una chiamata a t() con una stringa. Ma l'esperienza di sviluppo è nettamente migliore.

Niente più dipendenza dal contesto React

Il cambiamento più significativo qui non riguarda la sintassi, ma l'architettura. La funzione t esportata da gt-react/browser non usa il contesto React. Non ha bisogno di un Hook. Non deve essere chiamata all'interno di un componente.

Questo significa che puoi usare t in:

  • Gestori di eventi: onClick={() => alert(tSaved!)}
  • Funzioni di utilità: function formatError(code) { return tError: $ }
  • Costanti e configurazione: const LABELS = { save: tSave, cancel: tCancel }
  • Ovunque JavaScript venga eseguito sul client

Il vecchio pattern — useGT() che restituisce una funzione vincolata al contesto React — era un collo di bottiglia. Costringeva a trattare la traduzione come una responsabilità di React, quando in realtà è una questione di stringhe.

Registrazione globale

Se non vuoi importare t in ogni file, puoi registrarlo a livello globale:

// Nel punto di ingresso della tua app
import "gt-react/macros";

Questo imposta globalThis.t, rendendo il tagged template literal disponibile ovunque senza bisogno di importarlo. Il compilatore è abbastanza intelligente da rilevarlo: se t è già importato da una sorgente GT, non aggiungerà un import duplicato. Se invece non lo è e hai usato t come tagged template literal, il compilatore aggiunge l'import per te.

Funziona anche la concatenazione

L'espansione della macro non si limita ai tagged template literal. Gestisce anche i template literal passati come argomenti e la concatenazione di stringhe:

// Template literal come argomento — anche questo viene trasformato
t(`Welcome back, ${user}`)

// Concatenazione di stringhe — anche questa viene trasformata
t("Hello, " + name + "! Welcome.")

Entrambi vengono ricondotti alla stessa chiamata t("...", { ... }) in fase di build.

Per iniziare

1. Installa l'ultima versione di gt-react

npm install gt-react@latest

2. Usa la macro t

Importala direttamente:

import { t } from "gt-react/browser";

export function Greeting({ name }) {
  return <p>{t`Hello, ${name}!`}</p>;
}

Oppure registralo globalmente ed evita le importazioni:

// app/layout.tsx o punto di ingresso
import "gt-react/macros";
// Ovunque nella tua app
export function Greeting({ name }) {
  return <p>{t`Hello, ${name}!`}</p>;
}

3. È tutto qui

Il compilatore GT gestisce automaticamente la trasformazione in fase di build. Non è necessaria alcuna configurazione aggiuntiva: l'espansione delle macro è abilitata per impostazione predefinita.


La macro t introduce una piccola modifica all'API, ma riflette un cambiamento più ampio: le traduzioni dovrebbero risultare naturali in JavaScript, non sembrare una scappatoia specifica del framework. Scrivi le stringhe in modo naturale. Al resto pensa la toolchain.