diff --git a/examples/locale-param/.gitignore b/examples/locale-param/.gitignore new file mode 100644 index 0000000..2194f15 --- /dev/null +++ b/examples/locale-param/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +node_modules +build +.svelte-kit +package +.env +.env.* +!.env.example diff --git a/examples/locale-param/README.md b/examples/locale-param/README.md new file mode 100644 index 0000000..fb2ad7f --- /dev/null +++ b/examples/locale-param/README.md @@ -0,0 +1,7 @@ +[![Netlify Status](https://api.netlify.com/api/v1/badges/c5bbe5c2-c9b9-4175-aa68-fd4aec778589/deploy-status)](https://app.netlify.com/sites/multi-page-example/deploys) + +# Multi-page app +In this app, translations are loaded dynamically according to user navigation and `$locale` change. It has built-in mechanism to prevent duplicit (server and client) translation load on app enter. It's useful, when you are fetching your translations from remote API, or using other data-expensive solution. + +## Preview +You can view this demo live on [Netlify](https://multi-page-example.netlify.app). \ No newline at end of file diff --git a/examples/locale-param/jsconfig.json b/examples/locale-param/jsconfig.json new file mode 100644 index 0000000..0a13bbe --- /dev/null +++ b/examples/locale-param/jsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./.svelte-kit/tsconfig.json" +} \ No newline at end of file diff --git a/examples/locale-param/netlify.toml b/examples/locale-param/netlify.toml new file mode 100644 index 0000000..5ce4a5a --- /dev/null +++ b/examples/locale-param/netlify.toml @@ -0,0 +1,5 @@ +[build] + command = "cd ../../ && npm run build && npm run build --workspace locale-param" + publish = "build" +[functions] + node_bundler = "esbuild" \ No newline at end of file diff --git a/examples/locale-param/package.json b/examples/locale-param/package.json new file mode 100644 index 0000000..395b5e7 --- /dev/null +++ b/examples/locale-param/package.json @@ -0,0 +1,21 @@ +{ + "name": "locale-param", + "version": "0.0.1", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "package": "svelte-kit package", + "preview": "vite preview", + "prepare": "svelte-kit sync" + }, + "devDependencies": { + "@sveltejs/adapter-netlify": "^2.0.7", + "@sveltejs/kit": "^1.22.1", + "svelte": "^4.0.5", + "vite": "^4.4.2" + }, + "type": "module", + "dependencies": { + "sveltekit-i18n": "file:../../" + } +} \ No newline at end of file diff --git a/examples/locale-param/src/app.html b/examples/locale-param/src/app.html new file mode 100644 index 0000000..d76162a --- /dev/null +++ b/examples/locale-param/src/app.html @@ -0,0 +1,16 @@ + + + + + + + + + %sveltekit.head% + + + +
%sveltekit.body%
+ + + \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/cs/about.json b/examples/locale-param/src/lib/translations/cs/about.json new file mode 100644 index 0000000..8e6ae9b --- /dev/null +++ b/examples/locale-param/src/lib/translations/cs/about.json @@ -0,0 +1,4 @@ +{ + "title": "O této aplikaci", + "text": "

Toto je SvelteKit aplikace. Můžete si vytvořit svou vlastní vložením následujícího příkazu do příkazové řádky:

npm init svelte@next

Tato stránka je čistě statické HTML, bez nutnosti klientské interakce. Díky tomu není potřeba načítat žádný JavaScript. Zkuste zobrazit drojový kód stránky, nebo otevřete vývojářské nástroje a znovu načtěte stránku.

" +} \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/cs/home.json b/examples/locale-param/src/lib/translations/cs/home.json new file mode 100644 index 0000000..d234856 --- /dev/null +++ b/examples/locale-param/src/lib/translations/cs/home.json @@ -0,0 +1,4 @@ +{ + "title": "Vítejte ve SvelteKit", + "text": "Dokumentace je k přečtení na kit.svelte.dev" +} \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/cs/menu.json b/examples/locale-param/src/lib/translations/cs/menu.json new file mode 100644 index 0000000..327a19c --- /dev/null +++ b/examples/locale-param/src/lib/translations/cs/menu.json @@ -0,0 +1,5 @@ +{ + "home": "Domů", + "about": "O nás", + "notification": "{{count:gt; 0:Máte {{count}} {{count:gte; 1:novou zprávu; 2:nové zprávy; 5:nových zpráv}}!; default:Nemáte žádné zprávy...}}" +} \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/en/about.json b/examples/locale-param/src/lib/translations/en/about.json new file mode 100644 index 0000000..f4f55a9 --- /dev/null +++ b/examples/locale-param/src/lib/translations/en/about.json @@ -0,0 +1,4 @@ +{ + "title": "About this app", + "text": "

This is a SvelteKit app. You can make your own by typing the following into your command line and following the prompts:

npm init svelte@next

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.

" +} \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/en/home.json b/examples/locale-param/src/lib/translations/en/home.json new file mode 100644 index 0000000..f1f65f6 --- /dev/null +++ b/examples/locale-param/src/lib/translations/en/home.json @@ -0,0 +1,4 @@ +{ + "title": "Welcome to SvelteKit", + "text": "Visit kit.svelte.dev to read the documentation" +} \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/en/menu.json b/examples/locale-param/src/lib/translations/en/menu.json new file mode 100644 index 0000000..f66a63c --- /dev/null +++ b/examples/locale-param/src/lib/translations/en/menu.json @@ -0,0 +1,5 @@ +{ + "home": "Home", + "about": "About", + "notification": "You have {{count:gt; 0:{{count}} new {{count; 1:message; default:messages}}!; default:no messages...}}" +} \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/index.js b/examples/locale-param/src/lib/translations/index.js new file mode 100644 index 0000000..49281b5 --- /dev/null +++ b/examples/locale-param/src/lib/translations/index.js @@ -0,0 +1,56 @@ +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 }, + cs: { 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: 'cs', + key: 'menu', + loader: async () => (await import('./cs/menu.json')).default, + }, + { + locale: 'cs', + key: 'about', + routes: ['/about'], + loader: async () => (await import('./cs/about.json')).default, + }, + { + locale: 'cs', + key: 'home', + routes: ['/'], + loader: async () => (await import('./cs/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...')); \ No newline at end of file diff --git a/examples/locale-param/src/lib/translations/lang.json b/examples/locale-param/src/lib/translations/lang.json new file mode 100644 index 0000000..4b3170f --- /dev/null +++ b/examples/locale-param/src/lib/translations/lang.json @@ -0,0 +1,4 @@ +{ + "en": "English", + "cs": "Česky" +} \ No newline at end of file diff --git a/examples/locale-param/src/routes/+layout.js b/examples/locale-param/src/routes/+layout.js new file mode 100644 index 0000000..618a6a6 --- /dev/null +++ b/examples/locale-param/src/routes/+layout.js @@ -0,0 +1,14 @@ +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; +}; \ No newline at end of file diff --git a/examples/locale-param/src/routes/+layout.server.js b/examples/locale-param/src/routes/+layout.server.js new file mode 100644 index 0000000..0a647a9 --- /dev/null +++ b/examples/locale-param/src/routes/+layout.server.js @@ -0,0 +1,17 @@ +import { loadTranslations, translations, defaultLocale } from '$lib/translations'; + +/** @type {import('@sveltejs/kit').ServerLoad} */ +export const load = async ({ url, cookies }) => { + const { pathname, searchParams } = url; + + const initLocale = searchParams.get('lang') || cookies.get('locale') || defaultLocale; + + cookies.set('locale', initLocale); + + await loadTranslations(initLocale, pathname); // keep this just before the `return` + + return { + i18n: { locale: initLocale, route: pathname }, + translations: translations.get(), + }; +}; \ No newline at end of file diff --git a/examples/locale-param/src/routes/+layout.svelte b/examples/locale-param/src/routes/+layout.svelte new file mode 100644 index 0000000..029ad0a --- /dev/null +++ b/examples/locale-param/src/routes/+layout.svelte @@ -0,0 +1,26 @@ + + +{$t('menu.home')} +{$t('menu.about')} +
+
+{$t('menu.notification', { count })}
+ + +
+ +
+
+
+
+ \ No newline at end of file diff --git a/examples/locale-param/src/routes/+page.svelte b/examples/locale-param/src/routes/+page.svelte new file mode 100644 index 0000000..a6f3837 --- /dev/null +++ b/examples/locale-param/src/routes/+page.svelte @@ -0,0 +1,8 @@ + + +

{$t('home.title')}

+

{@html $t('home.text', { link })}

diff --git a/examples/locale-param/src/routes/about/+page.svelte b/examples/locale-param/src/routes/about/+page.svelte new file mode 100644 index 0000000..ee40d43 --- /dev/null +++ b/examples/locale-param/src/routes/about/+page.svelte @@ -0,0 +1,6 @@ + + +

{$t('about.title')}

+

{@html $t('about.text')}

diff --git a/examples/locale-param/static/favicon.png b/examples/locale-param/static/favicon.png new file mode 100644 index 0000000..825b9e6 Binary files /dev/null and b/examples/locale-param/static/favicon.png differ diff --git a/examples/locale-param/svelte.config.js b/examples/locale-param/svelte.config.js new file mode 100644 index 0000000..79cd261 --- /dev/null +++ b/examples/locale-param/svelte.config.js @@ -0,0 +1,10 @@ +import adapter from '@sveltejs/adapter-netlify'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + adapter: adapter(), + }, +}; + +export default config; diff --git a/examples/locale-param/vite.config.js b/examples/locale-param/vite.config.js new file mode 100644 index 0000000..d3c4f0d --- /dev/null +++ b/examples/locale-param/vite.config.js @@ -0,0 +1,6 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()], +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 13f4285..82881b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,6 +69,18 @@ "vite": "^4.4.2" } }, + "examples/locale-param": { + "version": "0.0.1", + "dependencies": { + "sveltekit-i18n": "file:../../" + }, + "devDependencies": { + "@sveltejs/adapter-netlify": "^2.0.7", + "@sveltejs/kit": "^1.22.1", + "svelte": "^4.0.5", + "vite": "^4.4.2" + } + }, "examples/locale-router": { "version": "0.0.1", "dependencies": { @@ -5360,6 +5372,10 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/locale-param": { + "resolved": "examples/locale-param", + "link": true + }, "node_modules/locale-router": { "resolved": "examples/locale-router", "link": true