Come creare un’applicazione Angular Universal multilingua

In questo tutorial dedicato ad Angular Universal tratterò di come ho risolto il problema di internazionalizzazione, detta anche i18n, nella mia applicazione Angular Universal.

Se non conosci Angular Universal, si tratta di una piattaforma che rende la tua applicazione Angular in grado di erogare pagine pre-renderizzate ad utenti e crawler web mentre l’app lato client viene caricata in background.

Una volta che tutto è pronto lato client, passerà senza problemi dalla visualizzazione delle pagine pre-renderizzate dal server alla normale app lato client.

Molti tutorial reperibili online discutono su come convertire la tua applicazione in Angular Universal, in questo cercheremo di fare un passo avanti e vedremo come creare un’applicazione Angular Universal con supporto multilingua.

Realizzeremo l’internazionalizzazione i18n usando gli angular cli tools e facendo alcune modifiche all’ Angular Universal express server, il tutorial si basa su 3 passaggi:

  1. Aggiungere il supporto i18n alla nostra app;
  2. Personalizzare il processo di build per ogni app tradotta;
  3. Modificare i server Express per gestire le lingue.

Repository di riferimento

Un esempio funzionante del progetto Angular Universal che useremo come riferimento è disponibile su:https://github.com/mzuccaroli/universal-multisite-multilanguage,  si tratta di un semplice progetto Angular 7 creato per scopi dimostrativi.

Si basa sull’ angular universal starter, per maggiori informazioni vedere: https://github.com/angular/universal- starter.

Aggiungere il supporto i18n alla nostra app

Questo passaggio imposterà l’ambiente i18n per le traduzioni di supporto nella tua app, esegui:

$npm install ngx-i18nsupport -s

Ora è possibile aggiungere la proprietà i18n nei tag html come ad esempio:

<h3 i18n>Hello interlanguage!</h3>

Per ottenere rispettivamente questi html per inglese e italiano:

<h3>Hello!</h3>
<h3>Ciao!</h3>

Ora vogliamo rendere automatico il processo di generazione dei file .xlf, aggiungiamo questa configurazione al nostro package.json

Basta aggiungere alla nostra sezione script:

"extract-i18n": "ng xi18n --output-path locale && node ./node_modules/ngx-i18nsupport/dist/xliffmerge/xliffmerge"

Ora è possibile eseguire il comando:

$npm run extract-i18n

Tutti i file html verranno analizzati e i file di traduzione (messages.xlf, messages.en.xlf, messages.fr.xlf, messages.fr.xlf) verranno generati nella cartella “locale”.

Ora è possibile modificare i file xlf e inserire le tue traduzioni.

Da notare è che questa generazione di chiavi è incrementale e, quando nuovi tag i18n verranno aggiunti al nostro html, l’esecuzione dello script aggiornerà in maniera automatica i file di traduzione senza modificare i testi già tradotti.

Personalizzare il processo di build 

Nota: questo passaggio si basa sul file angular.json supportato dalle versioni Angular 6+.

Diamo un’occhiata al file angular.json collocato nella radice del progetto, andiamo alla sezione projects.yourProjectName.architect.build.configurations : qui possiamo aggiungere altre configurazioni per eseguire build specifiche per lingua, ad esempio per creare una configurazione per l’inglese è possibile modificare outputPath in:

“outputPath”: “dist/browser/en/”

Ed aggiungere in fondo alla configurazione

"baseHref": "/en/",
"i18nFile": "src/locale/messages.en.xlf",
"i18nFormat": "xlf",
i18nLocale": "en",
i18nMissingTranslation": "error"

Nella sezione fileReplacements è possibile gestire un ambiente .env specifico per ogni applicazione tradotta, se necessario.

Una buona idea è quella di aggiungere un’altra veloce configurazione per  il develop target e gestire un ambiente dedicato allo sviluppo.

Il risultato finale per un’applicazione in inglese italiano e francese con un ambiente specifico di sviluppo dovrebbe essere:

Il json diventerà piuttosto grande ma avremo il pieno controllo delle nostre build e le nostre applicazioni finali saranno totalmente indipendenti e ottimizzate per la lingua, potremmo rilasciare un’app specifica per la lingua in un server/bucket/cdn dedicato senza problemi.

Ora dobbiamo aggiungere uno script al nostro package.json per eseguire le build delle singole lingue:

Su package.json nella sezione “script” aggiungere:

"build:language-bundles": "ng run ng-universal-demo:build:production-it && ng run ng-universal-demo:build:production-en && ng run ng-universal-demo:build:production-fr",

Poi modificare lo script build:client-and-server-bundles per creare tutte le applicazioni tradotte durante la build:

"build:client-and-server-bundles": "npm run build:language-bundles && ng run ng-universal-demo:server:production",

Ora è possibile eseguire il tuo comando build:ssr e vedere la cartella “dist” con dentro le tre applicazioni.

Modificare il server Express

Per erogare l’applicazione Universal è necessario modificare il server Express e renderlo in grado di gestire le diverse lingue.

Con questa soluzione il server identificherà le lingue supportate e passerà la lingua selezionata e l’ip della richiesta all’applicazione, è possibile utilizzare l’ip del client in servizi esterni (es: https://www.maxmind.com) per identificare il paese dell’utente dal suo IP e selezionare la lingua più appropriata.

In server.ts e trova la parte “regular routes”:

Cambiandola con:

Ora il server riconoscerà la lingua dal path e se corrisponde alle lingue supportate erogherà questa applicazione specifica, altrimenti erogherà l’applicazione “defaultlocale”.

Da notare che la lingua verrà iniettata dal server e potrebbe essere utilizzata dall’applicazione utilizzando:

@Inject(LOCALE_ID) public locale: string

Allo stesso modo è possibile rilevare l’ip utente, recuperare le impostazioni internazionali da un servizio esterno ed erogare la sua applicazione specifica per la lingua.

Questo è un esempio che rileva l’ip utente e lo inietta.

Diamo un’occhiata al risultato finale:

Inglese
Italiano
Francese

Leave a Reply