skip to Main Content

I am creating a multilingual app in react js and I want to always have the ?lang=languageName parameter in url. I am using react-i18next for translation. Below code which works fine if I refresh the page:

import React, { useEffect } from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';

import NavBar from './layout/navbar';
import Home from './pages/home';
import { useTranslation } from 'react-i18next';
import SignUp from './pages/auth/signup';

function App() {
  const { i18n } = useTranslation();
  const queryParam = new URLSearchParams(window.location.search);
  const lang = queryParam.get('lang');

  useEffect(() => {
    if (!lang) {
      queryParam.set('lang', i18n.language);
      window.history.replaceState({}, '', `?${queryParam}`);
    }
  });

  return (
    <>
      <BrowserRouter>
        <>
          <NavBar />
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="home" element={<Home />} />
            <Route path="signup" element={<signup />} />
          </Routes>
        </>
      </BrowserRouter>
    </>
  );
}

export default App;

It works fine when I reload page. But when I click on signup button and the url changes to http://example.com/signup it doesn’t add lang parameter with it. It should be like http://example.com/signup?lang=languageName.

2

Answers


  1. Your useEffect does not have empty array for dependencies.
    It should be like this

     useEffect(() => {
        if (!lang) {
          queryParam.set('lang', i18n.language);
          window.history.replaceState({}, '', `?${queryParam}`);
        }
      }, []); // <--- THIS IS IMPORTANT. Otherwise, it will executed for every render
    
    Login or Signup to reply.
  2. I suggest using the useSearchParams hook to update the queryString.

    import {
      Routes,
      Route,
      useSearchParams,
    } from 'react-router-dom';
    
    function App() {
      const { i18n } = useTranslation();
      const [searchParams, setSearchParams] = useSearchParams();
    
      const lang = searchParams.get('lang');
    
      useEffect(() => {
        if (!lang) {
          searchParams.set('lang', i18n.language);
          setSearchParams(searchParams, { replace: true });
        }
      }, [lang]);
    
      return (
        <>
          <NavBar />
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="home" element={<Home />} />
            <Route path="signup" element={<signup />} />
          </Routes>
        </>
      );
    }
    
    import { BrowserRouter } from 'react-router-dom';
    
    ...
    
    <BrowserRouter>
      <App />
    </BrowserRouter>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search