Configuración

Ejemplo de configuración

Éste es el ejemplo más básico de la inicialización de la librería. Copia esto en tu src/__layout.svelte .

  
import { addMessages, init } from 'svelte-intl-precompile'; import en from '$locales/en'; import es from '$locales/es'; addMessages('en', en); addMessages('es', es); init({ initialLocale: 'en', fallbackLocale: 'en' });

Ésto es suficiente para ir empezando pero vamos a profundizar más en todas las opciones que tienes.

Añadir idiomas estáticamente

Como en el ejemplo anterior, la manera más sencilla de añadir entradas al diccionario es simplemente importar el módulo que contiene las traducciones y añadirlas usando addMessages(langCode, translations).

  
import en from '$locales/en'; import es from '$locales/es'; addMessages('en', en); addMessages('es', es);

Observa que a pesar de que definiste tus traducciones en un fichero JSON aquí las estamos importando como si fuesen módulos ES6 situados en $locales . Esto es porque la librería ha transformado las traduccions en un módulo con funciones durante la compilación.

Esta estrategia está cargando todos esos idiomas incluso si solamente uno va a acabar siendo mostrado. Esto no suele ser un problema cuando estás comenzando el desarollo de un nuevo proyecto o si tu proyecto tiene pocas traducciones o pocos idiomas, pero cuando tu aplicación empieza a crecer debería empezar a cargar los paquetes de traducciones bajo demanda.

Añadir idiomas dinámicamente

Una ver tienes una cantidad significativa de traducciones en varios idiomas sería muy ineficiente cargar todos ellos para cada usuario cuando solamente va a utilizar el que haya seleccionado. La librería tiene una función register(langCode, callback) para dinámicamente importar idiomas cuando el usuario lo seleccione y otra función waitLocale(locale = defaultLocale) para esperar a que la carga haya finalizado.

Si todos tus idiomas se cargan dinámicamente debes impedir que la app prosiga el renderizado hasta que el idioma inicial haya sido cargado. Devolviendo el resultado de invocarla desde la función load proporcionada por SvelteKit hará exactamente eso.

  
import { init, register, waitLocale } from 'svelte-intl-precompile'; register('en', () => import('$locales/en')); register('es', () => import('$locales/es')); export async function load() { init({ initialLocale: en }); await waitLocale(); // awaits the default locale, "en" in this case. }

Añadir idiomas dinámicamente (pero más rápido esta vez)

Si tan solo quieres registar todos los idiomas disponibles (es decir, todos aquellos para los cuales tienes un fichero JSON con traducciones) automáticamente, hay un atajo muy práctico para lograrlo. La carpeta $locales de donde importas las traducciones funciona también como un módulo de donde puedes importar dos utilidades: registerAll y availableLocales.

La primera es una función que cuando se invoca equivale a llamar register(langCode, callback) para cada uno de los idiomas.
La segunda es un array con los códigos ISO de los idiomas diponibles (tanto si los has registrado o todavía no), para que tengas esa información disponible si necesitas utilizarla.

  
import { init, waitLocale } from 'svelte-intl-precompile'; import { registerAll, availableLocales } from '$locales'; registerAll(); export async function load() { init({ initialLocale: selectBestMatchingLocale(availableLocales) }); await waitLocale(); }

Idiomas inicial y de rescate

A la invocación init(libOptions) las opciones más importantes son initialLocale y fallbackLocale. La primera determina el idioma en el que la app va a ser renderizada inicialmente y el segundo el idioma que se usará como última opción cuando una entrada no se encuentre en el diccionario del idioma actual.

  
init({ initialLocale: 'es', fallbackLocale: 'en' });

Hay muchas cosas que se pueden hacer para lograr la experiencia de usuario perfecta, como convenientemente inicializar initialLocale al idioma seleccionado por el usuario durante el registro si ha hecho login, obtenerlo de las cookies si ya ha visitado la página anteriormente o obtenerlo de las cabecera

Accept-Language
de la petición HTTP cuando renderizando en el servidor, pero la más sencilla es detectar el idioma del navegador o de la URL con las utilidades proporcionadas para ello.

Encontar el mejor idioma

Hay múltiples estrategias válidas para seleccionar el mejor idioma para pasar a la función init() . Esta librería proporciona utilidades para las estrategias más comunes:

getLocaleFromNavigator()
Extrae el idioma del navegador, que a su vez es el idioma del sistema operativo.
getLocaleFromQueryString(key)
Extrae el idioma en el parámetro dado de la query string de la URL.
P.e
getLocaleFromQueryString('lang')
para
/users?sort=name&dir=asc&lang=es
getLocaleFromHash(key)
Como
getLocaleFromQueryString
pero para el hash de la URL.
P.e
getLocaleFromHash('lang')
para
/users#sort=name&dir=asc&lang=es
getLocaleFromPathname(regex)
Extrae el idioma de los segmentos de la URL.
P.e
getLocaleFromPathname(/^/((es|en)(-\w\w)?)/)
para
myapp.com/en-US/users
getLocaleFromHostname(regex)
Extrae el idioma del host.
P.e
getLocaleFromHostname(/^((es|en)(-\w\w)?)\./)
para
https://pt.myapp.com
getLocaleFromAcceptLanguageHeader(header, availableLocales?)
Extracts the locale from the Accept-Language header based on a list of available locales. If availableLocales is omitted, returns the first language from the header.
E.g.
getLocaleFromAcceptLanguageHeader('en-GB,en;q=0.9,es-ES;q=0.8,en-US;q=0.6', ['fr', 'es', 'de'])
for
'es'

Formatos personalizados

Esta librería puede formatear números, fechas y horas. Lo hace sin añadir un tamaño significativo a tu proyecto porque utiliza la API Intl ya presente en todos los navegadores modernos y en Node.js.
Por defecto tu app puede usar estos formatos pero puedes añadir los tuyos propios.

  
{ number: { scientific: { notation: 'scientific' } engineering: { notation: 'engineering' } compactLong: { notation: 'compact', compactDisplay: 'long' } compactShort: { notation: 'compact', compactDisplay: 'short' } }, date: { short: { month: 'numeric', day: 'numeric', year: '2-digit' } medium: { month: 'short', day: 'numeric', year: 'numeric' } long: { month: 'long', day: 'numeric', year: 'numeric' } full: { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' } }, time: { short: { hour: 'numeric', minute: 'numeric' } medium: { hour: 'numeric', minute: 'numeric', second: 'numeric' } long: { hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'short' } full: { hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'short' } } }

Si quieres definir tus propios formatos pásalos al incializar la librería usando la opción formats , los cuales será añadidos a los formatos por defecto listados arriba. Los formatos deben ser objetos válidos para pasar a Intl.DateTimeFormat.

  
init({ fallbackLocale: 'en', initialLocale: 'en', formats: { date: { abbreviated: { weekday: 'long', month: 'short', day: 'numeric' } }, time: { 'just-hour': { hour: 'numeric' } } } });

For numbers specifically you can register your own formats like that or you can use Number Skeletons as a more flexible way of customizing every single aspect of how numbers are rendered. Check the crash course here