Usage with Next.js

Get started with a template

The easiest way to get started is to use one of the templates. All templates are configured correctly: they include PostCSS setup, ColorSchemeScript and other essential features. Some templates also include additional features like Jest, Storybook and ESLint.

If you are not familiar with GitHub, you can find a detailed instruction on how to bootstrap a project from a template on this page.

next-app-template

Next.js template with app router and full setup: Jest, Storybook, ESLint

Use template

next-pages-template

Next.js template with pages router and full setup: Jest, Storybook, ESLint

Use template

next-app-min-template

Next.js template with app router and minimal setup – no additional tools included, only default Next.js configuration

Use template

next-pages-min-template

Next.js template with pages router and minimal setup – no additional tools included, only default Next.js configuration

Use template

next-vanilla-extract-template

Next.js template with Vanilla extract example

Use template

Generate new application

Follow create-next-app guide to create new Next.js application:

yarn create next-app --typescript

Installation

Choose packages that you will use in your application:

PackageDescription
@mantine/hooks

Hooks for state and UI management

@mantine/core

Core components library: inputs, buttons, overlays, etc.

@mantine/form

Form management library

@mantine/dates

Date inputs, calendars

@mantine/charts

Recharts based charts library

@mantine/notifications

Notifications system

@mantine/code-highlight

Code highlight with your theme colors and styles

@mantine/tiptap

Rich text editor based on Tiptap

@mantine/dropzone

Capture files with drag and drop

@mantine/carousel

Embla based carousel component

@mantine/spotlight

Overlay command center

@mantine/modals

Centralized modals manager

@mantine/nprogress

Navigation progress

Install dependencies:

yarn add @mantine/core @mantine/hooks

PostCSS setup

Install PostCSS plugins and postcss-preset-mantine:

yarn add --dev postcss postcss-preset-mantine postcss-simple-vars

Create postcss.config.cjs file at the root of your application with the following content:

module.exports = {
  plugins: {
    'postcss-preset-mantine': {},
    'postcss-simple-vars': {
      variables: {
        'mantine-breakpoint-xs': '36em',
        'mantine-breakpoint-sm': '48em',
        'mantine-breakpoint-md': '62em',
        'mantine-breakpoint-lg': '75em',
        'mantine-breakpoint-xl': '88em',
      },
    },
  },
};

Setup with pages router

Add styles imports and MantineProvider to the pages/_app.tsx file:

// Import styles of packages that you've installed.
// All packages except `@mantine/hooks` require styles imports
import '@mantine/core/styles.css';

import type { AppProps } from 'next/app';
import { createTheme, MantineProvider } from '@mantine/core';

const theme = createTheme({
  /** Put your mantine theme override here */
});

export default function App({ Component, pageProps }: AppProps) {
  return (
    <MantineProvider theme={theme}>
      <Component {...pageProps} />
    </MantineProvider>
  );
}

Create pages/_document.tsx file with ColorSchemeScript component. Note that it is required even if you use only one color scheme in your application.

import { Head, Html, Main, NextScript } from 'next/document';
import { ColorSchemeScript } from '@mantine/core';

export default function Document() {
  return (
    <Html lang="en">
      <Head>
        <ColorSchemeScript defaultColorScheme="auto" />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

All set! Start development server:

npm run dev

Setup with app router

Add MantineProvider, ColorSchemeScript and styles imports to the app/layout.tsx file:

// Import styles of packages that you've installed.
// All packages except `@mantine/hooks` require styles imports
import '@mantine/core/styles.css';

import { ColorSchemeScript, MantineProvider } from '@mantine/core';

export const metadata = {
  title: 'My Mantine app',
  description: 'I have followed setup instructions carefully',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <ColorSchemeScript />
      </head>
      <body>
        <MantineProvider>{children}</MantineProvider>
      </body>
    </html>
  );
}

All set! Start development server:

npm run dev

app + pages router together

If you use both app and pages router in one application, you need to setup both pages/_app.tsx and app/layout.tsx files as described above.

Next.js Link with polymorphic components

Next.js Link does not work in the same way as other similar components in all Next.js versions.

With Next.js 12 and below:

import Link from 'next/link';
import { Button } from '@mantine/core';

function Demo() {
  return (
    <Link href="/hello" passHref>
      <Button component="a">Next link button</Button>
    </Link>
  );
}

With Next.js 13 and above:

import Link from 'next/link';
import { Button } from '@mantine/core';

function Demo() {
  return (
    <Button component={Link} href="/hello">
      Next link button
    </Button>
  );
}

Server components

All Mantine components use useContext hook to support default props and Styles API. Mantine components cannot be used as server components. It means that components will render both on the server and client.

Entry points of all @mantine/* packages (index.js files) have 'use client'; directive at the top of the file – you do not need to add 'use client'; to your pages/layouts/components.

Compound components in server components

Some components like Popover have associated compound components (Component.XXX), where XXX is a compound component name. Compound components cannot be used in server components. Instead, use ComponentXXX syntax or add 'use client'; directive to the top of the file.

Example that will not work in server components:

import { Popover } from '@mantine/core';

// This will throw an error
export default function Page() {
  return (
    <Popover>
      <Popover.Target>Target</Popover.Target>
      <Popover.Dropdown>Dropdown</Popover.Dropdown>
    </Popover>
  );
}

Example with 'use client'; directive:

'use client';

import { Popover } from '@mantine/core';

// No error
export default function Page() {
  return (
    <Popover>
      <Popover.Target>Target</Popover.Target>
      <Popover.Dropdown>Dropdown</Popover.Dropdown>
    </Popover>
  );
}

Example with ComponentXXX syntax:

import {
  Popover,
  PopoverDropdown,
  PopoverTarget,
} from '@mantine/core';

// No error
export default function Page() {
  return (
    <Popover>
      <PopoverTarget>Trigger</PopoverTarget>
      <PopoverDropdown>Dropdown</PopoverDropdown>
    </Popover>
  );
}

app router tree shaking

To enable tree shaking with app router, enable experimental optimizePackageImports feature in your next.config.mjs:

export default {
  // ...other configuration
  experimental: {
    optimizePackageImports: ['@mantine/core', '@mantine/hooks'],
  },
};