Beamen Sie Ihre Svelte-Internationalisierung auf ein neues Level❕ (ein svelte-i18n Leitfaden)
en

Es macht Spass, mit Svelte zusammenzuarbeiten. Das Design ist elegant und die robusten First-Party-Ergänzungen, mit denen gekoppelt werden kann, machen das Erstellen von Browser-Apps zum Vergnügen.

Das bekannteste i18n-Plugin für das progressive JavaScript-Framework Svelte ist wohl svelte-i18n.

Christian Kaisermann, vielen Dank für dieses grossartige i18n-Plugin!

In diesem Tutorial werden wir zusätzliche Superkräfte zu svelte-i18n hinzufügen. 😉

Inhaltsverzeichnis

Wie sieht also ein einfaches Svelte-i18n-Setup aus?

Lassen Sie uns darauf eingehen...

Voraussetzungen

Stellen Sie sicher, dass Sie Node.js und npm installiert haben. Wenn Sie etwas Erfahrung mit einfachem HTML, JavaScript und einfachem Svelte haben, ist es am besten, bevor Sie zu svelte-i18n springen.

Einstieg

Nehmen Sie Ihr eigenes Svelte-Projekt oder erstellen Sie ein neues.

Lassen Sie uns die svelte-i18n-Abhängigkeit installieren:

npm install svelte-i18n

Erstellen Sie eine i18n.js-Datei:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { addMessages, init, getLocaleFromNavigator } from 'svelte-i18n';

const fallbackLocale = 'en';
const lngs = [fallbackLocale, 'de'];

addMessages('en', {
welcome: 'Welcome to Your Svelte App'
});
addMessages('de', {
welcome: 'Willkommen zu deiner Svelte-App'
});

let initialLocale;
const detectedLocale = getLocaleFromNavigator(); // the locale could be region specific, i.e. de-CH
if (lngs.indexOf(detectedLocale) > -1) initialLocale = detectedLocale;
if (!initialLocale && detectedLocale.indexOf('-') > 0) {
const foundLng = lngs.find((l) => detectedLocale.indexOf(l + '-') === 0);
if (foundLng) initialLocale = foundLng;
}
if (!initialLocale) initialLocale = fallbackLocale;

init({
fallbackLocale,
initialLocale
});

Importieren Sie die Datei i18n.js in Ihre Datei main.js:

1
2
3
4
5
6
7
8
9
10
import App from './App.svelte';

import './i18n';

const app = new App({
target: document.body,
props: {}
});

export default app;

Versuchen wir nun, unseren ersten internationalisierten Text zu verwenden. Importieren Sie in Ihrer Vorlage _ aus svelte-i18n und verwenden Sie es wie folgt:

1
2
3
4
5
6
7
8
<script>
import { _ } from 'svelte-i18n';
</script>

<main>
<img alt="svelte logo" src="img/svelte-logo.png" />
<h1>{$_('welcome')}</h1>
</main>

Nett! Jetzt fügen wir ein weiteres Textelement hinzu ...

1
2
3
4
5
6
7
8
9
<script>
import { _ } from 'svelte-i18n';
</script>

<main>
<img alt="svelte logo" src="img/svelte-logo.png" />
<h1>{$_('welcome')}</h1>
<p>{@html $_('descr', { values: { link: `<a href="https://svelte.dev/tutorial" target="_blank">${$_('doc')}</a>` } })}</p>
</main>

Und die entsprechenden Übersetzungen:

1
2
3
4
5
6
7
8
9
10
addMessages('en', {
welcome: 'Welcome to Your Svelte App',
descr: 'Visit the {link} to learn how to build Svelte apps.',
doc: 'Svelte tutorial'
});
addMessages('de', {
welcome: 'Willkommen zu deiner Svelte-App',
descr: 'Besuchen Sie den {link}, um zu erfahren, wie Sie Svelte-Apps erstellen.',
doc: 'Svelte Tutorial'
});

Jetzt sollten Sie, abhängig von Ihrer Browsersprache, so etwas sehen:

Sprachumschalter

Jetzt werden wir einen Sprachumschalter erstellen, um den Inhaltswechsel zwischen verschiedenen Sprachen vorzunehmen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
import { _, locale, locales } from 'svelte-i18n';
</script>

<main>
<img alt="svelte logo" src="img/svelte-logo.png" />
<h1>{$_('welcome')}</h1>
<p>{@html $_('descr', { values: { link: `<a href="https://svelte.dev/tutorial" target="_blank">${$_('doc')}</a>` } })}</p>
<select bind:value={$locale}>
{#each $locales as locale}
<option value={locale}>{locale}</option>
{/each}
</select>
</main>

Und wir speichern die aktuell gewählte Sprache im localStorage:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { addMessages, init, getLocaleFromNavigator, locale } from 'svelte-i18n';

const fallbackLocale = 'en';
const lngs = [fallbackLocale, 'de'];

addMessages('en', {
welcome: 'Welcome to Your Svelte App',
descr: 'Visit the {link} to learn how to build Svelte apps.',
doc: 'Svelte tutorial'
});
addMessages('de', {
welcome: 'Willkommen zu deiner Svelte-App',
descr: 'Besuchen Sie den {link}, um zu erfahren, wie Sie Svelte-Apps erstellen.',
doc: 'Svelte Tutorial'
});

locale.subscribe((lng) => {
if (lng) localStorage.setItem('svelte-i18n-locale', lng);
});

let initialLocale;
const detectedLocale = localStorage.getItem('svelte-i18n-locale') || getLocaleFromNavigator(); // the locale could be region specific, i.e. de-CH
if (lngs.indexOf(detectedLocale) > -1) initialLocale = detectedLocale;
if (!initialLocale && detectedLocale.indexOf('-') > 0) {
const foundLng = lngs.find((l) => detectedLocale.indexOf(l + '-') === 0);
if (foundLng) initialLocale = foundLng;
}
if (!initialLocale) initialLocale = fallbackLocale;

init({
fallbackLocale,
initialLocale
});

🥳 Grossartig, Sie haben gerade Ihren ersten Sprachumschalter erstellt!

Wo sind die zusätzlichen Superkräfte?

Lernen wir locizer kennen...

locizer ist ein einfaches Modul, um auf Daten aus Ihrem locize-Projekt zuzugreifen und diese in Ihrer Anwendung zu verwenden.

Was ist locize?

Wie sieht das aus?

Zuerst müssen Sie sich bei locize registrieren und anmelden. Dann erstellen Sie ein neues Projekt in locize und fügen Ihre Übersetzungen hinzu. Sie können Ihre Übersetzungen entweder über die CLI oder durch Importieren der einzelnen json-Dateien oder über die API bewerkstelligen.

Die Übersetzungen im Code zu haben, funktioniert, ist aber für Übersetzer nicht so geeignet, damit zu arbeiten. Die Verwendung von locize trennt die Übersetzungen vom Code.

Nachdem alle Übersetzungen importiert wurden, sollte es wie folgt aussehen:

Fertig, als werden wir locizer installieren.

npm install locizer

Passen wir die Datei i18n.js an:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { register, init, getLocaleFromNavigator, locale } from 'svelte-i18n';
import locizer from 'locizer';

const fallbackLocale = 'en';
const lngs = [fallbackLocale, 'de'];
const namespace = 'messages'; // your namespace name added in locize

locizer.init({
projectId: 'your-locize-project-id'
});

lngs.forEach((l) => {
register(l, () => new Promise((resolve, reject) => {
locizer.load(namespace, l, (err, ns) => {
if (err) return reject(err);
resolve(ns);
});
}));
})

locale.subscribe((lng) => {
if (lng) localStorage.setItem('svelte-i18n-locale', lng);
});

let initialLocale;
const detectedLocale = localStorage.getItem('svelte-i18n-locale') || getLocaleFromNavigator();
if (lngs.indexOf(detectedLocale) > -1) initialLocale = detectedLocale;
if (!initialLocale && detectedLocale.indexOf('-') > 0) {
const foundLng = lngs.find((l) => detectedLocale.indexOf(l + '-') === 0);
if (foundLng) initialLocale = foundLng;
}
if (!initialLocale) initialLocale = fallbackLocale;

init({
fallbackLocale,
initialLocale
});

Da die Übersetzungen jetzt asynchron geladen werden, möchten wir vielleicht auch eine Lademeldung anzeigen, bis die Übersetzungen fertig sind:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
import { isLoading, _, locale, locales } from 'svelte-i18n';
</script>

<main>
<img alt="svelte logo" src="img/svelte-logo.png" />
{#if $isLoading}
<p>
loading translations...
</p>
{:else}
<h1>{$_('welcome')}</h1>
<p>{@html $_('descr', { values: { link: `<a href="https://svelte.dev/tutorial" target="_blank">${$_('doc')}</a>` } })}</p>
<select bind:value={$locale}>
{#each $locales as locale}
<option value={locale}>{locale}</option>
{/each}
</select>
{/if}
</main>

Jetzt werden Ihre Übersetzungen direkt von locize CDN abgerufen.
🙀 Das bedeutet, dass Sie Übersetzungen korrigieren können, ohne Ihren Code ändern oder Ihre App erneut bereitstellen zu müssen. 🤩

fehlende Übersetzungen speichern

Ich möchte, dass neu hinzugefügte Schlüssel im Code automatisch gespeichert werden, um sie zu lokalisieren.

Ihr Wunsch ist mir Befehl!

Erweitern Sie die i18n.js-Datei mit dem locize api-key und der handleMissingMessage-Funktion:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { register, init, getLocaleFromNavigator, locale } from 'svelte-i18n';
import locizer from 'locizer';

const fallbackLocale = 'en';
const lngs = [fallbackLocale, 'de'];
const namespace = 'messages';
const apiKey = 'my-api-key'; // do not expose your API-Key in production

locizer.init({
projectId: 'your-locize-project-id',
apiKey
});

lngs.forEach((l) => {
register(l, () => new Promise((resolve, reject) => {
locizer.load(namespace, l, (err, ns) => {
if (err) return reject(err);
resolve(ns);
});
}));
})

locale.subscribe((lng) => {
if (lng) localStorage.setItem('svelte-i18n-locale', lng);
});

let initialLocale;
const detectedLocale = localStorage.getItem('svelte-i18n-locale') || getLocaleFromNavigator();
if (lngs.indexOf(detectedLocale) > -1) initialLocale = detectedLocale;
if (!initialLocale && detectedLocale.indexOf('-') > 0) {
const foundLng = lngs.find((l) => detectedLocale.indexOf(l + '-') === 0);
if (foundLng) initialLocale = foundLng;
}
if (!initialLocale) initialLocale = fallbackLocale;

init({
fallbackLocale,
initialLocale,
handleMissingMessage: apiKey ? ({ locale, id, defaultValue }) => {
if (locale !== locizer.referenceLng) return;
locizer.add(namespace, id, defaultValue);
} : undefined
});

Wenn Sie jetzt einen neuen Schlüssel in Ihren Vorlagen hinzufügen, <h2>{$_('howAreYou', { default: 'How are you?' })}</h2>:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
import { isLoading, _, locale, locales } from 'svelte-i18n';
</script>

<main>
<img alt="svelte logo" src="img/svelte-logo.png" />
{#if $isLoading}
<p>
loading translations...
</p>
{:else}
<h1>{$_('welcome')}</h1>
<h2>{$_('howAreYou', { default: 'How are you?' })}</h2>
<p>{@html $_('descr', { values: { link: `<a href="https://svelte.dev/tutorial" target="_blank">${$_('doc')}</a>` } })}</p>
<select bind:value={$locale}>
{#each $locales as locale}
<option value={locale}>{locale}</option>
{/each}
</select>
{/if}
</main>

Es wird automatisch zu locize hinzugefügt:

Schliesslch werden mit Hilfe des Arbeitsablaufs für automatische maschinelle Übersetzung nicht nur neue Schlüssel in locize hinzugefügt, während die App entwickelt wird, sondern werden auch automatisch per maschineller Übersetzung in die Zielsprachen übersetzt:

Schauen Sie sich dieses Video an, um zu sehen, wie der Arbeitsablauf der automatischen maschinellen Übersetzung aussieht!

In-Kontext-Editor

Es gibt noch eine coole Sache, die wir machen können ...

Lassen Sie uns locize installieren:

npm install locize

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { register, init, getLocaleFromNavigator, locale } from 'svelte-i18n';
import locizer from 'locizer';
import { addLocizeSavedHandler } from 'locize';

const fallbackLocale = 'en';
const lngs = [fallbackLocale, 'de'];
const namespace = 'messages';
const apiKey = 'my-api-key'; // do not expose your API-Key in production

locizer.init({
projectId: 'your-locize-project-id',
apiKey
});

lngs.forEach((l) => {
register(l, () => new Promise((resolve, reject) => {
locizer.load(namespace, l, (err, ns) => {
if (err) return reject(err);
resolve(ns);
});
}));
})

locale.subscribe((lng) => {
if (lng) localStorage.setItem('svelte-i18n-locale', lng);
});

let initialLocale;
const detectedLocale = localStorage.getItem('svelte-i18n-locale') || getLocaleFromNavigator();
if (lngs.indexOf(detectedLocale) > -1) initialLocale = detectedLocale;
if (!initialLocale && detectedLocale.indexOf('-') > 0) {
const foundLng = lngs.find((l) => detectedLocale.indexOf(l + '-') === 0);
if (foundLng) initialLocale = foundLng;
}
if (!initialLocale) initialLocale = fallbackLocale;

init({
fallbackLocale,
initialLocale,
handleMissingMessage: apiKey ? ({ locale, id, defaultValue }) => {
if (locale !== locizer.referenceLng) return;
locizer.add(namespace, id, defaultValue);
} : undefined
});

addLocizeSavedHandler(() => location.reload());

Öffnen Sie nun den locize InContext Editor und staunen Sie:

i18n incontext editor

👀 aber es gibt noch mehr...

Caching:

Versionen zusammenführen:

🧑‍💻 Den Code finden Sie hier.

🎉🥳 Herzlichen Glückwunsch 🎊🎁

Ich hoffe, Sie haben ein paar neue Dinge über Svelte-Lokalisierung und moderne Lokalisierungs-Workflows gelernt.

Wenn Sie also Ihr i18n-Thema auf die nächste Ebene bringen möchten, lohnt es sich, locize auszuprobieren.

👍

Share