Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.3.0 #117

Merged
merged 16 commits into from
Jul 8, 2023
Merged

2.3.0 #117

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
{
"extends": [
"airbnb-typescript/base"
"airbnb-typescript/base",
"plugin:svelte/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "**/tsconfig.json",
"sourceType": "module"
"sourceType": "module",
"extraFileExtensions": [
".svelte"
]
},
"plugins": [
"import",
"svelte3"
"import"
],
"overrides": [
{
"files": [
"*.svelte"
],
"processor": "svelte3/svelte3"
"parser": "svelte-eslint-parser",
"parserOptions": {
"parser": "@typescript-eslint/parser"
}
}
],
"rules": {
Expand All @@ -25,7 +31,10 @@
"@typescript-eslint/no-redeclare": 0,
"@typescript-eslint/no-shadow": 0,
"no-trailing-spaces": "error",
"no-multiple-empty-lines": "error"
"no-multiple-empty-lines": "error",
"import/extensions": 0,
"import/no-extraneous-dependencies": 0,
"svelte/no-at-html-tags": 0
},
"settings": {}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
**/.svelte-kit
**/.netlify
**/package
**/build
/lib
Expand Down
45 changes: 11 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# sveltekit-i18n
`sveltekit-i18n` is a tiny library with no external dependencies, built for [Svelte](https://github.com/sveltejs/svelte) and [SvelteKit](https://github.com/sveltejs/kit). It glues [@sveltekit-i18n/base](https://github.com/sveltekit-i18n/base) and [@sveltekit-i18n/parser-default](https://github.com/sveltekit-i18n/parsers/tree/master/parser-default) together to provide you the most straightforward `sveltekit-i18n` solution.

__Note this README is related to `[email protected]`. If you are looking for version `1.x` you can find it [here](https://github.com/sveltekit-i18n/lib/tree/1.x).__

## Key features

✅ SvelteKit ready\
Expand Down Expand Up @@ -77,44 +75,23 @@ const config = ({
export const { t, locale, locales, loading, loadTranslations } = new i18n(config);
```

...load your translations in `__layout.svelte`...

```svelte
<script context="module">
import { locale, loadTranslations } from '$lib/translations';

export const load = async ({ url }) => {
const { pathname } = url;

const defaultLocale = 'en'; // get from cookie, user session, ...

const initLocale = locale.get() || defaultLocale; // set default if no locale already set
...load your translations in `+layout.js`...

await loadTranslations(initLocale, pathname); // keep this just before the `return`

return {};
}
</script>
```

<details><summary>+layout.ts example</summary>
```javascript
import { locale, loadTranslations } from '$lib/translations';

In modern SvelteKit `+layout.ts` is used instead of `__layout.svelte`.
export const load = async ({ url }) => {
const { pathname } = url;

```ts
import { loadTranslations, locale } from '$lib/translations/translations';
import type { LayoutLoad } from './$types';
const defaultLocale = 'en'; // get from cookie, user session, ...

const initLocale = locale.get() || defaultLocale; // set default if no locale already set

export const load: LayoutLoad = async ({ url }) => {
const { pathname } = url;
const defaultLocale = 'en'; // get from cookie, user session, ...
const initLocale = locale.get() || defaultLocale; // set default if no locale already set
await loadTranslations(initLocale, pathname); // keep this just before the `return`
await loadTranslations(initLocale, pathname); // keep this just before the `return`

return {};
}
return {};
}
```
</details>

...and include your translations within pages and components.

Expand Down
38 changes: 33 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@


## Config

### `translations`?: __[Translations.T](https://github.com/sveltekit-i18n/base/blob/master/src/types.ts#L127)__
### `translations`?: __[Translations.T](https://github.com/sveltekit-i18n/base/blob/master/src/types.ts)__
This property defines translations, which should be in place before `loaders` will trigger. It's useful for synchronous translations (e.g. locally defined language names which are same for all language mutations).

### `loaders`?: __[Loader.LoaderModule[]](https://github.com/sveltekit-i18n/base/blob/master/src/types.ts#L69-L74)__
### `loaders`?: __[Loader.LoaderModule[]](https://github.com/sveltekit-i18n/base/blob/master/src/types.ts)__
You can use `loaders` to define your asyncronous translation load. All loaded data are stored so loader is triggered only once – in case there is no previous version of the translation. It can get refreshed according to `config.cache`.\
Each loader can include:

Expand All @@ -22,6 +21,35 @@ Each loader can include:

`routes`?: __Array<string | RegExp>__ – can define routes this loader should be triggered for. You can use Regular expressions too. For example `[/\/.ome/]` will be triggered for `/home` and `/rome` route as well (but still only once). Leave this `undefined` in case you want to load this module with any route (useful for common translations).

### `preprocess`?: __'full' | 'preserveArrays' | 'none' | (input: Translations.Input) => any__
Defines a preprocess strategy or a custom preprocess function. Preprocessor runs immediately after the translation data load. This is set to `'full'` by default.

Examples for input:
```json
{"a": {"b": [{"c": {"d": 1}}, {"c": {"d": 2}}]}}
```

`'full'` (default) setting will result in:
```json
{"a.b.0.c.d": 1, "a.b.1.c.d": 2}
```

`'preserveArrays'` in:
```json
{"a.b": [{"c.d": 1}, {"c.d": 2}]}
```

`'none'` (nothing's changed):
```json
{"a": {"b": [{"c": {"d": 1}}, {"c": {"d": 2}}]}}
```

Custom preprocess function `(input) => JSON.parse(JSON.stringify(input).replace('1', '"🦄"'))` will output:

```json
{"a": {"b": [{"c": {"d": "🦄"}}, {"c": {"d": 2}}]}}
```

### `initLocale`?: __string__
If you set this property, translations will be initialized immediately using this locale.

Expand All @@ -44,10 +72,10 @@ You can manage log level using this property (default: `'warn'`).
### `log.prefix`?: __string__
You can prefix output logs using this property (default: `'[i18n]: '`).

### `log.logger`?: __[Logger.T](https://github.com/sveltekit-i18n/base/blob/b488f34b2c160b62943968929c9e6e1ee642c5e8/src/types.ts#L20-L22)__
### `log.logger`?: __[Logger.T](https://github.com/sveltekit-i18n/base/blob/master/src/types.ts)__
You can setup your custom logger using this property (default: `console`).

### `parserOptions`?: __[Parser.Options](https://github.com/sveltekit-i18n/parsers/blob/53f348a82274864a5f18934f921169b76bdabfa0/parser-default/src/types.ts#L35-L38)__
### `parserOptions`?: __[Parser.Options](https://github.com/sveltekit-i18n/parsers/blob/master/parser-default/src/types.ts)__
This property includes configuration related to `@sveltekit-i18n/parser-default`.

Read more about `parserOptions` [here](https://github.com/sveltekit-i18n/parsers/tree/master/parser-default#options).
Expand Down
8 changes: 4 additions & 4 deletions examples/component-scoped-csr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"prepare": "svelte-kit sync"
},
"devDependencies": {
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"svelte": "^3.44.0",
"vite": "^3.0.2"
"@sveltejs/adapter-auto": "^2.1.0",
"@sveltejs/kit": "^1.22.1",
"svelte": "^4.0.5",
"vite": "^4.4.2"
},
"type": "module",
"dependencies": {
Expand Down
14 changes: 14 additions & 0 deletions examples/component-scoped-csr/src/routes/+layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { locale, loadTranslations } from '$lib/translations';

/** @type {import('@sveltejs/kit').Load} */
export const load = async ({ url }) => {
const { pathname } = url;

const defaultLocale = 'en'; // get from cookie / user session etc...

const initLocale = locale.get() || defaultLocale;

await loadTranslations(initLocale, pathname); // keep this just before the `return`

return {};
};
25 changes: 25 additions & 0 deletions examples/component-scoped-csr/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script>
import { writable } from 'svelte/store';
import { t, locale, locales } from '$lib/translations';

const count = writable(2);
</script>

<a href="/">{$t('menu.home')}</a>
<a href="/about">{$t('menu.about')}</a>
<br/>
<br/>
{$t('menu.notification', { count: $count })}<br />
<button on:click="{() => {if ($count) $count -= 1;}}">–</button>
<button on:click="{() => {$count += 1;}}">+</button>
<hr />
<slot />
<br />
<br />
<br />
<br />
<select bind:value="{$locale}">
{#each $locales as value}
<option value="{value}">{$t(`lang.${value}`)}</option>
{/each}
</select>
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script>
import { t } from '$lib/translations';
import Component from '$lib/component/index.svelte';
import { t } from '$lib/translations';
import Component from '$lib/component/index.svelte';

const link = 'https://kit.svelte.dev'
const link = 'https://kit.svelte.dev';
</script>

<h1>{$t('home.title')}</h1>
Expand Down
41 changes: 0 additions & 41 deletions examples/component-scoped-csr/src/routes/__layout.svelte

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import { t } from '$lib/translations';
import { t } from '$lib/translations';
</script>

<h1>{$t('about.title')}</h1>
Expand Down
8 changes: 3 additions & 5 deletions examples/component-scoped-csr/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

/** @type {import('vite').UserConfig} */
const config = {
export default defineConfig({
plugins: [sveltekit()],
};

export default config;
});
9 changes: 4 additions & 5 deletions examples/component-scoped-ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
"prepare": "svelte-kit sync"
},
"devDependencies": {
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"svelte": "^3.44.0",
"vite": "^3.0.2"
"@sveltejs/adapter-auto": "^2.1.0",
"@sveltejs/kit": "^1.22.1",
"svelte": "^4.0.5",
"vite": "^4.4.2"
},
"type": "module",
"dependencies": {
"eslint-plugin-svelte3": "^4.0.0",
"sveltekit-i18n": "file:../../"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div>
{JSON.stringify($translations)}
<p>{$t('common.info')}</p>

<select bind:value="{$locale}">
{#each $locales as locale}
<option value="{locale}">{$t(`lang.${locale}`)}</option>
Expand Down
14 changes: 14 additions & 0 deletions examples/component-scoped-ssr/src/routes/+layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { locale, loadTranslations } from '$lib/translations';

/** @type {import('@sveltejs/kit').Load} */
export const load = async ({ url }) => {
const { pathname } = url;

const defaultLocale = 'en'; // get from cookie / user session etc...

const initLocale = locale.get() || defaultLocale;

await loadTranslations(initLocale, pathname); // keep this just before the `return`

return {};
};
28 changes: 28 additions & 0 deletions examples/component-scoped-ssr/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script context="module">
import { t, locale, locales } from '$lib/translations';
</script>

<script>
import { writable } from 'svelte/store';

const count = writable(2);
</script>

<a href="/">{$t('menu.home')}</a>
<a href="/about">{$t('menu.about')}</a>
<br/>
<br/>
{$t('menu.notification', { count: $count })}<br />
<button on:click="{() => {if ($count) $count -= 1;}}">–</button>
<button on:click="{() => {$count += 1;}}">+</button>
<hr />
<slot />
<br />
<br />
<br />
<br />
<select bind:value="{$locale}">
{#each $locales as value}
<option value="{value}">{$t(`lang.${value}`)}</option>
{/each}
</select>
9 changes: 9 additions & 0 deletions examples/component-scoped-ssr/src/routes/+page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { init } from '$lib/component/index.svelte';

export const load = async () => {
const { loading: loadingEn, ...restEn } = init('en');
const { loading: loadingDe, ...restDe } = init('de');
await Promise.all([loadingEn.toPromise(), loadingDe.toPromise()]);

return { props1: { loading: loadingEn, ...restEn }, props2: { loading: loadingDe, ...restDe } };
};
Loading