Search code examples
next.jsnext-i18nextradix-ui

How to Apply RTL Support to Shadcn Components in Next.js?


I'm using Next.js app version 14. RTL is not applied to Shadcn components. I'm also using next-intl to support multiple languages Here's how my layout.tsx file looks like:

layout.tsx
import type { Metadata } from "next";
import "../globalsyour text.css";

import localFont from "next/font/local";
import { Provider } from "../../providers";
import { NextIntlClientProvider, useMessages } from "next-intl";

const iranSansFont = localFont({
  src: "../../fonts/iranSans.woff2",
  display: "swap",
  variable: "--font-iranSans",
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
  params: { locale },
}: Readonly<{
  children: React.ReactElement;
  params: { locale: string };
}>) {
  const messages = useMessages();

  return (
    <html lang={locale} dir={locale === "fa" ? "rtl" : "ltr"}>
      <body
        className={`${iranSansFont.className} bg-background text-foreground px-4 py-4 font-bold`}
      >
        <NextIntlClientProvider locale={locale} messages={messages}>
          <Provider>{children}</Provider>
        </NextIntlClientProvider>
      </body>
    </html>
  );
}

Additionally, I've utilized @radix-ui/react-direction, but encountered the following error.

import type { Metadata } from "next";
import "../globals.css";

import localFont from "next/font/local";
import { Provider } from "../../providers";
import { NextIntlClientProvider, useMessages } from "next-intl";
import { DirectionProvider } from "@radix-ui/react-direction";

const iranSansFont = localFont({
  src: "../../fonts/iranSans.woff2",
  display: "swap",
  variable: "--font-iranSans",
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
  params: { locale },
}: Readonly<{
  children: React.ReactElement;
  params: { locale: string };
}>) {
  const messages = useMessages();

  return (
    <html lang={locale} dir={locale === "fa" ? "rtl" : "ltr"}>
      <body
        className={`${iranSansFont.className} bg-background text-foreground px-4 py-4 font-bold`}
      >
        <DirectionProvider dir={locale === "fa" ? "rtl" : "ltr"}>
          <NextIntlClientProvider locale={locale} messages={messages}>
            <Provider>{children}</Provider>
          </NextIntlClientProvider>
        </DirectionProvider>
      </body>
    </html>
  );
}

Error: ⨯ node_modules@radix-ui\react-direction\dist\index.mjs (4:82) @ undefined ⨯ TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function at eval (webpack-internal:///(rsc)/./node_modules/@radix-ui/react-direction/dist/index.mjs:9:114) at (rsc)/./node_modules/@radix-ui/react-direction/dist/index.mjs (C:\Users\ehsanKey\Documents\dev\portfolio-site.next\server\[email protected]:260:1) at webpack_require (C:\Users\ehsanKey\Documents\dev\portfolio-site.next\server\webpack-runtime.js:33:42) at eval (webpack-internal:///(rsc)/./src/app/[locale]/layout.tsx:14:83) at (rsc)/./src/app/[locale]/layout.tsx (C:\Users\ehsanKey\Documents\dev\portfolio-site.next\server\app[locale]\page.js:374:1) at Function.webpack_require (C:\Users\ehsanKey\Documents\dev\portfolio-site.next\server\webpack-runtime.js:33:42) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async collectGenerateParams (C:\Users\ehsanKey\Documents\dev\portfolio-site\node_modules\next\dist\build\utils.js:919:21) at async Object.loadStaticPaths (C:\Users\ehsanKey\Documents\dev\portfolio-site\node_modules\next\dist\server\dev\static-paths-worker.js:46:13) { type: 'TypeError', page: '' }


Solution

  • You can fix this error by wrapping DirectionProvider with a component that is marked with 'use client' (see the Next.js docs on 3rd party providers).