feat: 🎸 make getClientLocale tree-shakeable

BREAKING CHANGE: It's now needed to explicitly import the `getClientLocale` method to use
its heuristics when setting the initial locale. This makes the method
and its helpers to be tree-shakeable.

```js
import { init, getClientLocale } from 'svelte-i18n'

init({
  initialLocale: getClientLocale({ ... })
})
```
This commit is contained in:
Christian Kaisermann 2020-01-21 10:59:26 -03:00
parent f3b88f90ab
commit 4881acb7b3
6 changed files with 59 additions and 61 deletions

View File

@ -64,7 +64,7 @@ After populating your [`$dictionary`](/docs/Dictionary.md) with [`addMessages()`
```js ```js
// src/i18n.js // src/i18n.js
import { register, init } from 'svelte-i18n' import { register, init, getClientLocale } from 'svelte-i18n'
register('en', () => import('./en.json')) register('en', () => import('./en.json'))
register('en-US', () => import('./en-US.json')) register('en-US', () => import('./en-US.json'))
@ -73,9 +73,9 @@ register('pt', () => import('./pt.json'))
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
initialLocale: { initialLocale: getClientLocale({
navigator: true, // i.e 'en-US' navigator: true, // i.e 'en-US'
}, }),
}) })
// starts loading 'en-US' and 'en' // starts loading 'en-US' and 'en'
``` ```

View File

@ -10,46 +10,24 @@ Method responsible for configuring some of the library behaviours such as the gl
interface InitOptions { interface InitOptions {
// the global fallback locale // the global fallback locale
fallbackLocale: string fallbackLocale: string
// set of heuristic configs to define the client's locale // the app initial locale
initialLocale?: InitialLocaleOptions initialLocale?: string
// custom time/date/number formats // custom time/date/number formats
formats?: Formats formats?: Formats
// loading delay interval // loading delay interval
loadingDelay?: number loadingDelay?: number
} }
interface InitialLocaleOptions {
// the fallback locale to use if no message is found in the current one
fallback?: string
// when 'true', check the 'window.navigator.language' to set the current locale
navigator?: boolean
// key to look for a locale on 'window.location.search'
// 'example.com?locale=en-US'
search?: string
// key to look for a locale on 'window.location.hash'
// 'example.com#locale=en-US'
hash?: string
// pattern to look in the window.location.pathname.
// It returns the first capturing group.
pathname?: RegExp
// pattern to look in the window.location.hostname.
// It returns the first capturing group.
hostname?: RegExp
}
``` ```
**Example**: **Example**:
```js ```js
import { init } from 'svelte-i18n' import { init, getClientLocale } from 'svelte-i18n'
init({ init({
// fallback to en if current locale is not in the dictionary // fallback to en if current locale is not in the dictionary
fallbackLocale: 'en', fallbackLocale: 'en',
initialLocale: { initialLocale: 'pt-br',
// based on the user's browser
navigator: true,
},
}) })
``` ```
@ -90,6 +68,50 @@ init({
<!-- 123.456,79 € --> <!-- 123.456,79 € -->
``` ```
#### getClientLocale
> `import { getClientLocale } from 'svelte-i18n'`
`getClientLocale(options: GetClientLocaleOptions): void`
Optional utility method to help getting the initial locale of a user. Use it together with the [`init()`](#init) method.
```ts
interface GetClientLocaleOptions {
// the fallback locale to use if no message is found in the current one
fallback?: string
// when 'true', check the 'window.navigator.language' to set the current locale
navigator?: boolean
// key to look for a locale on 'window.location.search'
// 'example.com?locale=en-US'
search?: string
// key to look for a locale on 'window.location.hash'
// 'example.com#locale=en-US'
hash?: string
// pattern to look in the window.location.pathname.
// It returns the first capturing group.
pathname?: RegExp
// pattern to look in the window.location.hostname.
// It returns the first capturing group.
hostname?: RegExp
}
```
**Example**:
```js
import { init, getClientLocale } from 'svelte-i18n'
init({
// fallback to en if current locale is not in the dictionary
fallbackLocale: 'en',
initialLocale: getClientLocale({
// based on the user's browser
navigator: true,
}),
})
```
#### addMessages #### addMessages
`import { addMessages } from 'svelte-i18n` `import { addMessages } from 'svelte-i18n`

View File

@ -1,4 +1,3 @@
import { getClientLocale } from './includes/getClientLocale'
import { ConfigureOptions } from './types' import { ConfigureOptions } from './types'
import { $locale } from './stores/locale' import { $locale } from './stores/locale'
@ -63,11 +62,7 @@ export function getOptions() {
export function init(opts: ConfigureOptions) { export function init(opts: ConfigureOptions) {
const { formats, ...rest } = opts const { formats, ...rest } = opts
const initialLocale = opts.initialLocale const initialLocale = opts.initialLocale || opts.fallbackLocale
? typeof opts.initialLocale === 'string'
? opts.initialLocale
: getClientLocale(opts.initialLocale) || opts.fallbackLocale
: opts.fallbackLocale
Object.assign(options, rest, { initialLocale }) Object.assign(options, rest, { initialLocale })

View File

@ -13,6 +13,7 @@ export function waitLocale(locale?: string) {
} }
export { init } from './configs' export { init } from './configs'
export { getClientLocale } from './includes/getClientLocale'
export { $locale as locale } from './stores/locale' export { $locale as locale } from './stores/locale'

View File

@ -29,25 +29,6 @@ test('inits the initial locale by string', () => {
expect(get($locale)).toBe('en') expect(get($locale)).toBe('en')
}) })
test('inits the initial locale by client heuristics', () => {
delete window.location
window.location = {
search: '?lang=en-US&foo',
pathname: '/',
hostname: 'example.com',
hash: '',
} as any
init({
fallbackLocale: 'pt',
initialLocale: {
search: 'lang',
},
})
expect(getOptions().initialLocale).toBe('en-US')
expect(get($locale)).toBe('en-US')
})
test('adds custom formats for time, date and number values', () => { test('adds custom formats for time, date and number values', () => {
const customFormats = require('../fixtures/formats.json') const customFormats = require('../fixtures/formats.json')

View File

@ -8,10 +8,11 @@ import {
getCurrentLocale, getCurrentLocale,
$locale, $locale,
isRelatedLocale, isRelatedLocale,
} from '../../../src/runtime/stores/locale' } from '../../../src/client/stores/locale'
import { getOptions, init } from '../../../src/runtime/configs' import { getOptions, init } from '../../../src/client/configs'
import { register } from '../../../src/runtime' import { register } from '../../../src/client'
import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue' import { hasLocaleQueue } from '../../../src/client/includes/loaderQueue'
import { getClientLocale } from '../../../src/client/includes/getClientLocale'
beforeEach(() => { beforeEach(() => {
init({ fallbackLocale: undefined }) init({ fallbackLocale: undefined })
@ -113,9 +114,7 @@ test('if no initial locale is set, set the locale to the fallback', () => {
test('if no initial locale was found, set to the fallback locale', () => { test('if no initial locale was found, set to the fallback locale', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
initialLocale: { initialLocale: null,
hash: 'lang',
},
}) })
expect(get($locale)).toBe('en') expect(get($locale)).toBe('en')
expect(getOptions().fallbackLocale).toBe('en') expect(getOptions().fallbackLocale).toBe('en')