Add check for duplicate locales (#37485)

## Bug

- [X] Related issues linked using `fixes #37483`
- [ ] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`

Duplicate locales will lead to an obscure error message at build time, here I caught them earlier.
Using a Set sounded the terser and fastest approach, but it won't tell which locale is duplicated.

Also I've noticed that the "Array.isArray" check happens twice on i18n.locales? Maybe it's on purpose?

Fixes #37483 

Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
This commit is contained in:
Eric Burel 2022-06-07 19:58:19 +02:00 committed by GitHub
parent 5d0c3edda3
commit 42f838e156
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 0 deletions

View file

@ -638,6 +638,26 @@ function assignDefaults(userConfig: { [key: string]: any }) {
)
}
const normalizedLocales = new Set()
const duplicateLocales = new Set()
i18n.locales.forEach((locale) => {
const localeLower = locale.toLowerCase()
if (normalizedLocales.has(localeLower)) {
duplicateLocales.add(locale)
}
normalizedLocales.add(localeLower)
})
if (duplicateLocales.size > 0) {
throw new Error(
`Specified i18n.locales contains the following duplicate locales:\n` +
`${[...duplicateLocales].join(', ')}\n` +
`Each locale should be listed only once.\n` +
`See more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
// make sure default Locale is at the front
i18n.locales = [
i18n.defaultLocale,

View file

@ -583,4 +583,25 @@ describe('i18n Support', () => {
'Both fr.example.com and french.example.com configured the defaultLocale fr but only one can'
)
})
it('should show proper error for duplicate locales', async () => {
nextConfig.write(`
module.exports = {
i18n: {
locales: ['en', 'fr', 'nl', 'eN', 'fr'],
defaultLocale: 'en',
}
}
`)
const { code, stderr } = await nextBuild(appDir, undefined, {
stderr: true,
})
nextConfig.restore()
expect(code).toBe(1)
expect(stderr).toContain(
'Specified i18n.locales contains the following duplicate locales:'
)
expect(stderr).toContain(`eN, fr`)
})
})