import { createInstance } from 'i18next' import { initReactI18next } from 'react-i18next' import ainuNavigation from '@/locales/ain-Kana/navigation.json' import ainuCommon from '@/locales/ain-Kana/common.json' import ainuTags from '@/locales/ain-Kana/tags.json' import nipponeseNavigation from '@/locales/ja/navigation.json' import nipponeseCommon from '@/locales/ja/common.json' import nipponeseTags from '@/locales/ja/tags.json' import type { LocaleCode } from '@/lib/locales' export const i18n = createInstance () // Keep Japanese placeholders editable without reporting them as completed translations. const translatedResource = (resource: Record): Record => { const untranslated = new Set ( Array.isArray (resource._untranslated) ? resource._untranslated : []) const select = (entries: Record, prefix = ''): Record => Object.fromEntries (Object.entries (entries).flatMap (([key, value]) => { const path = prefix ? `${ prefix }.${ key }` : key if (key === '_untranslated' || untranslated.has (path)) return [] const translated = (value != null && typeof value === 'object' && !(Array.isArray (value))) ? select (value as Record, path) : value return [[key, translated]] })) return select (resource) } void i18n.use (initReactI18next).init ({ lng: 'ja', fallbackLng: 'ja', supportedLngs: ['ja', 'ain-Kana'], load: 'currentOnly', initAsync: false, defaultNS: 'navigation', ns: ['navigation', 'common', 'tags'], resources: { ja: { navigation: nipponeseNavigation, common: nipponeseCommon, tags: nipponeseTags }, 'ain-Kana': { navigation: ainuNavigation, common: translatedResource (ainuCommon), tags: translatedResource (ainuTags) } }, interpolation: { escapeValue: false }, returnNull: false, returnEmptyString: false, saveMissing: import.meta.env.DEV, missingKeyHandler: (languages, namespace, key) => { console.warn ('[i18n] missing key', { languages, namespace, key }) }, react: { useSuspense: false } }) export const untranslatedKeys = ( locale: LocaleCode, namespace = 'navigation', ): string[] => { const collect = (resource: Record, prefix = ''): string[] => Object.entries (resource).flatMap (([key, value]) => { const path = prefix ? `${ prefix }.${ key }` : key return (value != null && typeof value === 'object') ? collect (value as Record, path) : [path] }) const baseline = i18n.getResourceBundle ('ja', namespace) ?? { } return collect (baseline).filter (key => { const value = i18n.getResource (locale, namespace, key) return typeof value !== 'string' || value.length === 0 }) } if (import.meta.env.DEV) { for (const namespace of ['navigation', 'common', 'tags']) { const missing = untranslatedKeys ('ain-Kana', namespace) if (missing.length > 0) console.warn (`[i18n] ain-Kana: untranslated ${ namespace } keys`, missing) } }