useI18n
'use client';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useI18nState } from '@/i18n/I18nProvider';
import { TranslationVariables } from '@/i18n/I18nProvider/typing';
import { I18nNamespaces } from '@/i18n/settings';
type CamelCase<S extends string> = S extends `${infer Head}-${infer Tail}`
? `${Head}${Capitalize<CamelCase<Tail>>}`
: S;
type AppendT<S extends string> = `${S}T`;
type ConvertArrayToCamelCaseWithT<T extends readonly string[]> = {
[K in keyof T]: AppendT<CamelCase<T[K]>>;
}[number];
export const useI18n = <T extends I18nNamespaces>(ns: T[]) => {
const { lng } = useI18nState();
const { t } = useTranslation();
const translator = useMemo(() => {
return ns.reduce(
(acc, cur) => {
acc[`${convertKebabCaseToCamelCase(cur)}T` as keyof typeof acc] = (
key: string,
variables?: TranslationVariables,
) => t(key, { ns: cur, lng, ...(typeof variables !== 'undefined' ? variables : {}) });
return acc;
},
{} as Record<ConvertArrayToCamelCaseWithT<typeof ns>, (key: string, variables?: TranslationVariables) => string>,
);
}, [lng, ns, t]);
return translator;
};
function convertKebabCaseToCamelCase(input: string) {
return input
.split('-')
.map((word, index) => {
if (index === 0) {
return word;
}
return word.charAt(0).toUpperCase() + word.slice(1);
})
.join('') as CamelCase<string>;
}