Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i18n.exists not working with nsMode fallback #1687

Open
sherman89 opened this issue Oct 13, 2023 · 4 comments
Open

i18n.exists not working with nsMode fallback #1687

sherman89 opened this issue Oct 13, 2023 · 4 comments

Comments

@sherman89
Copy link

🐛 Bug Report

i18n.exists does not fallback to other namespaces if key is not found, while t does.

It does seem to fetch from the fallbackNS set in the config, but does not use the default namespaces given to the provider.

To Reproduce

Config:

i18n
  .use(HttpApi)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    supportedLngs: languages,
    fallbackLng: defaultLanguage,
    debug: isDevelopmentEnv,
    react: {
      useSuspense: true,
      nsMode: 'fallback' // <-- Important
    },
    interpolation: {
      escapeValue: false,
      format: i18nFormatFunction
    },
    ns: ['common'],
    defaultNS: 'common',
    fallbackNS: 'common'
  });

Provider:

<I18nextProvider i18n={i18n} defaultNS={['firstNs', 'secondNs']}>
  ...
</I18nextProvider>

Usage:

const {t, i18n} = useTranslation();

i18n.exists('some.header'); // False
t('some.header'); // Works: returns correct translation from secondNs

i18n.exists('secondNs:some.header'); // True

Expected behavior

Should work same as t which knows to fallback to second default namespace since nsMode is fallback.

Your Environment

  • runtime version: Node 18.18.1, Chrome 118.0.5993.71
  • i18next version: 23.5.1
  • react-i18next version: 13.2.2
  • os: Windows 11
@jamuhl
Copy link
Member

jamuhl commented Oct 13, 2023

there is a big difference between calling t from useTranslation and calling exists on the instance (use translation uses https://github.com/i18next/i18next/blob/master/src/i18next.js#L379 with passing an array of ns in case of using nsMode: fallback)

calling i18n.t directly would give you same result

you will have to call i18n.exists('some.header', { ns: ['firstNs', 'secondNs'] }); to get same result

@sherman89
Copy link
Author

sherman89 commented Oct 14, 2023

@jamuhl Thanks for the response.

If I check i18n.reportNamespaces, it shows an array of common, firstNs, secondNs so it has loaded those namespaces but does not fallback to the second then third ones.

How do I make it do that by default, similar to passing nsMode: 'fallback' in i18n react options?

I don't want to explicitly reference secondNs in my component because the namespace it should use is decided in one of the two providers I'm using which use this same component. One solution I suppose would be to just t('defaultNamespace') and then pass that to i18n.exists but feels a bit hacky...

My setup is basically something like this:

<I18nextProvider i18n={i18n} defaultNS={['Ans', 'sharedNs']}>
  <A />
</I18nextProvider>

<I18nextProvider i18n={i18n} defaultNS={['Bns', 'sharedNs']}>
  <B />
</I18nextProvider>

The component where I do the exists check is used in both A and B, so namespace should not be fixed.

Thank you!

EDIT: Of course another solution is to just use t and check if return value is same as key, but now that we have this kind of architecture it would be nice if all of i18n played nicely with it.

@adrai adrai added the stale label Feb 17, 2024
@sherman89
Copy link
Author

Any update on this? is it my fault? I've resorted to checking if t returns the defaultValue (empty string) and then I know if value exists or not, but it would be cleaner if exists function worked with multiple namespaces.. or maybe I'm doing something wrong?

@stale stale bot removed the stale label Mar 12, 2024
@jamuhl
Copy link
Member

jamuhl commented Mar 12, 2024

nothing wrong...just like said before t on useTranslation is not same as exists on instance...so either you build a exist function that passes needed namespaces...or pass namespaces on every call to exists...

beside that not even sure what the benefit of checking exist before calling t is useful for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants