Skip to main content
Glama
useI18n.ts2.67 kB
'use client'; import { getIntlayer, type ValidDotPathsFor } from '@intlayer/core'; import type { DeclaredLocales, DictionaryKeys, DictionaryRegistryContent, GetSubPath, LocalesValues, } from '@intlayer/types'; import { useContext, useMemo } from 'react'; import type { DeepTransformContent } from '../plugins'; import { IntlayerClientContext } from './IntlayerProvider'; /** * Hook that provides a translation function `t()` for accessing nested content by key. * This hook mimics the pattern found in libraries like i18next, next-intl, and vue-i18n. * * @param namespace - The dictionary key to scope translations to * @param locale - Optional locale override. If not provided, uses the current context locale * @returns A translation function `t(key)` that returns the translated content for the given key * * @example * ```tsx * const t = useI18n('IndexPage'); * const title = t('title'); // Returns translated string for 'IndexPage.title' * const nestedContent = t('section.subtitle'); // Returns 'IndexPage.section.subtitle' * // For attributes like `aria-label`, use `.value` to get the plain string * const ariaLabel = t('button.ariaLabel').value; // 'Close modal' * ``` */ export const useI18n = < T extends DictionaryKeys, L extends LocalesValues = DeclaredLocales, >( namespace: T, locale?: L ) => { const { locale: currentLocale } = useContext(IntlayerClientContext); const localeTarget = useMemo( () => locale ?? currentLocale, [currentLocale, locale] ); // Get the dictionary content for the namespace // @ts-ignore Type instantiation is excessively deep and possibly infinite const dictionaryContent: DeepTransformContent<DictionaryRegistryContent<T>> = useMemo( () => getIntlayer<T, L>(namespace, localeTarget as L), [namespace, localeTarget] ); // Return the translation function // @ts-ignore Type instantiation is excessively deep and possibly infinite const t = <P extends ValidDotPathsFor<T>>( path: P // @ts-ignore Type instantiation is excessively deep and possibly infinite ): GetSubPath<DeepTransformContent<DictionaryRegistryContent<T>>, P> => { if (!path) { // @ts-ignore Type instantiation is excessively deep and possibly infinite return dictionaryContent as any; } const pathArray = (path as string).split('.'); let current: any = dictionaryContent; for (const key of pathArray) { current = current?.[key]; if (current === undefined) { // Return the whole dictionary as fallback if path is not found return dictionaryContent as any; } } return current; }; return t; };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server