I'm trying to implement a multi-language React JS website I have implemented the translation files and language buttons and the translation is working but what I need is to change the layout of the pages I'm using Bootstrap v5.3 on my project, I have changed the direction of the body depending on the selected language but still, there are some of the components needs the bootstrap itself to change
when I import the bootstrap.min.css inside the index.js or app.js and try to remove it to depend on the useEffect() the whole design collapses even though I can see the Link is appended to the head and when I check the network I get
Request URL:
http://localhost:3000/node_modules/bootstrap/dist/css/bootstrap.min.css?1703491881256
Request Method:
GET
Status Code:
200 OK
What I have tried:
here is the index.js file
import React from 'react';
import ReactDOM from 'react-dom/client';
import '/node_modules/bootstrap/dist/js/bootstrap.bundle.min';
import '/node_modules/bootstrap/dist/css/bootstrap.min.css';
import './i18n';
import App from './App';
import './index.css';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<React.Suspense fallback="loading">
<App />
</React.Suspense>
</BrowserRouter>
</React.StrictMode>
);
I have tried to add multiple imports
if(document.documentElement.dir=="ltr"){
import 'bootstrap/dist/css/bootstrap.css'
}else{
import 'bootstrap/dist/css/bootstrap.rtl.css';
}
but I got an error:
'import' and 'export' may only appear at the top level.
and here inside the App.js where I add the current language I have tried to add this
const {languages } = useTranslationContext();
const currentLanguageCode= Cookies.get('i18next')||'en';
const currentLanguage = languages.find(lang => lang.code === currentLanguageCode);
useEffect(()=>{
document.documentElement.lang = currentLanguage.code;
document.body.dir = currentLanguage.dir;
const linkElement = document.getElementById('bootstrap-css');
const newLinkElement = document.createElement('link');
newLinkElement.rel = 'stylesheet';
newLinkElement.id = 'bootstrap-css';
newLinkElement.type='text/css';
newLinkElement.href = currentLanguage.dir === 'rtl'
? `./node_modules/bootstrap/dist/css/bootstrap.rtl.min.css?${new Date().getTime()}`
: `./node_modules/bootstrap/dist/css/bootstrap.min.css?${new Date().getTime()}`;
if (linkElement) {
document.head.removeChild(linkElement);
}
document.head.appendChild(newLinkElement);
},[currentLanguage]);
#I added this date ${new Date().getTime()} to prevent caching and make the file reload but nothing happens the Link is appended but there's no effect
Also, I have tried this function instead of the useEffect >
function getBootstrapCss() {
return currentLanguage.code === "ar" ? "bootstrap.rtl.min.css" : "bootstrap.min.css";
}
<>
<link
rel="stylesheet"
type="text/css"
href={`/node_modules/bootstrap/dist/css/${getBootstrapCss()}`}
/>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="home" element={<Home />} />
</Routes>
<Footer />
</>
)
#but this also not working and the link is added inside the body
And finally here is my dropdown-menu
<li className="nav-item dropdown">
<Link className="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<GrLanguage />
</Link>
<ul className="dropdown-menu">
{
languages.map(({code,name,countryCode})=>(
<li key={countryCode}>
<button className="dropdown-item"
onClick={()=>i18n.changeLanguage(code)}
disabled={i18n.resolvedLanguage===code}
>
<span className={`flag-icon flag-icon-${countryCode} mx-2`}</span>
{name}
</button>
</li>
))
}
</ul>
</li>