Search code examples
next.jsinternationalizationi18nextnext-i18next

next-i18next : get the value of locale to change page dir to right to left


I just migrated to next.js and started using next-i18next instead of React i18n. my objective is to change the html page dir to right to left when choosing the Arabic language.

I was using a cookie to achieve this but I belive if I can get the value of locale in loginHeader.js component I can achieve that.

How to get the value of local ?

I highly appreciate your support.

loginHeader.js ;

import React, { Fragment, useEffect } from 'react';
import styles from '../styles/LoginHeader.module.css';
import Link from 'next/link';
import { connect } from 'react-redux';
import { logout } from '../actions/auth';
import SortIcon from '@mui/icons-material/Sort';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import Alert from './Alert';
// import Drower from './Drower';
import Logo from '../assets/images/logoo.png';
import { useTranslation } from 'next-i18next';
import { Select, MenuItem } from '@mui/material';
import LanguageIcon from '@mui/icons-material/Language';
import { Link as Scroll } from 'react-scroll';
import Image from 'next/image';
import {useRouter} from 'next/router';

import i18n from '../../i18n';
import cookies from 'js-cookie';

const languages = [
  {
    code: 'fr',
    name: 'Français',
    country_code: 'fr'
  },
  {
    code: 'en',
    name : 'English',
    country_code: 'en'
  },
  {
    code: 'ar',
    name: 'العربية',
    country_code: 'ly',
    dir: 'rtl'
  }
]

//this is new code but the value isn't there
export function getServerSideProps({locale}) {
  return {
    props: {
      locale
    }
  }
};

function LoginHeader(props, { logout, isAuthenticated }) {

  // This is old code before migration
  const currentLanguageCode = cookies.get('i18next') || 'en';
  const currentLanguage = languages.find(l => l.code === currentLanguageCode);
  useEffect (() => {
    document.body.dir = currentLanguage.dir || 'ltr'
    // document.title = t('app_title')
  },[currentLanguage]);

  const { t } = useTranslation();
  const router = useRouter();

  const guestLinks = () => (
    <Fragment>
      <div className={styles.loginHeader__right}>
        <div className='middle__header__bx'>
    
          <div className={styles.loginHeader__main__btns}>
            <Link className={styles.loginHeader__loginButton} href='/login'><button className={styles.login__btn}>{t('header_login')}</button></Link>
            <Link className={styles.loginHeader__signupButton} href='/signup'><button className={styles.signup__btn}>{t('header_signup')}</button></Link>
          </div> 
        
          <div className={styles.loginHeader__services__dropdown}>
            <Scroll offset={-100}  to='services'><button className={styles['dropdown__btn']+' '+styles['dropdown__services']}>{t('header_services')}<ExpandMoreIcon className={styles.services__expand}/></button></Scroll>
            <div className={styles['dropdown__content']+' '+styles['dropdown__services__content']}>
              <Link className={styles.loginHeader__menuItem} href='/admission'>{t('services_addmissionOffers')}</Link>
              {/* <Link className='loginHeader__menuItem' to='/application-form'>{t('services_forms')}</Link> */}
              <Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('services_premium')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('services_visaAssist')}</Link>
            </div>
          </div>
          {/* start of lang box */}
            <Select
              className={styles.loginHeader__select}
              labelId='select-demo'
              id='language-select'
              disableUnderline
              variant='standard'
              IconComponent={LanguageIcon}
            >
              {router.locales.map((locale) => ( 
                <MenuItem
                  className={styles.loginHeader__select__menu}
                  key={locale}
                >
                  <Link href={router.asPath} locale={locale}>
                    <a>{locale}</a>
                  </Link>
                </MenuItem>
              ))}
            </Select>

          {/* end of lang box */}
          <div className={styles['loginHeader__services__dropdown']+' '+styles['sortIcon__bx']}>
            <SortIcon className={styles['dropdown__btn']+' '+styles['loginHeader__sortIcon']}/>
            <div className={styles['dropdown__content']+' '+styles['sortIcon__dropdown']}>
              <Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('header_dropdown_prem')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('header_dropdown_visaAssist')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/admission'>{t('header_dropdown_admission')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/request-service'>{t('header_dropdown_requestService')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/contact'>{t('header_dropdown_contact')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/signup'>{t('header_signup')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/login'>{t('header_login')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/guid'>{t('header_dropdown_guide')}</Link>
            </div>
          </div>
        
       </div>
      </div>
    </Fragment>
  );

  const authLinks = () => (
    <Fragment>
      <div className={styles.loginHeader__right}>
        <div className={styles.middle__header__bx}>
            
            <div className={styles.loginHeader__main__btns}>
              <Link className={styles.loginHeader__loginButton} href='/login'><button className={styles.login__btn}>{t('header_login')}</button></Link>
              <Link className={styles.loginHeader__signupButton} href='/signup'><button className={styles.singin__btn}>{t('header_signup')}</button></Link>
            </div> 
          
            <div className={styles.loginHeader__services__dropdown}>
              <Scroll offset={-100}  to='services'><button className={styles['dropdown__btn']+' '+styles['dropdown__services']}>{t('header_services')}<ExpandMoreIcon className={styles.services__expand}/></button></Scroll>
              <div className={styles['dropdown__content']+' '+styles['dropdown__services__content']}>
                <Link className={styles.loginHeader__menuItem} href='/admission'>{t('services_addmissionOffers')}</Link>
                {/* <Link className='loginHeader__menuItem' to='/application-form'>{t('services_forms')}</Link> */}
                <Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('services_premium')}</Link>
                <Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('services_visaAssist')}</Link>
              </div>
            </div>
          {/* start of lang box */}
            <Select
              className={styles.loginHeader__select}
              labelId='select-demo'
              id='language-select'
              disableUnderline
              variant='standard'
              IconComponent={LanguageIcon}
            >
              {languages.map(({code, name, country_code}) => 
                <MenuItem
                  key={country_code}
                >
                  <button 
                    onClick={() => i18next.changeLanguage(code)}
                    className='loginHeader__lang__btn'
                  >
                    {name}
                  </button>
                </MenuItem>
              )}
            </Select>
          {/* end of lang box */}
          <div className={styles['loginHeader__services__dropdown']+' '+styles['loggedin__icon__bx']}>
            <button className={styles.dropdown__btn}><SortIcon className={styles['loginHeader__sortIcon']+' '+styles['logedin__sortIcon']}/></button>
            <div className={styles['dropdown__content']+' '+styles['logged__sortIcon__dropdown']}>
              <Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('header_dropdown_prem')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/admission'>{t('header_dropdown_admission')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('header_dropdown_visaAssist')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/request-service'>{t('header_dropdown_requestService')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/contact'>{t('header_dropdown_contact')}</Link>
              <Link className={styles.loginHeader__menuItem} href='/guid'>{t('header_dropdown_guide')}</Link>
              <button onClick={logout} className={styles.logout__btn}>{t('header_logout')}</button>
            </div>
          </div>
        </div>
        
      </div>
    </Fragment>
  );

  return (
    <div className={styles.loginHeader}>
      <div className={styles.loginHeader__left}>
        <Link href='/'><Image className={styles.logo} src={Logo} alt='logo'/></Link>  
      </div>
      {isAuthenticated ? authLinks() : guestLinks()}
      <Alert/>
    </div>
  )
};

const mapStateToProps = state => ({
  isAuthenticated: state.auth.isAuthenticated
});

export default connect(mapStateToProps, { logout }) (LoginHeader);

i18n.js :

const path = require('path');

module.exports = {
  i18n: {
    locales: ['ar', 'en', 'fr'],
    defaultLocale: 'en',
    localeDetection: false,
    localePath: path.resolve('./public/locales'),
  },
};

next.config.js ;

const { i18n } = require('./i18n');

const nextConfig = {
  reactStrictMode: true,
  i18n,
};

module.exports = nextConfig;

Solution

  • Thanks to Juliomalves who guided me to the solution. So, I changed two parts in my code :

    1st :

      const router = useRouter();
      const [show, setShow] = useState (false);
      const currentLanguageCode = router.locale;
      const currentLanguage = languages.find(l => l.code === currentLanguageCode);
      useEffect (() => {
        document.body.dir = currentLanguage.dir || 'ltr'
        // document.title = t('app_title')
      },[currentLanguage]);
    

    2nd :

    <div className={styles.lang__container}>
                        {languages.map(({code, name, country_code}) => 
                          <MenuItem
                            className={styles.loginHeader__select__menu}
                            key={country_code}
                          >
                            <Link className={styles.loginHeader__lang__btn} href={router.asPath} locale={code}>
                              <a>{name}</a>
                            </Link>
                          </MenuItem>
                        )}
                      </div>