Skip to content

Commit

Permalink
feat: improve i18next integration (#3146)
Browse files Browse the repository at this point in the history
  • Loading branch information
stepan662 authored Jan 27, 2023
1 parent e767bf9 commit d305426
Show file tree
Hide file tree
Showing 24 changed files with 116 additions and 71 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion packages/i18next/src/I18nextPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TolgeePlugin } from '@tolgee/web';

export const I18nextPlugin = (): TolgeePlugin => (tolgee) => {
tolgee.updateOptions({ ns: [] });
tolgee.updateOptions({ ns: [], defaultNs: undefined });
return tolgee;
};
80 changes: 80 additions & 0 deletions packages/i18next/src/__integration/tolgeeUpdating.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
jest.autoMockOff();

import '@testing-library/jest-dom';
import { mockCoreFetch } from '@tolgee/testing/fetchMock';
import i18n from 'i18next';
import { DevTools, Tolgee } from '@tolgee/web';
import { withTolgee, I18nextPlugin } from '..';

const API_URL = 'http://localhost';
const API_KEY = 'dummyApiKey';

const fetch = mockCoreFetch();

describe('withTolgee', () => {
let i18next: typeof i18n;
beforeEach(async () => {
fetch.enableMocks();
});

afterEach(() => {
i18next?.tolgee?.stop();
});

it('loads static data first', async () => {
const tolgee = Tolgee()
.use(DevTools())
.use(I18nextPlugin())
.init({
staticData: {
'en:translation': {
hello_world: 'Hello static!',
},
},
});

i18next = withTolgee(i18n.createInstance(), tolgee);
await i18next.init({ lng: 'en', supportedLngs: ['en'] });
expect(i18next.t('hello_world')).toContain('Hello static!');
});

it('loads dev data over static data', async () => {
const tolgee = Tolgee()
.use(DevTools())
.use(I18nextPlugin())
.init({
apiUrl: API_URL,
apiKey: API_KEY,
staticData: {
'en:translation': {
hello_world: 'Hello static!',
},
},
});

i18next = withTolgee(i18n.createInstance(), tolgee);
await i18next.init({ lng: 'en', supportedLngs: ['en'] });
expect(i18next.t('hello_world')).toContain('Hello world!');
});

it('loads dev data on lang change', async () => {
const tolgee = Tolgee()
.use(DevTools())
.use(I18nextPlugin())
.init({
apiUrl: API_URL,
apiKey: API_KEY,
staticData: {
'en:translation': {
hello_world: 'Hello static!',
},
},
});

i18next = withTolgee(i18n.createInstance(), tolgee);
await i18next.init({ lng: 'en', supportedLngs: ['en', 'cs'] });
expect(i18next.t('hello_world')).toContain('Hello world!');
await i18next.changeLanguage('cs');
expect(i18next.t('hello_world')).toContain('Ahoj světe!');
});
});
9 changes: 5 additions & 4 deletions packages/i18next/src/tolgeeApply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { i18n } from 'i18next';
export const tolgeeApply = (tolgee: TolgeeInstance, i18n: i18n) => {
const updateTranslations = () => {
tolgee.getAllRecords().forEach(({ language, namespace, data }) => {
const ns = namespace || 'translation';
i18n.removeResourceBundle(language, ns);
i18n.addResources(language, ns, Object.fromEntries(data));
if (i18n.getResourceBundle(language, namespace)) {
i18n.removeResourceBundle(language, namespace);
i18n.addResources(language, namespace, Object.fromEntries(data));
}
});
};

tolgee.on('initialLoad', updateTranslations);
tolgee.on('update', updateTranslations);
i18n.on('languageChanged', (lang) => {
if (lang && tolgee.getLanguage() !== lang) {
tolgee.changeLanguage(lang);
Expand Down
2 changes: 1 addition & 1 deletion packages/i18next/src/tolgeeBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const tolgeeBackend = (tolgee: TolgeeInstance): Module => {
try {
const translations = await tolgee.loadRecord({
language,
namespace: ns === 'translation' ? '' : ns,
namespace: ns,
});
callback(null, Object.fromEntries(translations));
} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions packages/i18next/src/tolgeeProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const tolgeeProcessor = (tolgee: TolgeeInstance): Module => {
key: key.join('.'),
defaultValue: options.defaultValue,
translation: value,
ns: options.ns,
});
},
} as any as Module;
Expand Down
12 changes: 10 additions & 2 deletions packages/testing/fetchMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,22 @@ export const mockCoreFetchAsync = () => {
const fetch = fetchMock.mockResponse((req) => {
if (req.url.includes('/v2/api-keys/current')) {
return result.currentApiKey.promise;
} else if (req.url.includes('/v2/projects/translations/en')) {
} else if (
req.url.includes('/v2/projects/translations/en?ns=translation')
) {
return result.enTranslations.promise;
} else if (req.url.includes('/v2/projects/translations/cs')) {
} else if (
req.url.includes('/v2/projects/translations/cs?ns=translation')
) {
return result.csTranslations.promise;
} else if (req.url.includes('/v2/projects/translations/en?ns=test')) {
return result.enTranslations.promise;
} else if (req.url.includes('/v2/projects/translations/cs?ns=test')) {
return result.csTranslations.promise;
} else if (req.url.includes('/v2/projects/translations/en')) {
return result.enTranslations.promise;
} else if (req.url.includes('/v2/projects/translations/cs')) {
return result.csTranslations.promise;
}

throw new Error('Invalid request');
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 1 addition & 3 deletions testapps/react-i18next/src/Todos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ export const Todos = () => {
<div className="example">
<Navbar>
<a href="/translation-methods">
{t('menu-item-translation-methods', {
defaultValue: 'Translation methods',
})}
{t('menu-item-translation-methods')}
</a>
</Navbar>

Expand Down
12 changes: 0 additions & 12 deletions testapps/react-i18next/src/i18n/de.json

This file was deleted.

12 changes: 0 additions & 12 deletions testapps/react-i18next/src/i18n/en.json

This file was deleted.

12 changes: 0 additions & 12 deletions testapps/react-i18next/src/i18n/fr.json

This file was deleted.

12 changes: 0 additions & 12 deletions testapps/vue-i18next/i18n/cs.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"send-via-email" : "Odeslat e-mailem",
"share-button" : "Sdílet",
"this_is_a_key" : "Toto je klíč",
"this_is_a_key_with_params" : "Toto je klíč s parametry {key} {key2}"
"this_is_a_key_with_params" : "Toto je klíč s parametry {key} {key2}",
"this_is_a_key_with_tags" : "Toto je klíč s tagy <b>bold</b> <b><i>{key}</i></b>"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"send-via-email" : "Per Email abschicken",
"share-button" : "Teilen",
"this_is_a_key" : "Dies ist ein Schlüssel",
"this_is_a_key_with_params" : "Dies ist ein Schlüssel mit den Parametern {key} {key2}"
"this_is_a_key_with_params" : "Dies ist ein Schlüssel mit den Parametern {key} {key2}",
"this_is_a_key_with_tags" : "Dies ist ein Schlüssel mit den Tags <b>bold</b> <b><i>{key}</i></b>"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"send-via-email" : "Send via e-mail",
"share-button" : "Share",
"this_is_a_key" : "This is a key",
"this_is_a_key_with_params" : "This is key with params {key} {key2}"
"this_is_a_key_with_params" : "This is key with params {key} {key2}",
"this_is_a_key_with_tags" : "This is a key with tags <b>bold</b> <b><i>{key}</i></b>"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"send-via-email" : "Envoyer par courriel",
"share-button" : "Partager",
"this_is_a_key" : "C'est une clé",
"this_is_a_key_with_params" : "C'est la clé avec les paramètres {key} {key2}"
}
"this_is_a_key_with_params" : "C'est la clé avec les paramètres {key} {key2}",
"this_is_a_key_with_tags" : "C'est la clé avec des tags <b>bold</b> <b><i>{key}</i></b>"
}
15 changes: 8 additions & 7 deletions testapps/vue-i18next/src/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import Vue from 'vue';
import { DevTools, I18nextPlugin, Tolgee, withTolgee } from '@tolgee/i18next';
import {
DevTools,
I18nextPlugin,
Tolgee,
BackendFetch,
withTolgee,
} from '@tolgee/i18next';
import { FormatIcu } from '@tolgee/format-icu';
import i18next from 'i18next';
import ICU from 'i18next-icu';
Expand All @@ -9,17 +15,12 @@ import App from './App.vue';

const tolgee = Tolgee()
.use(DevTools())
.use(BackendFetch())
.use(I18nextPlugin())
.use(FormatIcu())
.init({
apiUrl: process.env.VUE_APP_TOLGEE_API_URL,
apiKey: process.env.VUE_APP_TOLGEE_API_KEY,
staticData: {
en: () => import('../i18n/en.json'),
de: () => import('../i18n/de.json'),
fr: () => import('../i18n/fr.json'),
cs: () => import('../i18n/cs.json'),
},
});

Vue.use(VueI18Next);
Expand Down

0 comments on commit d305426

Please sign in to comment.