Next-i18next: Functionality lost during the upgrade to v8

Created on 26 Feb 2021  路  3Comments  路  Source: isaachinman/next-i18next

Describe the bug

Some functions/configurations are not working as they worked in v7

Occurs in next-i18next version

8.0.2

Steps to reproduce

  1. use i18n.changeLanguage for example, it wont change the language, wont set cookie
  2. add detection configuration to next-i18next.config.js - wont consider it

Expected behaviour

  1. expecting to have the cookie with the selected language and that it will effect after navigation to main url without the language subfolder
  2. will respect the rules of the detection

OS (please complete the following information)

  • Device: MacBook Pro (2019) 10.15.7
  • Browser: Chorme 89.0.4389.40 (Official Build) beta (x86_64)

Additional context

Here's my next-18next.config.js content

const path = require('path');

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'he'],
  },
  localePath: path.resolve('./public/static/locales'),
  fallbackLng: 'en',
  load: 'currentOnly',
  // default next-i18next detection with order change
  detection: {
    caches: ['cookie'],
    cookieSameSite: 'strict',
    lookupCookie: 'next-i18next',
    order: ['querystring', 'cookie', 'header'],
  },
};

Most helpful comment

@retromack @isaachinman This is my implementation for my needs.

added getInitialProps to my _app (with the detection strategy I wanted)
```typescript
MyApp.getInitialProps = async (appContext: AppContextType) => {
const { router, ctx } = appContext;
if (ctx.req) {
const { __NEXT_INIT_QUERY, cookies } = ctx.req as any;
const { lng } = __NEXT_INIT_QUERY || {};
const { NEXT_LOCALE } = cookies || {};
const { asPath, locale, defaultLocale } = router || {};

  const desiredLocale = lng || NEXT_LOCALE || locale;
  if (desiredLocale !== locale) {
    const Location = `${defaultLocale === desiredLocale ? '' : `/${desiredLocale}`}${asPath}`;
    ctx.res.setHeader('Location', Location);
    ctx.res.setHeader('Set-Cookie', `NEXT_LOCALE=${desiredLocale}; Max-Age=31556952; Path=/`);
    ctx.res.statusCode = 302;
  }
}

const appProps = await App.getInitialProps(appContext);

return { ...appProps };
};

hook to change language (instead of the i18n.change language which is not working anymore)
```typescript
import { useRouter } from 'next/router';
import { useCallback } from 'react';
import cookie from 'js-cookie';

const useChangeLanguage = () => {
  const { push, query, locale: currentLocale } = useRouter();

  const changeLanguage = useCallback(
    (locale: string, options?: { cookie?: boolean }) => {
      const { cookie: saveCookie = true } = options || {};
      if (currentLocale !== locale) {
        push({ query }, undefined, { locale });
      }
      if (saveCookie) {
        cookie.set('NEXT_LOCALE', locale, { expires: 365 });
      }
    },
    [query, currentLocale]
  );

  return changeLanguage;
};

export default useChangeLanguage;

All 3 comments

Facing the same issue

Hi @ronfogel 鈥撀燦extJs as a framework now handles locale detection and management. Please read through the new next-i18next docs carefully, as well as the NextJs Internationalization docs.

To answer your questions:

use i18n.changeLanguage for example, it wont change the language, wont set cookie

NextJs handles language, and you can change it via the framework itself

add detection configuration to next-i18next.config.js - wont consider it

NextJs handles detection, and any issues you have therein will need to be opened on the main NextJs repo.

To put it shortly: next-i18next@8 is a very different kind of plugin than all previous versions.

Hope that helps!

@retromack @isaachinman This is my implementation for my needs.

added getInitialProps to my _app (with the detection strategy I wanted)
```typescript
MyApp.getInitialProps = async (appContext: AppContextType) => {
const { router, ctx } = appContext;
if (ctx.req) {
const { __NEXT_INIT_QUERY, cookies } = ctx.req as any;
const { lng } = __NEXT_INIT_QUERY || {};
const { NEXT_LOCALE } = cookies || {};
const { asPath, locale, defaultLocale } = router || {};

  const desiredLocale = lng || NEXT_LOCALE || locale;
  if (desiredLocale !== locale) {
    const Location = `${defaultLocale === desiredLocale ? '' : `/${desiredLocale}`}${asPath}`;
    ctx.res.setHeader('Location', Location);
    ctx.res.setHeader('Set-Cookie', `NEXT_LOCALE=${desiredLocale}; Max-Age=31556952; Path=/`);
    ctx.res.statusCode = 302;
  }
}

const appProps = await App.getInitialProps(appContext);

return { ...appProps };
};

hook to change language (instead of the i18n.change language which is not working anymore)
```typescript
import { useRouter } from 'next/router';
import { useCallback } from 'react';
import cookie from 'js-cookie';

const useChangeLanguage = () => {
  const { push, query, locale: currentLocale } = useRouter();

  const changeLanguage = useCallback(
    (locale: string, options?: { cookie?: boolean }) => {
      const { cookie: saveCookie = true } = options || {};
      if (currentLocale !== locale) {
        push({ query }, undefined, { locale });
      }
      if (saveCookie) {
        cookie.set('NEXT_LOCALE', locale, { expires: 365 });
      }
    },
    [query, currentLocale]
  );

  return changeLanguage;
};

export default useChangeLanguage;

Was this page helpful?
0 / 5 - 0 ratings