migrating to Sapper part 4 - i18n with Sapper

Today you will see how to add multiple language support to a Sapper blog like this one.

This article is part of a series of posts about migrating from GatsbyJS/React to Sapper/Svelte. You can check the other posts: part 1, part 2, part 2 bis, part 3, and more to come!


Prototype & reusability

All of this is a remix of some E2E test stubbing done at work and reusing the multi-language button and i18n store from my existing Cooking Contest Svelte app’s code.

The idea was to lay the ground to writing and translating my blog posts to my main language: French.

Test Driven

As I’m still trying to maintain the TDD discipline, I first added E2E tests to express my requirements in an executable form.

You can look at them in the /cypress/integration/i18n.js file.


When writing these tests, I stumbled upon some subtleties for which I had to call for help on twitter:

Thanks to Gleb Bahmutov, I was able to use an old article of his to solve this issue. I cannot thank him enough for that!

So the general idea is to stub the navigator.language property which you cannot do easily because it is read-only. So you should read his post, I won’t repeat it here.

Switch Language Button

I added a Language button, which should be on this page almost at the top-right corner.

If you click on it, some labels will switch to the other supported language of this blog: either French or English, for now.

I18N Svelte Store

I used the simple and awesome Svelte Stores which you can get a hand on on Svelte’s tutorial.

ES6 Tagged Template Literals

At first, in Cooking Contest, I used a simple array/dictionnary notation to retrieve the label values, and you could use {i18n['key']} in your HTML .svelte templates.

This time, I introduced a way to remove 2 characters πŸ’ͺ😎 by using Tagged Template Literals from ES6 (EcmaScript 6).

Don’t worry, this JavaScript feature is already well supported.

So instead of writing the above, we can now use: {i18n`key`} which removes the brackets and use back-ticks instead of simple quotes.

Auto-detection of the language

In Lang.svelte, we use:

  onMount(() => {

in order to get the β€˜fr’ or β€˜en’ part of the language of the browser. It might produce a quick flash, though.

Store resetting when I navigate

For now, if you change the language, it is not persisted and if you navigate to another page, it will revert to the current browser’s language because of the above onMount.

I will solve this issue later and update this post.


Well, that was fast. in the future, expect some content in the πŸ‡«πŸ‡· French language!

In this 4th post about migrating my previous blog from GatsbyJS/React to Sapper/Svelte, we have seen how to add i18n to the website, this time succeeding in writing tests first!

It was a short post because it was really easy to implement. I hope you found it interesting!

If you have any questions about TDD, Cypress, Svelte, Sapper, or just want to say hi or thank you, my DMs are open on Twitter!