I am bilingual and wanted my apps to be accessible in two languages. I had this idea during my first solo project at CodeClan. Wanted to define routes that lead users to different content pages, it would be so much unnecessary files and code. I came across SmashingMagazine article last week about using i18n in Vue app. When I heard about it before I got the impression that this amazing package translates websites for me. Well, not really but separates different language contantent in a definitely more elegant way that I was planning to do.
I18n stands for internationalization where 18 is a number of letters between i and n . (Hard to say if the shortcut or full word is a better tongue twister… ) It is a process of designing software that can be easily adapted to various languages without engineering changes.
Timi Omoyeni explained here detailed how to use it.
Simply run
vue add i18n
This will add some additional files to your folder tree .env, i18n.js, Helloi18n.vue and locales folder all to show how to use this package. Files in the locales folder (en.json, pl.json etc) are responsible for storing translation in simple JSON format. The key will be used in the code and automatically substituted with a proper value based on the chosen language.
pl.json:
1{2 "daysList": {3 "header": "Wybierz datę, aby zobaczyć szczegóły"4 },5 "dayDetails": {6 "description": "Opis:",7 "temperature": "Temperatura",8 "rain": "Deszcz",9 "sunrise": "Wschód Słońca",10 "sunset": "Zachód Słońca"11 },
en.json:
1{2 "daysList": {3 "header": "Select the date to see details",4 },5 "dayDetails": {6 "description": "Description:",7 "temperature": "Temperature",8 "rain": "Rain",9 "sunrise": "Sunrise",10 "sunset": "Sunset"11 },
To access it from vue component use $t function:
1<template lang="html">2<div>34<h2>{{ $t('daysList.header')}}</h2>5 <div class="select">
When locale is set to ‘en’ this will return “Select the date to see details” and when locale is set ‘pl’ "Wybierz datę, aby zobaczyć szczegóły"
Switching locale is a feature available for user who can change displayed language during any point of browsing the app. Ilya Bodrov-Krukowski explains here step by step shows how to create a new vue component LocaleSwitcher to allow users to select language.
This is enough to have static data available in two languages but I was facing other challenges:
a) for date formatting I am using Moment library
b) Incoming weather data is in English
Momentjs
Once you start to use Moment in JavaScript you don’t want to go back to an old way of dealing with date format. It is very simple to use and allows parsing, validating, manipulating and displaying date/time in a human readable way. By default moment formats data in English (‘Monday, 7 Sep 2020). I was over the moon when found in documentation that Moment supports i18n by moment.locale()
Great! But same as the group of developers on Stackoverflow I struggled to understand how to use it. Long walk, fresh yerba mate and figured out that need to create custom moment.locale(‘pl’) file:
1import { locale } from 'moment';2locale('pl', {3 monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),4 weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),5 weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'),6 weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),7 longDateFormat : {8 LT : 'HH:mm',9 LTS : 'HH:mm:ss',10 L : 'DD.MM.YYYY',11 LL : 'Do MMMM',12 LLL : 'D MMMM YYYY HH:mm',13 LLLL : 'dddd, D MMMM YYYY HH:mm'14 }15 });
And add
1this.moment.locale(locale);
To the LocaleSwitcher component in switchLocale method.
API response
At this point all parts of my app were translated apart from the weather description field that depends on API response. There was no way that I could add all possible translations to a pl.json file and with some logic manipulate it in this way. Luckily description includes maximum three words so should be easy to translate with help of external API. I found list of free/paid translation APIs
And started read their docs, creating accounts, hoping that won’t go over the 50 translated words per day limit (I reached it after 1 hour). And finally decided to go with Systrans translator. Set up a TextTranslator vue component, sending weather description text and getting a translated response back but… As you can imagine there are few ways of translating: “broken clouds” , “light shower”... I wasn’t happy with the result.
Another walk, fresh yerba mate.
There needed to be a more elegant way to translate this API… Went back to it’s documentation hoping that it supports other languages. Obviously DOES! About 30 other languages!
Solution was so easy- needed to manipulate fetch method a little:
1localeChange() {2 fetch(3 `https://api.weatherbit.io/v2.0/forecast/daily?city=${this.searchCity},4 UK&key=${key}&lang=${this.locale}`5 )6...
Here is my weather app available in two languages now.
https://weather-app-solo-project.netlify.app/