Creating a Multi-Language Website with SvelteKit
If you want to share your content in multiple languages on your website, it’s far easier to do this with SvelteKit. sveltekit-i18n
package will handle all the setup for your multi-language website easily.
What is i18n?
i18n (internationalization) is a concept that has been used since the early days of HTML and has evolved with various improvements till nowadays. This concept allows web pages to be displayed in different languages. As a result, web pages become more understandable, reachable and usable for users in different languages.
SvelteKit with i18n
First of all, let’s add the sveltekit-i18n
package to our project. This package will convert our project into a multi-language website by creating its own configuration files.
npm i sveltekit-i18n
Translations Folder
translations
folder will keep the translations of the languages that our project supports.
Let’s create a lang.json
for the languages we will include and keep the names and codes of them.
{
"en": "English",
"tr": "Türkçe"
}
In the translations
folder, let’s create an index.js
file that will save the configurations for the sveltekit-i18n
package.
import i18n from 'sveltekit-i18n';
import { dev } from '$app/environment';
import lang from './lang.json';
export const defaultLocale = 'en';
/** @type {import('sveltekit-i18n').Config} */
export const config = {
log: {
level: dev ? 'warn' : 'error',
},
translations: {
en: { lang },
tr: { lang },
},
loaders: [
{
locale: 'en',
key: 'menu',
loader: async () => (await import('./en/menu.json')).default,
},
{
locale: 'en',
key: 'about',
routes: ['/about'],
loader: async () => (await import('./en/about.json')).default,
},
{
locale: 'en',
key: 'home',
routes: ['/'],
loader: async () => (await import('./en/home.json')).default,
},
{
locale: 'tr',
key: 'menu',
loader: async () => (await import('./tr/menu.json')).default,
},
{
locale: 'tr',
key: 'about',
routes: ['/about'],
loader: async () => (await import('./tr/about.json')).default,
},
{
locale: 'tr',
key: 'home',
routes: ['/'],
loader: async () => (await import('./tr/home.json')).default,
},
],
};
export const { t, loading, locales, locale, translations, loadTranslations, addTranslations, setLocale, setRoute } = new i18n(config);
loading.subscribe(($loading) => $loading && console.log('Loading translations...'));
Here, we point out which languages will be supported, where the translations will be kept, and on which pages the translations will be used.
## Translation Files
Create en and tr folders and add our translation files to them.
about.json (about page){
"title": "Bu uygulama hakkında",
"text": "<p>Bu bir <a href="https://kit.svelte.dev">SvelteKit</a> uygulamasıdır. Aşağıdaki komutu komut satırına girerek kendi uygulamanızı oluşturabilirsiniz:</p><pre>npm init svelte@next</pre> <p> Bu sayfa tamamen statik HTML'dir ve istemci etkileşimi gerektirmez. Bu nedenle herhangi bir JavaScript yüklemeye gerek yoktur. Sayfanın kaynak kodunu görüntülemeyi veya geliştirici araçlarını açıp sayfayı yeniden yüklemeyi deneyin.</p>"
}
home.json (homepage) {
"title": "SvelteKit'e Hoş Geldiniz",
"text": "Dokümantasyona <a href="{{link}}">kit.svelte.dev</a> adresinden ulaşabilirsiniz."
}
menu.json (menu) {
"home": "Ana Sayfa",
"about": "Hakkımızda"
}
about.json (about page) {
"title": "About this app",
"text": "<p>This is a <a href="https://kit.svelte.dev">SvelteKit</a> app. You can make your own by typing the following into your command line and following the prompts:</p><pre>npm init svelte@next</pre> <p> The page you're looking at is purely static HTML, with no client-side interactivity needed. Because of that, we don't need to load any JavaScript. Try viewing the page's source, or opening the devtools network panel and reloading. </p>"
}
home.json (home page) {
"title": "Welcome to SvelteKit",
"text": "Visit <a href="{{link}}">kit.svelte.dev</a> to read the documentation"
}
menu.json (menu) {
"home": "Home",
"about": "About"
}
Storing Locale in Cookie
We’ll use cookies to store the user’s language preference. We can also do this without storing it in the browser cookie, for instance, by getting the language information from the URL. But in this post, we’ll store the user’s preference via cookies.
SvelteKit’s server-side features will be beneficial for this. Let’s create a +layout.server.js
file under the src/routes
folder.
import { locales, loadTranslations, translations, defaultLocale } from '$lib/translations';
/** @type {import('@sveltejs/kit').ServerLoad} */
export const load = async ({ url, cookies, request }) => {
const { pathname } = url;
// Try to get the locale from cookie
let locale = (cookies.get('lang') || '').toLowerCase();
// Get user preferred locale
if (!locale) {
locale = `${`${request.headers.get('accept-language')}`.match(/[a-zA-Z]+?(?=-|_|,|;)/)}`.toLowerCase();
}
// Get defined locales
const supportedLocales = locales.get().map((l) => l.toLowerCase());
// Use default locale if current locale is not supported
if (!supportedLocales.includes(locale)) {
locale = defaultLocale;
}
await loadTranslations(locale, pathname); // keep this just before the `return`
return {
i18n: { locale, route: pathname },
translations: translations.get(), // `translations` on server contain all translations loaded by different clients
};
};
Basically, we are checking the language preference stored in user’s browser. If there is no language preference in the user’s browser, we are using our default language.
In SvelteKit’s client-side, we’ll use the translations loaded on the server-side. Now, create a +layout.js
file under the src/routes
folder. After that, paste the following code into this file.
import { addTranslations, setLocale, setRoute } from '$lib/translations';
/** @type {import('@sveltejs/kit').Load} */
export const load = async ({ data }) => {
const { i18n, translations } = data;
const { locale, route } = i18n;
addTranslations(translations);
await setRoute(route);
await setLocale(locale);
return i18n;
};
Using Translations
We are ready to go! We can now use the translations in our SvelteKit application.
In our home
route, create a +page.svelte
file and add the followings.
<script>
import { t } from '$lib/translations';
const link = 'https://kit.svelte.dev';
</script>
<h1>{$t('home.title')}</h1>
<p>{@html $t('home.text', { link })}</p>
t
function is using for getting translations. To use it correctly, we access the translation value by using the key, for example, home.title
.
Adding a New Language
To add a new language, create a new folder in the translations folder and add the translation files to the relevant folder, for example, de for German, fr for French. Next, include the file paths in the loader in the translations/index.js file.
Sample Application
Handling internalization is very easy with SvelteKit! You can easily add new languages to your web application.
If you want your website to reach a global audience, SvelteKit and the sveltekit-i18n
package can be a powerful duo. This way, you can share content in multiple languages and reach more users worldwide.
Is your website still in a single language? We can help you with this.
Book Free Consultation