diff --git a/__tests__/transCore.test.js b/__tests__/transCore.test.js index 18fcbe0..ed9caeb 100644 --- a/__tests__/transCore.test.js +++ b/__tests__/transCore.test.js @@ -25,6 +25,10 @@ const nsWithEmpty = { emptyKey: '', } +const nsConflictWithKeySeparatorKey = { + 'key likes sentence.': 'message 1 conflict', +} + describe('transCore', () => { test('should return an object of root keys', async () => { const t = transCore({ @@ -153,4 +157,17 @@ describe('transCore', () => { expect(typeof t).toBe('function') expect(t('nsWithEmpty:emptyKey')).toEqual('nsWithEmpty:emptyKey') }) + + test('should return key string when key conficts with separator and log warning.', () => { + const t = transCore({ + config: {}, + allNamespaces: { nsConflictWithKeySeparatorKey }, + lang: 'en', + }) + + expect(typeof t).toBe('function') + expect(t('nsConflictWithKeySeparatorKey:key likes sentence.')).toEqual( + 'nsConflictWithKeySeparatorKey:key likes sentence.' + ) + }) }) diff --git a/src/index.tsx b/src/index.tsx index 20ef5dc..809f9d4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -96,6 +96,7 @@ export interface LoaderConfig extends I18nConfig { export interface LoggerProps { namespace: string | undefined i18nKey: string + isKeyConflictWithKeySeparator?: boolean } export interface I18nLogger { diff --git a/src/transCore.tsx b/src/transCore.tsx index 3f5a40a..e3f3c43 100644 --- a/src/transCore.tsx +++ b/src/transCore.tsx @@ -57,7 +57,11 @@ export default function transCore({ const t: Translate = (key = '', query, options) => { const k = Array.isArray(key) ? key[0] : key - const { nsSeparator = ':', loggerEnvironment = 'browser' } = config + const { + nsSeparator = ':', + loggerEnvironment = 'browser', + keySeparator = '.', + } = config const { i18nKey, namespace = options?.ns ?? config.defaultNS } = splitNsKey( k, @@ -77,6 +81,17 @@ export default function transCore({ (typeof value === 'object' && !Object.keys(value).length) || (value === '' && !allowEmptyStrings) + const keyParts = keySeparator + ? keyWithPlural.split(keySeparator) + : [keyWithPlural] + + const isKeyConflictWithKeySeparator = + keyWithPlural === keySeparator && options?.returnObjects + ? false + : !!keySeparator && + keyWithPlural.includes(keySeparator) && + !keyParts.at(-1) + const fallbacks = typeof options?.fallback === 'string' ? [options.fallback] @@ -88,7 +103,7 @@ export default function transCore({ loggerEnvironment === (typeof window === 'undefined' ? 'node' : 'browser')) ) { - logger({ namespace, i18nKey }) + logger({ namespace, i18nKey, isKeyConflictWithKeySeparator }) } // Fallbacks @@ -268,7 +283,11 @@ function objectInterpolation({ return obj } -function missingKeyLogger({ namespace, i18nKey }: LoggerProps): void { +function missingKeyLogger({ + namespace, + i18nKey, + isKeyConflictWithKeySeparator, +}: LoggerProps): void { if (process.env.NODE_ENV === 'production') return // This means that instead of "ns:value", "value" has been misspelled (without namespace) @@ -278,6 +297,13 @@ function missingKeyLogger({ namespace, i18nKey }: LoggerProps): void { ) return } + // This means that key named likes "i am a sentence." will be regarded as nested keys which losts the last part of the key + if (isKeyConflictWithKeySeparator) { + console.warn( + `[next-translate] "${i18nKey}" is missing its last part of the key after key separator.` + ) + return + } console.warn( `[next-translate] "${namespace}:${i18nKey}" is missing in current namespace configuration. Try adding "${i18nKey}" to the namespace "${namespace}".` )