Reputation: 1122
What would be the best way to implement RTL support in React apps? Is there a way to override default <p>
and <span>
tags (components) to add RTL support so that I don't have to rewrite components I already wrote to have RTL support? (for example, to have some global variable window.RTL
, so when set to true to have all <p>
and <span>
tags flip text direction to RTL). I could probably change the build system, or make a babel plugin, that will replace all React.createElement("p" ...)
with my own implementation of a p tag, but is there a better solution?
Thanks.
Upvotes: 21
Views: 39290
Reputation: 16
I'm using react-i18next to change the position from left to right when the Arabic language is chosen. I did the flowing, and it worked for me.
first i went to to the index.html and wrote this inside of body tag:
<body dir="ltr">
which will allow the page to left to write when the direction is chosen. lastly i add this line in my App.js which is my main code:
document.body.dir = i18n.dir(); //this will change the direction of the dir in the index.html.
Upvotes: 0
Reputation: 59
if you use react-i18next
import React from 'react';
import { useTranslation } from 'react-i18next';
import './App.css';
function App() {
const { t, i18n } = useTranslation();
document.body.dir = i18n.dir();
return (
<div className="App">
{t('welcome')}
</div>
);
}
export default App;
Upvotes: 1
Reputation: 11
Go to main.tsx
or main.js
depending on your project and wrap <App />
tag with a <div dir="rtl"></div>
like this
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<div dir="rtl">
<App />
</div>
</React.StrictMode>
)
Upvotes: 1
Reputation: 2918
There is a special HTML tag to use RTL direction:
bdo {
unicode-bidi: bidi-override;
}
<bdo dir="rtl">
This text will go right-to-left.
</bdo>
https://www.w3schools.com/tags/tag_bdo.asp
Upvotes: 1
Reputation: 65
here's your solution:
first of all create an array of rtl language locales, like this:
const rtlLanguages = ["ar"]
here's how you can update your page direction based on your current language:
function setPageDirection(language) {
const dir = rtlLanguages.includes(language) ? "rtl" : "ltr"
document.documentElement.dir = dir
}
now when you set your new language, update the page direction using the function above, like this:
setPageDirection("en") // ltr
setPageDirection("ar") // rtl
NOTE: to automatically update the page direction during first render try storing your current language locale (for example: "en") in localStorage whenever you update your language, and then try using useEffect (or componentDidMount), and use localStorage.getItem to get your language and just call the setPageDirection function and provide the language
Upvotes: 4
Reputation: 1489
Simple and easy, Just set dir
attribute of <html>
in index.js
as follow:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
//HERE ->
document.getElementsByTagName('html')[0].setAttribute("dir", "rtl");
//Or you can do it where ever you want, base on user selected language, or something else
serviceWorker.unregister();
UPDATE: If your application is RTL at all, just add dir="rtl"
in <html>
tag, but if user can chose different languages that may be RTL or LTR you can do it like above example, and handle other things with CSS...
Just check User chosen language is RTL and document.getElementsByTagName('html')[0].setAttribute("dir", "rtl");
let CSS handle appearance stuff.
Upvotes: 8
Reputation: 2570
A more optimal way is to use CSS / HTML abilities for that:
direction
CSS property‏
/ ‎
.rtl
/ .ltr
classes to body
and use them to change orderIn that cases order of your elements in HTML are the same for RTL and LTR. The difference in applied CSS rules.
If you really need the order of elements in React, you can create own component that reverses the list of children if RTL:
const Dir = React.createClass({
render: function() {
let children = (this.props.direction == 'rtl' && this.props.children && this.props.children.reverse) ? this.props.children.reverse() : null;
return <div>
{ children }
</div>;
}
});
// And use as:
// directionVariable = 'rtl'|'ltr'
<Dir direction={ directionVariable }>
<a>First</a>
<a>Second</a>
<a>Third</a>
</Dir>
Upvotes: 14