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

i18next.changeLanguage() changes only in-components locale, added by useTranslation #2171

Closed
Edymov opened this issue Jun 6, 2023 · 13 comments

Comments

@Edymov
Copy link

Edymov commented Jun 6, 2023

🐛 Bug Report

I am using next-i18next in two ways in my app - via t from useTranslation hook in components and using t from i18next in outside components file.

The problem is with locale changing.
I use i18next.changeLocation to change location. As a result, location changes only in in-component translation with useTranslation hook. Outside components translations don`t refresh at all. They resfreshing only after page reloading, what does not suit me.

To Reproduce

// file one (in-component translation)

import {  useTranslation } from 'next-i18next';

const Page = () => {
  const { t } = useTranslation('common')
 
  return <div>{t('cat)}</div>
}
// file two (non-component)

import { t } from 'i18next';

const translations = [
  frog: t('frog'),
  ship: t('ship'),
  sky: t(''sky)
]

Expected behavior

Language changes in both cases in and outside components

Your Environment

  • runtime version: node v16.15.1, Chrome 114, Next 12.1.6
  • i18next version: 22.4.15
  • next-i18next version: 13.0.3
  • os: Win10
@adrai
Copy link
Member

adrai commented Jun 6, 2023

Personally, I would not use the changeLanguage function in a next-i18next project...
Always use link or navigate: #2169 (comment)

There is no global i18next instance... some pieces are coming from server side and some from client side... so if you navigate to the correct languge page that would guarantee the new lnguage on all elements.

@Edymov
Copy link
Author

Edymov commented Jun 6, 2023

Personally, I would not use the changeLanguage function in a next-i18next project... Always use link or navigate: #2169 (comment)

There is no global i18next instance... some pieces are coming from server side and some from client side... so if you navigate to the correct languge page that would guarantee the new lnguage on all elements.

I used changeLanguage just in order to translate non-component translations. Before i added this, it does not refreshed at all, even after reload.
Where can i get instance of non-component translations? I thought it in i18next.

Maybe it makes sence, i initialized i18next in i18n.ts file:

import english from 'public/locales/en/common.json';
import pl from 'public/locales/pl/common.json';

i18n
  .use(Backend)
  .use(Cache)
  .use(LanguageDetector)
  .init({
    debug: false,
    defaultNS: 'common',
    fallbackLng: 'pl',

    interpolation: {
      escapeValue: false
    },

    ns: ['common'],

    resources: {
      en: {
        common: {
          ...english
        }
      },
      pl: {
        common: {
          ...pl
        }
      }
    }
  });

@adrai
Copy link
Member

adrai commented Jun 6, 2023

Looks not to be a typical next-i18next project...
Please compare with the simple example in this repo.

@Edymov
Copy link
Author

Edymov commented Jun 6, 2023

I compared it. The typical case (useTranslation hook) works. But by i can`t understand how to proper use next-18next outside functional components.

I don`t think, that all next-i18next users using only in-components translations using useTranslation

@Edymov Edymov closed this as completed Jun 6, 2023
@Edymov Edymov reopened this Jun 6, 2023
@adrai
Copy link
Member

adrai commented Jun 6, 2023

There is no "good" way to use i18next outside...
#2079 (comment)

@stale
Copy link

stale bot commented Jun 15, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 15, 2023
@KoJaem
Copy link

KoJaem commented Jul 14, 2023

@Edymov
Not exactly, but I had a similar situation and it worked out.

In non-component code
Can you try this? import { i18n } from 'next-i18next';

import { i18n } from 'next-i18next';

const translations = [
  frog: i18n?.t('frog'),
  ship: i18n?.t('ship'),
  sky: i18n?.t(''sky)
]

@stale stale bot removed the stale label Jul 14, 2023
@stale
Copy link

stale bot commented Aug 12, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Aug 12, 2023
@Edymov
Copy link
Author

Edymov commented Sep 13, 2023

@Edymov Not exactly, but I had a similar situation and it worked out.

In non-component code Can you try this? import { i18n } from 'next-i18next';

import { i18n } from 'next-i18next';

const translations = [
  frog: i18n?.t('frog'),
  ship: i18n?.t('ship'),
  sky: i18n?.t(''sky)
]

I think, it`s not enough. It also necessary to init i18n. Without this it returns undefined

@stale stale bot removed the stale label Sep 13, 2023
@allanortiz
Copy link

allanortiz commented Sep 30, 2023

When I change the locale with i18n.changeLanguage, i18n.language changes but no translation. Only works by redirecting. How can I solve this? I need to change the language without redirect the user. Can I change de default language? Is this issue apply to me?

const domainDetector = {
  // We use the name to refer to it later when we want to tell i18next when to use it.
  name: 'domain',
  lookupDomain(req, res, options) {
    return 'professional'
    }
};
    
module.exports = {
  debug: process.env.NODE_ENV === 'development',
  i18n: {
    defaultLocale: 'es',  <------- ONLY UPDATING THIS WORKS, OR REDIRECTING USER TO SPECIFIC LANGUAGE PATH
    locales: ['es', 'professional'],
  },
  reloadOnPrerender: process.env.NODE_ENV === 'development',
  localePath: path.resolve('./public/locales'),
  serializeConfig: false,
  customDetectors: [domainDetector],
  // Register our custom language detector
  // Tell i18next to _only_ use our custom language detector.
  // https://github.com/i18next/i18next-http-middleware#detector-options
  detection: {
    order: ["domain"]
  },
  localeDetection: false,
}
<div>
   Testing: {t('test')}
      <div>{i18n.language}</div>
      
      <button
        className="bg-red-500"
        onClick={() => {
          i18n.changeLanguage('es');
        }}
      >
        Change to es
      </button>
      
      <button
        className="bg-red-500"
        onClick={() => {
          i18n.changeLanguage('professional');
        }}
      >
        Change to pro
      </button>
 </div>

In the last code, t('test') always has the default language value, never changes. But i18n.language does.

@stale
Copy link

stale bot commented Oct 15, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Oct 15, 2023
@MONTYYYYY
Copy link

When I change the locale with i18n.changeLanguage, i18n.language changes but no translation. Only works by redirecting. How can I solve this? I need to change the language without redirect the user. Can I change de default language? Is this issue apply to me?

const domainDetector = {
  // We use the name to refer to it later when we want to tell i18next when to use it.
  name: 'domain',
  lookupDomain(req, res, options) {
    return 'professional'
    }
};
    
module.exports = {
  debug: process.env.NODE_ENV === 'development',
  i18n: {
    defaultLocale: 'es',  <------- ONLY UPDATING THIS WORKS, OR REDIRECTING USER TO SPECIFIC LANGUAGE PATH
    locales: ['es', 'professional'],
  },
  reloadOnPrerender: process.env.NODE_ENV === 'development',
  localePath: path.resolve('./public/locales'),
  serializeConfig: false,
  customDetectors: [domainDetector],
  // Register our custom language detector
  // Tell i18next to _only_ use our custom language detector.
  // https://github.com/i18next/i18next-http-middleware#detector-options
  detection: {
    order: ["domain"]
  },
  localeDetection: false,
}
<div>
   Testing: {t('test')}
      <div>{i18n.language}</div>
      
      <button
        className="bg-red-500"
        onClick={() => {
          i18n.changeLanguage('es');
        }}
      >
        Change to es
      </button>
      
      <button
        className="bg-red-500"
        onClick={() => {
          i18n.changeLanguage('professional');
        }}
      >
        Change to pro
      </button>
 </div>

In the last code, t('test') always has the default language value, never changes. But i18n.language does.

have you found solution yet? Experiencing the same problem.

@allanortiz
Copy link

allanortiz commented Oct 23, 2023

When I change the locale with i18n.changeLanguage, i18n.language changes but no translation. Only works by redirecting. How can I solve this? I need to change the language without redirect the user. Can I change de default language? Is this issue apply to me?

const domainDetector = {
  // We use the name to refer to it later when we want to tell i18next when to use it.
  name: 'domain',
  lookupDomain(req, res, options) {
    return 'professional'
    }
};
    
module.exports = {
  debug: process.env.NODE_ENV === 'development',
  i18n: {
    defaultLocale: 'es',  <------- ONLY UPDATING THIS WORKS, OR REDIRECTING USER TO SPECIFIC LANGUAGE PATH
    locales: ['es', 'professional'],
  },
  reloadOnPrerender: process.env.NODE_ENV === 'development',
  localePath: path.resolve('./public/locales'),
  serializeConfig: false,
  customDetectors: [domainDetector],
  // Register our custom language detector
  // Tell i18next to _only_ use our custom language detector.
  // https://github.com/i18next/i18next-http-middleware#detector-options
  detection: {
    order: ["domain"]
  },
  localeDetection: false,
}
<div>
   Testing: {t('test')}
      <div>{i18n.language}</div>
      
      <button
        className="bg-red-500"
        onClick={() => {
          i18n.changeLanguage('es');
        }}
      >
        Change to es
      </button>
      
      <button
        className="bg-red-500"
        onClick={() => {
          i18n.changeLanguage('professional');
        }}
      >
        Change to pro
      </button>
 </div>

In the last code, t('test') always has the default language value, never changes. But i18n.language does.

have you found solution yet? Experiencing the same problem.

I had to add the extra language in serverSideTranslations (in getStaticProps of the page):

const translations = await serverSideTranslations(
      context.locale,
      namespacesRequired,
      nextI18nextConfig,
      ['professional'] // Extra locales. I needed to add it  here to make changeLanguage works with 'professional'.
    );

    return {
      props: {
        ...translations,
      },
    };`

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

5 participants