0

I am using next-i18next to translate my pages in my Next.JS app. I followed the basic tutorial and this works great for translating a page.

In the page login.tsx this code handles the translation:

    const { i18n } = useTranslation();
    const { language: currentLanguage } = i18n;
    const locales = router.locales ?? [currentLanguage];

    const languageNames = useMemo(() => {
        return new Intl.DisplayNames([currentLanguage], {
            type: 'language',
        });
    }, [currentLanguage]);

    const onToggleLanguageClick = (newLocale: string) => {
        const { pathname, asPath, query } = router
        router.push({ pathname, query }, asPath, { locale: newLocale })
    }

Note that Intl.DisplayNames here is just to translate my locale such as "en" into the language name "English".

This is rendered as such:

<div className="flex w-56 justify-between">
    {locales.map( (locale) => {
        return <button key={locale} onClick={(e) => onToggleLanguageClick(locale)}>{capitalize(languageNames.of(locale) ?? locale)}</button>
    })}
</div>

Until here all is great, but I now want to move this logic out of the page and into a Component "Navbar", so that the user can select their language from there. The "Navbar" Component can then be re-used across the website.

This is the Navbar, and it is included directly in the Login page as a Component. For some reason the page takes forever to load when I do this. There is clearly some underlying error but I am too new with Next.JS and React to understand what the issue is. If someone could help me would be fantastic!

import {useState} from "react";
import { useTranslation } from 'next-i18next'
import {useRouter} from "next/router";
import {useCallback, useMemo} from "react";

export default function Navbar() {
    const { i18n } = useTranslation();
    const { language: currentLanguage } = i18n;
    const router = useRouter();
    const locales = router.locales ?? [currentLanguage];
    const languageNames = useMemo(() => {
        return new Intl.DisplayNames([currentLanguage], {
            type: 'language',
        });
    }, [currentLanguage]);

    const onToggleLanguageClick = useCallback((newLocale: string) => {
        return ((e: any) => {
            const { pathname, asPath, query } = router
            router.push({ pathname, query }, asPath, { locale: newLocale })
        })
    }, [router]);


    return (
             <>
                {locales.map( (locale) => {
                   return <li key={locale}>
                        <div onClick={onToggleLanguageClick(locale)}
                           className="flex items-center space-x-2 px-4 py-2 hover:bg-gray-100 hover:cursor-pointer dark:hover:bg-gray-600 dark:hover:text-white"><span>{capitalize(languageNames.of(locale) ?? locale)}</span></div>
                     </li>
                 })}
          </>
    )
}

const capitalize = (lang: string) => {
    return lang.slice(0, 1).toUpperCase() + lang.slice(1);
};

0 Answers0