Files
heygermany-e2e-mrg5yqhb/apps/website/context/i18n-provider.tsx
e2e f0093328d8
Some checks failed
Main / Setup and Test (push) Has been cancelled
Main / Build Website (push) Has been cancelled
chore: heygermany customer project
2026-07-11 11:30:11 +02:00

76 lines
2.4 KiB
TypeScript

import React, { createContext, useContext, useMemo } from 'react'
import type { I18nString } from '@pikku/react'
import type { SupportedLocale } from '@/config'
import { mKey } from '@/i18n/messages'
import { setRouteLocale, supportedLocales, defaultLocale } from '@/i18n/config'
export type GetNamespaced = (
key: string,
variables?: Record<string, any>
) => I18nString
export interface I18nContextType {
locale: SupportedLocale
get: GetNamespaced
getEnumOptions: (
e: Record<string, string>,
enumName: string
) => { value: string; label: I18nString }[]
}
// Resolve any dotted i18n key through Paraglide (mKey snake_cases it and calls
// the compiled message). Replaces the old i18next `t`.
const get: GetNamespaced = (key, variables) => mKey(key, variables)
const getEnumOptions = (enumObject: Record<string, string>, enumName: string) =>
Object.values(enumObject).map((value) => ({
value,
label: mKey(`enums.${enumName}.${value}`.toLowerCase()),
}))
export const I18nContext = createContext<I18nContextType>({
locale: defaultLocale as SupportedLocale,
get,
getEnumOptions,
})
// useI18n() returns a callable `t` (Paraglide-backed) augmented with the same
// helpers components used under i18next: `t('key')`, `t.getEnumOptions(...)`,
// `t.locale`.
export const useI18n = () => {
const ctx = useContext(I18nContext)
const t = (key: string, variables?: Record<string, any>): I18nString =>
mKey(key, variables)
return Object.assign(t, {
get: ctx.get,
getEnumOptions: ctx.getEnumOptions,
locale: ctx.locale,
})
}
interface I18nProviderProps {
children: React.ReactNode
lang?: string
}
const normalize = (lang: string): SupportedLocale => {
const short = lang.slice(0, 2).toLowerCase()
return (
supportedLocales.includes(short as (typeof supportedLocales)[number])
? short
: defaultLocale
) as SupportedLocale
}
export function I18nProvider({ children, lang = 'en' }: I18nProviderProps) {
const locale = normalize(lang)
// Set the active Paraglide locale before children resolve messages (SSR-safe:
// synchronous, ahead of the children's render in this pass).
setRouteLocale(locale as (typeof supportedLocales)[number])
const value = useMemo<I18nContextType>(
() => ({ locale, get, getEnumOptions }),
[locale]
)
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>
}