Next.js bi-directionality package
A Next.js package, that makes working with directions a breeze.
Check out the Live Example to try it for yourself.
$ npm install next-direction
# or
$ yarn add next-direction
_app
import { DirModeProvider } from "next-direction";
function MyApp({ Component, pageProps }) {
return (
<DirModeProvider>
<Component {...pageProps} ></Component>
</DirModeProvider>
)
}
export default MyApp
import { useDirMode } from 'next-direction'
const DirmodeChanger = () => {
const { dirmode, setDirMode } = useDirMode();
return (
<div>
The current direction is: {dirmode}
<button onClick={() => setDirMode('ltr')}>LTR Mode</button>
<button onClick={() => setDirMode('rtl')}>RTL Mode</button>
</div>
)
}
Warning! The above code is hydration unsafe and will throw a hydration mismatch warning when rendering with SSG or SSR. This is because we cannot know the direction on the server, so it will always be undefined until mounted on the client.
You should delay rendering any direction toggling UI until mounted on the client. See the example.
storageKey
= ‘dirmode’: Key used to store dir mode setting in localStoragedefaultDirMode
= ‘ltr’: Default dir mode nameforcedDirMode
: Forced dir mode name for the current page (does not modify saved dir mode settings)dirmode
: Active dir mode namesetDirMode(dirmode: string)
: a function to set the dir modeforcedDirMode
: Forced page dir or falsy. If forcedDirMode is set, you should disable any dir mode switching UIBecause we cannot know the dirmode
on the server, many of the values returned from useDirMode
will be undefined
until mounted on the client. This means if you try to render UI based on the current dir mode before mounting on the client, you will see a hydration mismatch error.
The following code sample is unsafe:
import { useDirMode } from 'next-direction'
const dirModeChanger = () => {
const { dirMode, setDirMode } = useDirMode()
return (
<div>
The current direction mode is: {dirMode}
<button onClick={() => setDirMode('LTR')}>LTR Mode</button>
<button onClick={() => setDirMode('RTL')}>RTL Mode</button>
</div>
)
}
To fix this, make sure you only render UI that uses the current dir mode when the page is mounted on the client:
import { useDirMode } from 'next-direction'
const DirModeChanger = () => {
const [mounted, setMounted] = useState(false)
const { dirMode, setDirMode } = useDirMode()
// When mounted on client, now we can show the UI
useEffect(() => setMounted(true), [])
if (!mounted) return null
return (
<div>
The current direction mode is: {dirMode}
<button onClick={() => setDirMode('LTR')}>LTR Mode</button>
<button onClick={() => setDirMode('RTL')}>RTL Mode</button>
</div>
)
}
To avoid Content Layout Shift, consider rendering a skeleton until mounted on the client side.
I created another plugin that makes working with bi-direction less painful with tailwind, check it out:
https://github.com/yassinebridi/tailwind-direction
This project’s code is heavily inspired by this great project