3

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.

juliomalves
  • 42,130
  • 20
  • 150
  • 146
  • "I don't want to change my URL with pushing sub paths" - any reason why not? That's how Next.js i18n sub-path routing is meant to work. – juliomalves Jul 11 '21 at 13:12
  • This will cause our CDN to crash (because the URL has changed and is no longer cached)... so we don't have other way ? – Mohamad Mirzai Jul 11 '21 at 13:23
  • 1
    I'm not sure I understand - shouldn't the CDN be caching the routes for all possible locales of the app? – juliomalves Jul 11 '21 at 18:06

2 Answers2

6

This worked for me:

const changeLocale = (locale) => {
        router.push({
            route: router.pathname,
            query: router.query
        }, router.asPath, { locale });
    }
Abdo Elmorsy
  • 61
  • 1
  • 4
  • 2
    Thank you. It sounds crazy, but yeah: official documentation doesn't contain how to change language. Unbelievable. – nlavr Jan 21 '23 at 12:28
0

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.

jackhkm
  • 71
  • 1
  • 5