From 4953a9952e9f9ba0b741ac25f8fe6f20059d2d0a Mon Sep 17 00:00:00 2001 From: Dan Blackadder Date: Thu, 11 Sep 2025 11:28:00 +0100 Subject: [PATCH] POC Implementation using sveltekit-i18n --- package-lock.json | 32 ++++++++++++++ package.json | 1 + .../components/layout/LandingHeader.svelte | 15 +++++++ .../src/lib/utils/translations/de.json | 5 +++ .../src/lib/utils/translations/en.json | 5 +++ .../src/lib/utils/translations/es.json | 5 +++ .../src/lib/utils/translations/id.json | 5 +++ .../src/lib/utils/translations/index.ts | 42 +++++++++++++++++++ .../src/lib/utils/translations/lang.json | 6 +++ .../src/routes/(new-styling)/+layout.svelte | 8 ++++ .../src/routes/(new-styling)/+page.svelte | 3 +- 11 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/frontend/src/lib/utils/translations/de.json create mode 100644 src/frontend/src/lib/utils/translations/en.json create mode 100644 src/frontend/src/lib/utils/translations/es.json create mode 100644 src/frontend/src/lib/utils/translations/id.json create mode 100644 src/frontend/src/lib/utils/translations/index.ts create mode 100644 src/frontend/src/lib/utils/translations/lang.json diff --git a/package-lock.json b/package-lock.json index 02cf4af998..8e7061cd5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "plausible-tracker": "0.3.9", "qr-creator": "^1.0.0", "stream-browserify": "^3.0.0", + "sveltekit-i18n": "^2.4.2", "ua-parser-js": "^1.0.35", "zod": "^3.22.3" }, @@ -3185,6 +3186,21 @@ "vite": "^6.0.0" } }, + "node_modules/@sveltekit-i18n/base": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@sveltekit-i18n/base/-/base-1.3.7.tgz", + "integrity": "sha512-kg1kql1/ro/lIudwFiWrv949Q07gmweln87tflUZR51MNdXXzK4fiJQv5Mw50K/CdQ5BOk/dJ0WOH2vOtBI6yw==", + "license": "MIT", + "peerDependencies": { + "svelte": ">=3.49.0" + } + }, + "node_modules/@sveltekit-i18n/parser-default": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@sveltekit-i18n/parser-default/-/parser-default-1.1.1.tgz", + "integrity": "sha512-/gtzLlqm/sox7EoPKD56BxGZktK/syGc79EbJAPWY5KVitQD9SM0TP8yJCqDxTVPk7Lk0WJhrBGUE2Nn0f5M1w==", + "license": "MIT" + }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -14841,6 +14857,22 @@ "typescript": "^4.9.4 || ^5.0.0" } }, + "node_modules/sveltekit-i18n": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/sveltekit-i18n/-/sveltekit-i18n-2.4.2.tgz", + "integrity": "sha512-hjRWn4V4DBL8JQKJoJa3MRvn6d32Zo+rWkoSP5bsQ/XIAguPdQUZJ8LMe6Nc1rST8WEVdu9+vZI3aFdKYGR3+Q==", + "license": "MIT", + "workspaces": [ + "./examples/*/" + ], + "dependencies": { + "@sveltekit-i18n/base": "~1.3.0", + "@sveltekit-i18n/parser-default": "~1.1.0" + }, + "peerDependencies": { + "svelte": ">=3.49.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 418df5d5e4..5fc5dbbff0 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,7 @@ "plausible-tracker": "0.3.9", "qr-creator": "^1.0.0", "stream-browserify": "^3.0.0", + "sveltekit-i18n": "^2.4.2", "ua-parser-js": "^1.0.35", "zod": "^3.22.3" }, diff --git a/src/frontend/src/lib/components/layout/LandingHeader.svelte b/src/frontend/src/lib/components/layout/LandingHeader.svelte index f329edfe12..6b68f53334 100644 --- a/src/frontend/src/lib/components/layout/LandingHeader.svelte +++ b/src/frontend/src/lib/components/layout/LandingHeader.svelte @@ -1,8 +1,14 @@
+ {@render children?.()}
diff --git a/src/frontend/src/lib/utils/translations/de.json b/src/frontend/src/lib/utils/translations/de.json new file mode 100644 index 0000000000..f67e19291f --- /dev/null +++ b/src/frontend/src/lib/utils/translations/de.json @@ -0,0 +1,5 @@ +{ + "landing": { + "experience": "Erleben" + } +} \ No newline at end of file diff --git a/src/frontend/src/lib/utils/translations/en.json b/src/frontend/src/lib/utils/translations/en.json new file mode 100644 index 0000000000..509b126b8e --- /dev/null +++ b/src/frontend/src/lib/utils/translations/en.json @@ -0,0 +1,5 @@ +{ + "landing": { + "experience": "Experience" + } +} \ No newline at end of file diff --git a/src/frontend/src/lib/utils/translations/es.json b/src/frontend/src/lib/utils/translations/es.json new file mode 100644 index 0000000000..2bec4f7c7c --- /dev/null +++ b/src/frontend/src/lib/utils/translations/es.json @@ -0,0 +1,5 @@ +{ + "landing": { + "experience": "Experiencia" + } +} \ No newline at end of file diff --git a/src/frontend/src/lib/utils/translations/id.json b/src/frontend/src/lib/utils/translations/id.json new file mode 100644 index 0000000000..5fe008e755 --- /dev/null +++ b/src/frontend/src/lib/utils/translations/id.json @@ -0,0 +1,5 @@ +{ + "landing": { + "experience": "Pengalaman" + } +} \ No newline at end of file diff --git a/src/frontend/src/lib/utils/translations/index.ts b/src/frontend/src/lib/utils/translations/index.ts new file mode 100644 index 0000000000..1fa7fc1eb0 --- /dev/null +++ b/src/frontend/src/lib/utils/translations/index.ts @@ -0,0 +1,42 @@ +import i18n from "sveltekit-i18n"; +import type { Config } from "sveltekit-i18n"; +import lang from "./lang.json"; + +const config: Config = { + translations: { + en: { lang }, + es: { lang }, + id: { lang }, + de: { lang }, + }, + loaders: [ + { + locale: "en", + key: "t", + loader: async () => (await import("./en.json")).default, + }, + { + locale: "es", + key: "t", + loader: async () => (await import("./es.json")).default, + }, + { + locale: "id", + key: "t", + loader: async () => (await import("./id.json")).default, + }, + { + locale: "de", + key: "t", + loader: async () => (await import("./de.json")).default, + }, + ], +}; + +export const { t, locale, locales, loading, loadTranslations } = new i18n( + config, +); + +loading.subscribe( + ($loading) => $loading && console.log("Loading translations..."), +); diff --git a/src/frontend/src/lib/utils/translations/lang.json b/src/frontend/src/lib/utils/translations/lang.json new file mode 100644 index 0000000000..fb30145f23 --- /dev/null +++ b/src/frontend/src/lib/utils/translations/lang.json @@ -0,0 +1,6 @@ +{ + "en": "English", + "es": "Spanish", + "id": "Indonesian", + "de": "German" +} \ No newline at end of file diff --git a/src/frontend/src/routes/(new-styling)/+layout.svelte b/src/frontend/src/routes/(new-styling)/+layout.svelte index d417d929ad..adeef63638 100644 --- a/src/frontend/src/routes/(new-styling)/+layout.svelte +++ b/src/frontend/src/routes/(new-styling)/+layout.svelte @@ -4,8 +4,16 @@ import WaveCanvas from "$lib/components/backgrounds/WaveCanvas.svelte"; import Toaster from "$lib/components/utils/Toaster.svelte"; import type { LayoutProps } from "./$types"; + import { loadTranslations, locale } from "$lib/utils/translations"; + import { onMount } from "svelte"; const { children }: LayoutProps = $props(); + + onMount(async () => { + const initLocale = "en"; + + await loadTranslations(initLocale, "t"); + }); diff --git a/src/frontend/src/routes/(new-styling)/+page.svelte b/src/frontend/src/routes/(new-styling)/+page.svelte index 39e89b377f..22f830a844 100644 --- a/src/frontend/src/routes/(new-styling)/+page.svelte +++ b/src/frontend/src/routes/(new-styling)/+page.svelte @@ -21,6 +21,7 @@ } from "$lib/config"; import LandingHeader from "$lib/components/layout/LandingHeader.svelte"; import { fade } from "svelte/transition"; + import { t } from "$lib/utils/translations"; const faq = [ { @@ -126,7 +127,7 @@

- Experience + {$t("t.landing.experience", { default: "Experience" })}