You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js 14中为Shadcn组件添加RTL支持?

Next.js 14 + Shadcn RTL 不生效及 Radix Direction 错误解决指南

一、修复 Shadcn 组件 RTL 样式不生效问题

Shadcn UI 基于 Tailwind CSS 实现,要让 RTL 样式生效,需配合 Tailwind 的 RTL 支持配置:

  1. 安装 Tailwind RTL 插件
npm install @tailwindcss/rtl
  1. 更新 tailwind.config.ts 配置
    添加插件以启用 RTL 样式支持:
import type { Config } from 'tailwindcss';
import tailwindcssRTL from '@tailwindcss/rtl';

const config: Config = {
  content: [
    './src/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [
    tailwindcssRTL(),
    // 保留你原有的其他插件(如 shadcn/ui 插件)
  ],
};

export default config;
  1. 保留现有 HTML dir 属性设置
    你当前在 <html> 标签中设置的 dir={locale === "fa" ? "rtl" : "ltr"} 是正确的,无需修改,Tailwind 和 Shadcn 组件会自动响应这个属性切换布局方向。

  2. 优化组件样式写法
    对于自定义样式,尽量使用 Tailwind 的 start/end 替代固定的 left/right,比如用 text-start 代替 text-left,这样在 RTL 模式下会自动切换为文本右对齐。

二、修复 @radix-ui/react-direction 报错问题

你遇到的 TypeError: createContext is not a function 错误,是因为在 React Server Components(RSC)中使用了仅支持客户端的组件——DirectionProvider 依赖 React Context,而 Context 只能在客户端组件中运行。

解决步骤:

  1. 封装客户端版 DirectionProvider
    创建单独的客户端组件文件,比如 src/app/components/DirectionProviderClient.tsx:
'use client';

import { DirectionProvider } from '@radix-ui/react-direction';

type Props = {
  children: React.ReactNode;
  dir: 'ltr' | 'rtl';
};

export default function DirectionProviderClient({ children, dir }: Props) {
  return <DirectionProvider dir={dir}>{children}</DirectionProvider>;
}
  1. 在 Layout 中使用封装后的组件
    替换原直接导入的 DirectionProvider,改为使用上述客户端组件:
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 DirectionProviderClient from "../components/DirectionProviderClient";

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();
  const dir = locale === "fa" ? "rtl" : "ltr";

  return (
    <html lang={locale} dir={dir}>
      <body
        className={`${iranSansFont.className} bg-background text-foreground px-4 py-4 font-bold`}
      >
        <DirectionProviderClient dir={dir}>
          <NextIntlClientProvider locale={locale} messages={messages}>
            <Provider>{children}</Provider>
          </NextIntlClientProvider>
        </DirectionProviderClient>
      </body>
    </html>
  );
}
  1. 可选:移除不必要的依赖
    如果你不需要在组件内部主动获取当前方向状态,仅靠 HTML 的 dir 属性就足够让 Tailwind 和 Shadcn 组件适配 RTL,此时可以直接移除 @radix-ui/react-direction 依赖,简化代码。

额外检查项

  • 确认 globals.css 中没有覆盖 RTL 相关的默认样式
  • 验证波斯字体 iranSans 已正确加载,RTL 文本需要适配的字体才能正常排版
  • 检查 next-intl 配置,确保 locale 切换时 HTML 的 dir 属性同步更新

内容的提问来源于stack exchange,提问作者EhsanKey_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:52:50