Mantine UI in Next.js 13 App Directory
âť— Next.js app directory architecture is still in beta and not recommended for production applications. The solution below is a temporary solution for Mantine in Next.js 13.
Mantine UI Components can only be used in Next.js 13 Client Components. By default, components in the app directory are Server Components. So the new use client
directive must be used in any component that you want to use Mantine in. Find more on Client Components here: Client Components and use client in Next.js App Directory.
I did not develop this solution myself and will reference where the code originated.
Versions Tested With:
1"dependencies": { 2 "@emotion/react": "^11.10.5", 3 "@emotion/server": "^11.10.0", 4 "@mantine/core": "^5.10.2", 5 "@mantine/hooks": "^5.10.2", 6 "@mantine/next": "^5.10.2", 7 "next": "13.1.5", 8 "react": "18.2.0", 9 }
1. Create a new Next.js application
1npx create-next-app
Using create-next-app
, go through multiple questions one of them doing you want to use the new experimental app directory architecture? Make sure to select that you do want to use the app directory. Note: I am also providing this example with TypeScript.
2. Install Mantine and Emotion packages
1// Choose your favorite package manager to install Mantine and emotion packages 2npm install @mantine/core @mantine/hooks @mantine/next @emotion/server @emotion/react 3 4yarn add @mantine/core @mantine/hooks @mantine/next @emotion/server @emotion/react 5 6pnpm install @mantine/core @mantine/hooks @mantine/next @emotion/server @emotion/react
Need more than the packages listed above? Find the complete list of installable packages in the Mantine usage with Next.js Guide.
3. Create an emotion.tsx file at the root of your app directory
The following code goes into an emotion.tsx
file.
1// app/emotion.tsx 2"use client" 3import { CacheProvider } from "@emotion/react"; 4import { useEmotionCache, MantineProvider } from "@mantine/core"; 5import { useServerInsertedHTML } from "next/navigation"; 6 7export default function RootStyleRegistry({ 8 children 9}: { 10 children: React.ReactNode 11}) { 12 const cache = useEmotionCache(); 13 cache.compat = true; 14 15 useServerInsertedHTML(() => ( 16 <style 17 data-emotion={ 18 `${cache.key} ${Object.keys(cache.inserted).join(" ")}` 19 } 20 dangerouslySetInnerHTML={{ 21 __html: Object.values(cache.inserted).join(" "), 22 }} 23 /> 24 )); 25 26 return ( 27 <CacheProvider value={cache}> 28 <MantineProvider withGlobalStyles withNormalizeCSS> 29 {children} 30 </MantineProvider> 31 </CacheProvider> 32 ) 33}
The above code comes from Vitaly Rtishchev from this sample GitHub repository. The solution was found via: Mantine GitHub issue 2815.
4. Update layout.tsx with RootStyleRegistry
The RootStyleRegistry you just created needs to be added to the layout.tsx in the root of the app folder.
1// app/layout.tsx 2import RootStyleRegistry from './emotion' 3import './globals.css' 4 5export default function RootLayout({ 6 children, 7}: { 8 children: React.ReactNode 9}) { 10 return ( 11 <html lang="en-US"> 12 <head /> 13 <body> 14 <RootStyleRegistry>{children}</RootStyleRegistry> 15 </body> 16 </html> 17 ) 18}
5. Using a Mantine UI Component on page.tsx
Because of how Mantine components work, they must be used inside Client Components in Next.js. To make a component a Client Component add the use client
to the top of the file.
1// app/page.tsx 2'use client' 3import styles from './page.module.css' 4import { Button } from '@mantine/core'; 5 6export default function Home() { 7 const handleClick = () => { console.log("Clicked") } 8 9 return ( 10 <main className={styles.main}> 11 <Button onClick={handleClick}> 12 Settings 13 </Button> 14 </main> 15 ) 16}
If everything goes well, you should have a Mantine UI Button in your Next.js application built in the app directory. Load up your dev environment npm run dev
, and ensure it works!
Moving forward, any component you build that uses Mantine UI elements will need the use client
directive. It’s best to keep these as small and single-purpose as possible so you don’t need use client
in every file. Try to take advantage of the default Server Components whenever possible.
Tracking Production Support of Mantine in Next.js 13
Much work is being done to add better and easier support of UI component libraries in the new Next.js 13 app directory architecture. Below are the GitHub issues you can track to keep up with the latest changes and support for Next.js 13 in Mantine and Emotion.
Mantine with Next.js 13 app dir Issue #2815
Emotion: Plans to support Next.js 13 - /app directory Issue #2928