I need to build an app in English, French, and Polish, that's why I want to install and configure these three languages in my Svelte app.
I created my app and I installed also the tests
I will use svelte-i18n
npm i svelte-i18n
It's time to configure this package. The file main.js before configuration is like this:
import './app.css'
import App from './App.svelte'
const app = new App({
target: document.getElementById('app')
})
export default app
now I add a svelte-i18n import:
import './app.css'
import App from './App.svelte'
import { addMessages, init } from 'svelte-i18n'
addMessages('en', {
hello: 'Hello word!'
}) // this is my key that I will use after in my App page.
init({
initialLocale: 'en',
fallbackLocale: 'en'
}); // here I inicialise and configure a local language
const app = new App({
target: document.getElementById('app')
})
export default app
Now I import i18n to App.svelte like this:
<script>
import { _ } from 'svelte-i18n'
</script>
<main>
<h1>{$_('hello')}</h1>
</main>
In a browser, it works very well but tests failed. I'll take care of it later. For the moment I add another language in main.js:
import './app.css'
import App from './App.svelte'
import { addMessages, init } from 'svelte-i18n'
addMessages('en', {
hello: 'Hello word!'
})
addMessages('fr', {
hello: 'Salut tout le monde!'
})
addMessages('pl', {
hello: 'Witajcie w naszej bajce!'
})
init({
initialLocale: 'fr',
fallbackLocale: 'en'
});
const app = new App({
target: document.getElementById('app')
})
export default app
So when you change a local language your text in a browser will change also.
As I mentioned the tests are broken so I will fix them.
In the first place, I create a folder locale in folder src
mkdir locale
cd locale
touch i18n.js
from main.js I cut this part of code:
import { addMessages, init } from 'svelte-i18n'
addMessages('en', {
hello: 'Hello word!'
})
addMessages('fr', {
hello: 'Salut tout le monde!'
})
addMessages('pl', {
hello: 'Witajcie w naszej bajce!'
})
init({
initialLocale: 'fr',
fallbackLocale: 'en'
});
to paste it to i18n.js and I import this file in main.js:
import './locale/i18n'
The translation works in the browser.
I import this file also to the App.spec.js file:
import '../src/locale/i18n'
and tests are green when the local language is English.
To have all languages in the same file so I create a JSON file for each language:
and in i18n.js I import all these files:
import { addMessages, init } from 'svelte-i18n';
import en from './en.json';
import fr from './fr.json';
import pl from './pl.json';
addMessages('en', en)
addMessages('fr', fr)
addMessages('pl', pl)
init({
initialLocale: 'en',
fallbackLocale: 'en'
});
Now I test if traduction is well displayed
App.spec.js:
/**
* @jest-environment jsdom
*/
import App from "../src/App.svelte";
import { render, screen } from "@testing-library/svelte";
import '../src/locale/i18n'
import en from '../src/locale/en.json' //here I import a json files
import fr from '../src/locale/fr.json'
import pl from '../src/locale/pl.json'
// I modify a little bit a teste by adding description tag
describe("App Page", () =>{
describe("Layout", () =>{
it("has Hello header", () =>{
render(App);
const header = screen.getAllByText("Hello word!");
expect(header).toBeTruthy()
});
});
describe("i18n", () =>{
it("displays text in English", () =>{
render(App);
expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument; /here I use from json file key and its value
});
it("displays text in French", () =>{
render(App);
expect(screen.queryByRole('heading', {level: 1, name: fr.hello})).toBeInDocument;
});
it("displays text in Polish", () =>{
render(App);
expect(screen.queryByRole('heading', {level: 1, name: pl.hello})).toBeInDocument;
});
})
})
For a moment all is by default but I want to change languages so I need to create a little button to toggle between languages.
In tests I add those 2 tests:
it("displays text in French after clic a FR btn", async () =>{
render(App);
const frBtn = screen.getByText('FR');
await userEvent.click(frBtn);
expect(screen.queryByRole('heading', {level: 1, name: fr.hello})).toBeInDocument;
});
it("displays text in Polish after clic a PL btn", async () =>{
render(App);
const plBtn = screen.getByText('PL');
await userEvent.click(plBtn);
expect(screen.queryByRole('heading', {level: 1, name: pl.hello})).toBeInDocument;
});
Those tests are correct but it doesn't work because I need to import user event from the library that I installed before.
import userEvent from '@testing-library/user-event'
Now the tests are broken because in App.svelte I don't have any element to click. So I create 3 languages elements and I add on:click to them. I need also to import a local from i18n. Now App.svelte is like this:
<script>
import { _, locale } from 'svelte-i18n'
</script>
<main>
<h1>{$_('hello')}</h1>
<span on:click = {() => locale.set("en")}>EN</span>
<span on:click = {() => locale.set("fr")}>FR</span>
<span on:click = {() => locale.set("pl")} >PL</span>
</main>
Now all works but I need to know if the EN button works also good than others so I create one more test:
it("displays text in English after click from PL btn", async() =>{
render(App);
const plBtn = screen.getByText('PL');
await userEvent.click(plBtn);
const enBtn = screen.getByText('EN');
await userEvent.click(enBtn);
expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument;
});
so all App.spec.js is like this:
/**
* @jest-environment jsdom
*/
import App from "../src/App.svelte";
import { render, screen } from "@testing-library/svelte";
import userEvent from '@testing-library/user-event'
import '../src/locale/i18n'
import en from '../src/locale/en.json'
import fr from '../src/locale/fr.json'
import pl from '../src/locale/pl.json'
describe("App Page", () =>{
describe("Layout", () =>{
it("has Hello header", () =>{
render(App);
const header = screen.getAllByText("Hello word!");
expect(header).toBeTruthy()
});
});
describe("i18n", () =>{
it("displays text in English by default", () =>{
render(App);
expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument;
});
it("displays text in French after clic a FR btn", async () =>{
render(App);
const frBtn = screen.getByText('FR');
await userEvent.click(frBtn);
expect(screen.queryByRole('heading', {level: 1, name: fr.hello})).toBeInDocument;
});
it("displays text in Polish after clic a PL btn", async () =>{
render(App);
const plBtn = screen.getByText('PL');
await userEvent.click(plBtn);
expect(screen.queryByRole('heading', {level: 1, name: pl.hello})).toBeInDocument;
});
it("displays text in English after click from PL btn", async() =>{
render(App);
const plBtn = screen.getByText('PL');
await userEvent.click(plBtn);
const enBtn = screen.getByText('EN');
await userEvent.click(enBtn);
expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument;
});
})
})
When I run the tests all is green.
Top comments (0)