Mohamad Mirzai
Mohamad Mirzai

Reputation: 31

How to use changeLanguage method in next-i18next for changing locale?

I'm trying to change default locale in my project with just button click. I don't want to change my URL with pushing sub paths like fooo.com/fa.

Here is my next-i18next config:

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fa'],
  },
};

And here is my simple code for changing locale and using that:

const { t, i18n } = useTranslation('common');
   ///
<button onClick={() => i18n.changeLanguage('fa')}>
    Click to Change Language
</button>
<p>{t('title')}</p>

But it does not work and stuck in default locale that is EN.

Upvotes: 3

Views: 6993

Answers (2)

jackhkm
jackhkm

Reputation: 81

I had something similar and came up with this:

pages/some-route

export async function getAllTranslationsServerSide(locale: string) {
  return serverSideTranslations(
    locale,
    ["common"],
    nextI18nextConfig,
    nextI18nextConfig.i18n.locales
  );
}

export async function getStaticProps({ locale }) {
  return {
    props: {
      ...(await getAllTranslationsServerSide(locale)),
    },
  };
}

components/SomeComponent.tsx

function changeLanguage(locale) {
  i18n.changeLanguage(locale);
  router.push({ pathname, query }, asPath, {
    locale,
    scroll: false,
    shallow: true,
  });
}

I wanted to change locale (including the sub-path as my project uses NextJS sub-path routing) but without re-triggering other API requests that a route might need and hence any potential re-renders (I was getting some ugly white flashes).

The key bit is loading all locales in getStaticProps.

This means that when changeLanguage is called the required translation strings are already loaded client-side.

This works for my small app but is probably a bad idea for apps with more translations.

Upvotes: 1

Abdo Elmorsy
Abdo Elmorsy

Reputation: 71

This worked for me:

const changeLocale = (locale) => {
        router.push({
            route: router.pathname,
            query: router.query
        }, router.asPath, { locale });
    }

Upvotes: 7

Related Questions