net - change title angular 4
Angular Universal con i18n(representación del lado del servidor) (1)
Una solución es precompilar paquetes para cada idioma y hacer que un proxy detecte qué paquete servir como predeterminado.
De los documentos angulares en i8n :
Fusionar con el compilador AOT El compilador AOT (Ahead-of-Time) es parte de un proceso de compilación que produce un paquete de aplicaciones pequeño, rápido y listo para ejecutarse.
Cuando se internacionaliza con el compilador AOT, debe precompilar un paquete de aplicaciones separado para cada idioma y servir el paquete apropiado en función de la detección del lenguaje del lado del servidor o de los parámetros de url.
También debe indicar al compilador de AOT que use su archivo de traducción. Para hacerlo, usa tres opciones con los comandos ng serve o ng build:
--i18nFile: la ruta al archivo de traducción. --i18nFormat: el formato del archivo de traducción. --locale: la id de configuración regional. El siguiente ejemplo muestra cómo servir el archivo de idioma francés creado en secciones anteriores de esta guía:
ng build --aot --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr
Intento utilizar las herramientas de internacionalización oficiales de Angular con angular universal. Hasta ahora soy capaz de traducir la representación del lado del cliente utilizando el siguiente procedimiento (gracias a esta respuesta https://stackoverflow.com/a/40930110/1110635 ):
Añado atributos "i18n" como se indica en la documentación en mis plantillas:
./src/+app/about/about.component.html:
<h1 i18n="H1 of the about component">About</h1>
...
Luego corro:
./node_modules/.bin/ng-xi18n
para generar el archivo base messages.xlf .
Luego copio este archivo para cada configuración regional que deseo admitir como " mensajes. [Configuración regional] .xlf " en una carpeta "configuración regional". Cuando esté listo, creo un " messages. [Locale] .ts " para cada archivo xlf que contenga una cadena exportada de su contenido:
./locale/messages.fr.ts:
// TRANSLATION_FR is only for "messages.fr.ts" of course.
// I would create a TRANSLATION_ES const inside "messages.es.ts" for spanish for example.
export const TRANSLATION_FR: string = `<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
<source>About</source>
<target>A propos</target>
<note priority="1" from="description">H1 of the about component</note>
</trans-unit>
</body>
</file>
</xliff>
`;
Finalmente, mi archivo client.ts se ve así:
./src/client.ts:
[...]
// i18n
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from ''@angular/core'';
import { TRANSLATION_FR } from ''../locale/messages.fr'';
import { MainModule } from ''./browser.module'';
export const platformRef = platformUniversalDynamic();
// on document ready bootstrap Angular 2
export function main() {
return platformRef.bootstrapModule(MainModule, {
providers: [
{provide: TRANSLATIONS, useValue: TRANSLATION_FR},
{provide: TRANSLATIONS_FORMAT, useValue: "xlf"},
{provide: LOCALE_ID, useValue: ''fr''}
]
});
}
bootloader(main);
Esto funciona y hace que la aplicación "del lado del cliente" funcione como se espera. " Acerca de " se reemplaza por " A propos ". PERO , debido a que angular universal preproduce la página en el lado del servidor utilizando express, el texto no se traduce hasta que se realiza el bootstraping del lado del cliente.
Por lo tanto, cuando va por primera vez a la página, ve " Acerca de " durante aproximadamente 1 segundo antes de que el lado del cliente lance y la reemplace con " A propos ".
La solución parece obvia, simplemente ejecute el servicio de traducción del lado del servidor. Pero no tengo idea de cómo hacer eso.
Mi server.ts se ve así:
./src/server.ts
[...]
// i18n
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from ''@angular/core'';
import { TRANSLATION_FR } from ''../locale/messages.fr'';
const app = express();
const ROOT = path.join(path.resolve(__dirname, ''..'', ''dist''));
// Express View
app.engine(''.html'', createEngine({
ngModule: MainModule,
providers: [
/**
* HERE IS THE IMPORTANT PART.
* I tried to declare providers but it has no effect.
*/
{provide: TRANSLATIONS, useValue: TRANSLATION_FR},
{provide: TRANSLATIONS_FORMAT, useValue: "xlf"},
{provide: LOCALE_ID, useValue: ''fr''}
]
}));
app.set(''port'', process.env.PORT || 3000);
app.set(''views'', ROOT);
app.set(''view engine'', ''html'');
[...]
function ngApp(req, res) {
res.render(''index'', {
req,
res,
preboot: false,
baseUrl: ''/'',
requestUrl: req.originalUrl,
originUrl: `http://localhost:${ app.get(''port'') }`
});
}
app.get(''*'', ngApp);
// Server
let server = app.listen(app.get(''port''), () => {
console.log(`Listening on: http://localhost:${server.address().port}`);
});
No tengo acceso directo al método bootstrapModule como en el lado del cliente. La clave de proveedores en el objeto de parámetro " createEngine " ya estaba allí en el código server.ts original .
¿Qué me estoy perdiendo?