Next.js Discord

Discord Forum

RTL support

Answered
dank() posted this in #help-forum
Open in Discord
Avatar
I used Next.js i18n but it doesn't seem to consider directions for the locales. How should I go about it now that I used it?
Answered by not-milo.tsx
You can extend the default i18n config file provided in the example and add in an rtl property for each locale.

export const i18n = {
  defaultLocale: 'en',
  locales: [
    {
      value: 'en',
      rtl: false,
    },
    {
      value: 'es',
      rtl: false,
    },
    {
      value: 'he',
      rtl: true,
    },
  ],
} as const

export type Locale = (typeof i18n)['locales'][number]
View full answer

17 Replies

Avatar
You can extend the default i18n config file provided in the example and add in an rtl property for each locale.

export const i18n = {
  defaultLocale: 'en',
  locales: [
    {
      value: 'en',
      rtl: false,
    },
    {
      value: 'es',
      rtl: false,
    },
    {
      value: 'he',
      rtl: true,
    },
  ],
} as const

export type Locale = (typeof i18n)['locales'][number]
Answer
Avatar
Then you can use that to style a page differently for each case.
Avatar
@not-milo.tsx okay I did that, however the rtl value update doesn't seem to reflect in my app
I did this
export async function generateStaticParams() {
  return i18n.locales.map((locale) => ({
    lang: locale.value,
    rtl: locale.rtl,
  }));
}
import { Box, CssBaseline } from "@mui/material";
import React from "react";
import { Locale, i18n } from "../../../i18n.config";

//sidebar and header
import SideBar from "./components/sideBar";
import { AppHeader } from "./components/appHeader";
import { SideBarContent } from "./components/sideBar/SideBarContent";
export const drawerWidth = 240;
export async function generateStaticParams() {
  return i18n.locales.map((locale) => ({
    lang: locale.value,
    rtl: locale.rtl,
  }));
}
export default function ContentLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { lang: Locale["value"]; rtl: Locale["rtl"] };
}) {
  return (
    <div>
      {/* main container */}
      <Box
        sx={{
          display: "flex",
          direction: params.rtl ? "rtl" : "ltr", //set dir to rtl if lang need rtl support
        }}
      >
        {/* Include shared UI here : sidebar */}
        <CssBaseline />
        <div>
          <AppHeader
            lang={params.lang}
            direction={params.rtl ? "rtl" : "ltr"}
          />
        </div>
        <Box
          component="nav"
          sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}
        >
          <SideBar
            anchor={params.rtl ? "right" : "left"}
            sideBarContent={<SideBarContent params={{ lang: params.lang }} />}
          />
        </Box>
        <Box
          component="main"
          sx={{
            flexGrow: 1,
            p: 3,
            width: { sm: `calc(100% - ${drawerWidth}px)` },
            marginTop: 10,
          }}
        >
          {children}
        </Box>
      </Box>
    </div>
  );
}
everything seems in place
oh sh nvm
wait
I think Ik what it is about
I gotta do the localeswitcher to change the rtl I think
Avatar
You don't have to do this. Once you have the rtl values in the config you can access it like this from your pages:

import { i18n } from "~/i18n.config";

const Home = async ({ params: { lang } }: { params: { lang: Locale } }) => {
  const dictionary = await getDictionary(lang);
  const isRtl = i18n.locales.find((locale) => locale.value === lang.value)?.rtl || i18n.defaultLocale.rtl;

  return (
    <></>
  );
}
Avatar
oh
I kinda already changed it across all my components
🥲
that worked
thanks a lot
Avatar
No problem ✨