amannn / next-intl

🌐 Internationalization (i18n) for Next.js
https://next-intl-docs.vercel.app
MIT License
2.58k stars 236 forks source link

`other` should be a fallback for missing values too #1337

Closed wingsofovnia closed 2 months ago

wingsofovnia commented 2 months ago

Description

When interpolating enums or other grammar rules that have other fallback for unmatched values, it does not treat an undefined value as a mismatch, instead it fails to render the whole message.

Say we have such a message (from docs):

"message": "{gender, select, female {She} male {He} other {They}} is online."

The behaviour is:

t('message', {gender: 'female'});     // "She is online."
t('message', {gender: 'male'});       // "He is online."
t('message', {gender: 'something'});  // "They is online."
t('message', {gender: undefined});    // "They is online."

// but

t('message');     // "message" - fails to render
t('message', {}); // "message" - fails to render

I am not sure if that is intentional, but it neither looks consistent to me nor behaves as one might imply from the docs:

The other case is required and will be used when none of the specific values match.

Such behaviour is useful for creating plurals of the same thing:

const messages = {
  "elf": {
    "name": "{plural, select, y {elves} other {elf}}",
  }
}

t('elf.name')                  // "elf" - doesn't work now
t('elf.name', { plural: 'y' }) // "elves"

t('elf.name', { plural: 'f' }) // "elf" - only workable solution right now, too verbose

Verifications

Mandatory reproduction URL

n/a

Reproduction description

see description

Expected behaviour

t('message');     // "They is online."
t('message', {}); // "They is online."
amannn commented 2 months ago

We rely on the behavior of intl-messageformat here, which also doesn't provide a way for customizing this. Therefore this is out of scope for next-intl.

That being said, I agree with the behavior of intl-messageformat, enabling stricter checks while still allowing undefined to be passed for edge cases as a way to bypass the check.