i18next.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import path from 'path';
  2. import type { Lang } from '@growi/core';
  3. import type { InitOptions, TFunction, i18n } from 'i18next';
  4. import { createInstance } from 'i18next';
  5. import resourcesToBackend from 'i18next-resources-to-backend';
  6. import * as i18nextConfig from '^/config/i18next.config';
  7. import { resolveFromRoot } from '~/utils/project-dir-utils';
  8. import { configManager } from './config-manager';
  9. const relativePathToLocalesRoot = path.relative(__dirname, resolveFromRoot('public/static/locales'));
  10. const initI18next = async(overwriteOpts: InitOptions) => {
  11. const i18nInstance = createInstance();
  12. await i18nInstance
  13. .use(
  14. resourcesToBackend(
  15. (language: string, namespace: string) => {
  16. return import(path.join(relativePathToLocalesRoot, language, `${namespace}.json`));
  17. },
  18. ),
  19. )
  20. .init({
  21. ...i18nextConfig.initOptions,
  22. ...overwriteOpts,
  23. });
  24. return i18nInstance;
  25. };
  26. type Translation = {
  27. t: TFunction,
  28. i18n: i18n
  29. }
  30. type Opts = {
  31. lang?: Lang,
  32. ns?: string | readonly string[],
  33. }
  34. export async function getTranslation(opts?: Opts): Promise<Translation> {
  35. const globalLang = configManager.getConfig('crowi', 'app:globalLang') as Lang;
  36. const fixedLang = opts?.lang ?? globalLang;
  37. const initOptions: InitOptions = {
  38. fallbackLng: [fixedLang, i18nextConfig.defaultLang],
  39. };
  40. // set ns if not null
  41. // cz: 'ns: unefined' causes
  42. // TypeError: Cannot read properties of undefined (reading 'forEach')
  43. // at /workspace/growi/node_modules/.pnpm/i18next@23.16.5/node_modules/i18next/dist/cjs/i18next.js:1613:18"
  44. if (opts?.ns != null) {
  45. initOptions.ns = opts.ns;
  46. }
  47. const i18nextInstance = await initI18next(initOptions);
  48. return {
  49. t: i18nextInstance.getFixedT(fixedLang, opts?.ns),
  50. i18n: i18nextInstance,
  51. };
  52. }