RTL Support

Mantine is built with emotion which supports RTL languages with stylis-plugin-rtl.

Install stylis-plugin-rtl:

# Install with yarn
yarn add stylis stylis-plugin-rtl
# or with npm
npm install stylis stylis-plugin-rtl

Add dir="rtl" to html element:

<html dir="rtl">...</html>

Add stylis-plugin-rtl and theme.dir to your MantineProvider:

import { MantineProvider } from '@mantine/core';
import rtlPlugin from 'stylis-plugin-rtl';
function App() {
return (
<MantineProvider
withGlobalStyles
withNormalizeCSS
emotionOptions={{ key: 'mantine', stylisPlugins: [rtlPlugin] }}
theme={{ dir: 'rtl' }}
>
<YourApp />
</MantineProvider>
);
}

Dynamic direction changes

To make rtl dynamic, change cache key when cache changes (!important cache key cannot be the same):

import { useState } from 'react';
import { MantineProvider, Button } from '@mantine/core';
import rtlPlugin from 'stylis-plugin-rtl';
function App() {
const [rtl, setRtl] = useState(false);
return (
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{ dir: rtl ? 'rtl' : 'ltr' }}
emotionOptions={
rtl
? // rtl cache
{ key: 'mantine-rtl', stylisPlugins: [rtlPlugin] }
: // ltr cache
{ key: 'mantine' }
}
>
<div dir={rtl ? 'rtl' : 'ltr'}>
<Button onClick={() => setRtl((c) => !c)}>Toggle rtl/ltr</Button>
<YourApp />
</div>
</MantineProvider>
);
}

RTL with Next.js

To setup RTL support for Next.js:

  • Replace your _document.tsx with
import Document, { DocumentContext, Html, Head, Main, NextScript } from 'next/document';
import rtlPlugin from 'stylis-plugin-rtl';
import { ServerStyles, createStylesServer } from '@mantine/next';
export default class _Document extends Document {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx);
const stylesServer = createStylesServer({ key: 'rtl', stylisPlugins: [rtlPlugin] });
return {
...initialProps,
styles: (
<>
{initialProps.styles}
<ServerStyles html={initialProps.html} server={stylesServer} />
</>
),
};
}
render() {
return (
<Html dir="rtl" lang={this.props.locale}>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
  • In your _app.tsx set dir: 'rtl' prop on theme and provide emotionOptions, important! emotionOptions should be the same as you've provided in createStylesServer:
import { AppProps } from 'next/app';
import rtlPlugin from 'stylis-plugin-rtl';
import { MantineProvider } from '@mantine/core';
export default function App(props: AppProps) {
const { Component, pageProps } = props;
return (
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{ dir: 'rtl' }}
emotionOptions={{ key: 'rtl', stylisPlugins: [rtlPlugin] }}
>
<Component {...pageProps} />
</MantineProvider>
);
}