diff --git a/docs/pages/docs/_meta.json b/docs/pages/docs/_meta.json index 0d09d16..9e823c4 100644 --- a/docs/pages/docs/_meta.json +++ b/docs/pages/docs/_meta.json @@ -1,6 +1,7 @@ { "index": "Get Started", "writing-locales": "Writing locales", + "rtl-support": "RTL support", "testing": "Testing", "examples": "Examples", "-- App Router": { diff --git a/docs/pages/docs/rtl-support.mdx b/docs/pages/docs/rtl-support.mdx new file mode 100644 index 0000000..c335410 --- /dev/null +++ b/docs/pages/docs/rtl-support.mdx @@ -0,0 +1,114 @@ +import { Tabs, Tab } from 'nextra/components' + +# RTL support + +If you want to support the `dir` attribute in your `` tag, you'll need to add some logic: + +## From the root layout + +```tsx +// app/[locale]/layout.tsx +export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) => { + const dir = new Intl.Locale(locale).getTextInfo().direction + + return ( + + + {children} + + + ) +} +``` + +### Caveat + +Note that this doesn't work in Firefox, if your root layout is a client component. +This is because `Intl.Locale.prototype.getTextInfo` is not yet supported in Firefox, even if it is built-in in Node.js. + +To cover this, you can add a _polyfill_ to guarantee compatibility with all browsers, until this standard is fully adopted. + +To do this, you can firstly add this polyfill: + + + + ```bash + pnpm install intl-locale-textinfo-polyfill + ``` + + + ```bash + npm install intl-locale-textinfo-polyfill + ``` + + + ```bash + yarn add intl-locale-textinfo-polyfill + ``` + + + ```bash + bun add intl-locale-textinfo-polyfill + ``` + + + +And then write: + +```tsx +// app/[locale]/layout.tsx +import Locale from 'intl-locale-textinfo-polyfill'; + +export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) => { + const { direction: dir } = new Locale(locale).textInfo; + + return ( + + + {children} + + + ); +}; +``` + +Or you can use a lib like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect) + +## With a useEffect call + +You may implement your RTL support with a `useEffect` as well. + +For instance, if you have a language switcher component on all your pages, you could also choose to write the language direction detection logic in it. + +Something like: + +```tsx +// LanguageSwitcher.tsx +'use client' + +import { useChangeLocale, useCurrentLocale } from '../../locales/client' +import { FunctionComponent, useEffect } from 'react' + +export default function LanguageSwitcher() { + const currentLocale = useCurrentLocale() + const changeLocale = useChangeLocale() + + useEffect(() => { + document.documentElement.dir = isLocaleRTL(currentLocale) ? 'rtl' : 'ltr' + }, [currentLocale]) + + return ( +
+ + +
+ ) +} +``` + +Where `isLocaleRTL` could be a call to a lib like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect), or the implementation mentioned just above, based on `Intl.Locale.prototype.getTextInfo`, including the polyfill currently required to ensure compatibility with Firefox-based browsers. + +### Caveat + +Note that this choice of implementation will cause an UI flickering when your user loads your web pages for the first time. +This is because the page will first be mounted with the default `dir` attribute value of your HTML node, then updates when the component including the `useEffect` is mounted. This will introduce CLS (Cumulative Layout Shift) issues.