Whenever you add a new item in English it generates other languages and types. Also translates with OpenAI API.
types.ts
export type Translations
en
) and:fi/
) doesn’t exist, create it.npm i
npm install -D chokidar-cli npm-run-all
/codegen/.env
file with the following content:OPENAI_API_KEY = "sk-XXXXXXXX"
Copy the root_folder_structure_example/src/lib/i18n
folder to yout /src/lib
folder and update languages.json
with your languages.
Update your SvelteKit main package.json
scripts something like this:
{
"scripts": {
"dev": "npm-run-all --parallel dev:*",
"dev:vite": "vite --host",
"dev:watch-i18n": "chokidar \"./src/lib/i18n/en/*.json\" -c \"node ./codegen/index.js\"",
"codegen:i18n": "node ./codegen/index.js",
"build": "vite build",
"preview": "vite preview",
"test": "vitest",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
}
}
Notes:
dev:watch-i18n
uses chokidar-cli
to watch for changes in en/*.json
and rerun the codegen script.npm run codegen:i18n
manually.See the lines 59-66 and adjust your promop, temperature, etc.
Add to eg. $lib/runes/language.svnpm create [email protected]
:
export let locale = $state('en');
// Loads a single translation file
export function loadSection(section: string): Promise<Record<string, string>> {
// Dynamic import –> returns promise
return (
import(`../i18n/${locale}/${section}.json`)
// Default export is `module.default`
.then((module) => module.default)
);
}
// Load multiple sections at once and merge them
export function loadTranslations(sections: string[]): Promise<Record<string, string>> {
return Promise.all(sections.map((section) => loadSection(section))).then((results) => {
let merged = {};
for (const r of results) {
merged = { ...merged, ...r };
}
return merged;
});
}
<script lang="ts>
import { loadTranslations } from '$lib/runes/language.svelte';
import type { Translations } from '$lib/types';
let requiredSections = ['common', 'calendar']; // change this
let trans: Translations = $state({}) as Translations;
$effect(() => {
loadTranslations(requiredSections).then((data) => {
trans = data as Translations;
});
});
</script>
Calendar in another language: {trans.calendar}
package.json
add:{
"scripts": {
"dev:vite": "vite --host",
"dev:watch-i18n": "chokidar \"./src/lib/i18n/en/*.json\" -c \"npm run codegen:i18n\"",
"codegen:i18n": "node ./codegen/index.mjs",
"dev": "npm-run-all --parallel dev:vite dev:watch-i18n",
// rest of your scripts
}
}