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

Feature request for getT: get multiple namespaces #862

Merged
merged 3 commits into from
Jun 13, 2022
Merged
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
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,8 @@ Remember that `['dynamic']` namespace should **not** be listed on `pages` config

Asynchronous function to load the `t` function outside components / pages. It works on both server-side and client-side.

Unlike the useTranslation hook, we can use here any namespace, it doesn't have to be a namespace defined in the "pages" configuration. It downloads the namespace indicated as a parameter on runtime.
Unlike the useTranslation hook, we can use here any namespace, it doesn't have to be a namespace defined in the "pages" configuration. It downloads the namespace indicated as a parameter on runtime.
You can load multiple namespaces by giving an array as a paramater, in this case the default namespace will be the fist one.

Example inside `getStaticProps`:

Expand Down Expand Up @@ -462,6 +463,23 @@ export default async function handler(req, res) {
}
```


Example of loading multiple namespaces:

```js
import getT from 'next-translate/getT'

export default async function handler(req, res) {
const t = await getT(req.query.__nextLocale, ['common', 'errors'])
const title = t('title') // The default namespace is the first one.
const errorMessage = t('errors:app_error') // The default namespace is the first one.

res.statusCode = 200
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify({ title }))
}
```

### I18nProvider

**Size**: ~3kb 📦
Expand Down
52 changes: 52 additions & 0 deletions __tests__/getT.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import getT from '../src/getT'

describe('getT', () => {
beforeAll(() => {
global.i18nConfig = {
loadLocaleFrom: (__lang, ns) => {
if (ns === 'ns1') {
return Promise.resolve({
key_ns1: 'message from ns1',
})
}
if (ns === 'ns2') {
return Promise.resolve({
key_ns2: 'message from ns2',
})
}
},
}
})

test('should load one namespace and translate', async () => {
const t = await getT('en', 'ns1')
expect(typeof t).toBe('function')

expect(t('ns1:key_ns1')).toEqual('message from ns1')
expect(t('ns2:key_ns2')).toEqual('ns2:key_ns2')
})

test('should load multiple namespaces and translate', async () => {
const t = await getT('en', ['ns1', 'ns2'])
expect(typeof t).toBe('function')

expect(t('ns1:key_ns1')).toEqual('message from ns1')
expect(t('ns2:key_ns2')).toEqual('message from ns2')
})

test('should use the only namespace as default', async () => {
const t = await getT('en', 'ns1')
expect(typeof t).toBe('function')

expect(t('key_ns1')).toEqual('message from ns1')
})

test('should use the first namespace as default', async () => {
const t = await getT('en', ['ns2', 'ns1'])
expect(typeof t).toBe('function')

expect(t('key_ns2')).toEqual('message from ns2')
expect(t('key_ns1')).toEqual('key_ns1')
expect(t('ns1:key_ns1')).toEqual('message from ns1')
})
})
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@babel/preset-env": "7.16.4",
"@babel/preset-typescript": "7.16.0",
"@testing-library/react": "12.1.2",
"@types/jest": "27.4.0",
"@types/node": "16.11.7",
"@types/react": "17.0.35",
"@types/react-dom": "17.0.11",
Expand Down
19 changes: 16 additions & 3 deletions src/getT.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,29 @@ import transCore from './transCore'
import wrapTWithDefaultNs from './wrapTWithDefaultNs'
import { I18nDictionary, LocaleLoader } from './index'

export default async function getT(locale = '', namespace = '') {
export default async function getT(
locale = '',
namespace: string | string[] = ''
) {
const config = getConfig()
const defaultLoader = async () => Promise.resolve<I18nDictionary>({})
const lang = locale || config.defaultLocale || ''
const loader: LocaleLoader = config.loadLocaleFrom || defaultLoader
const allNamespaces = { [namespace]: await loader(lang, namespace) }

const namespaces = Array.isArray(namespace) ? namespace : [namespace]

const allNamespaces: Record<string, I18nDictionary> = {}
await Promise.all(
namespaces.map(async (namespace) => {
allNamespaces[namespace] = await loader(lang, namespace)
})
)

const localesToIgnore = config.localesToIgnore || ['default']
const ignoreLang = localesToIgnore.includes(lang)
const pluralRules = new Intl.PluralRules(ignoreLang ? undefined : lang)
const t = transCore({ config, allNamespaces, pluralRules, lang })

return wrapTWithDefaultNs(t, namespace)
const defaultNamespace = namespaces[0]
return wrapTWithDefaultNs(t, defaultNamespace)
}
37 changes: 37 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,14 @@
dependencies:
"@types/istanbul-lib-report" "*"

"@types/[email protected]":
version "27.4.0"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.0.tgz#037ab8b872067cae842a320841693080f9cb84ed"
integrity sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==
dependencies:
jest-diff "^27.0.0"
pretty-format "^27.0.0"

"@types/json-schema@*", "@types/json-schema@^7.0.8":
version "7.0.9"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
Expand Down Expand Up @@ -2805,6 +2813,11 @@ diff-sequences@^27.0.6:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723"
integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==

diff-sequences@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327"
integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==

diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
Expand Down Expand Up @@ -3837,6 +3850,16 @@ jest-config@^27.3.1:
micromatch "^4.0.4"
pretty-format "^27.3.1"

jest-diff@^27.0.0:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def"
integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==
dependencies:
chalk "^4.0.0"
diff-sequences "^27.5.1"
jest-get-type "^27.5.1"
pretty-format "^27.5.1"

jest-diff@^27.3.1:
version "27.3.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.3.1.tgz#d2775fea15411f5f5aeda2a5e02c2f36440f6d55"
Expand Down Expand Up @@ -3895,6 +3918,11 @@ jest-get-type@^27.3.1:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.3.1.tgz#a8a2b0a12b50169773099eee60a0e6dd11423eff"
integrity sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==

jest-get-type@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1"
integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==

jest-haste-map@^27.3.1:
version "27.3.1"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.3.1.tgz#7656fbd64bf48bda904e759fc9d93e2c807353ee"
Expand Down Expand Up @@ -4835,6 +4863,15 @@ [email protected]:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==

pretty-format@^27.0.0, pretty-format@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==
dependencies:
ansi-regex "^5.0.1"
ansi-styles "^5.0.0"
react-is "^17.0.1"

pretty-format@^27.0.2, pretty-format@^27.3.1:
version "27.3.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.3.1.tgz#7e9486365ccdd4a502061fa761d3ab9ca1b78df5"
Expand Down