Usage with Next.js

Usage with Next.js (Next.js와 함께 사용하기)

Next.js에서 Mantine을 설정하는 방법을 안내해 드릴게요. 템플릿, pages router/app router 설정, 다형성 컴포넌트와의 Link 사용, 서버 컴포넌트 주의사항을 설명해요.

출처: 문서

본문

템플릿으로 시작하기

가장 쉬운 시작 방법은 템플릿 중 하나를 사용하는 것이에요. 모든 템플릿은 올바르게 구성되어 있어요. PostCSS 설정, ColorSchemeScript와 다른 필수 기능을 포함해요. 일부 템플릿에는 Jest, Storybook, oxlint 같은 추가 기능도 있어요.

GitHub에 익숙하지 않다면 이 페이지에서 템플릿으로 프로젝트를 부트스트랩하는 자세한 방법을 볼 수 있어요.

  • next-app-template — Next.js app router + 전체 설정 (Jest, Storybook, oxlint) — Use template
  • next-pages-template — Next.js pages router + 전체 설정 (Jest, Storybook, oxlint) — Use template
  • next-app-min-template — Next.js app router + 최소 설정 — Use template
  • next-pages-min-template — Next.js pages router + 최소 설정 — Use template
  • next-vanilla-extract-template — Next.js + Vanilla Extract 예제 — Use template

새 애플리케이션 생성

create-next-app 가이드를 따라 새 Next.js 애플리케이션을 만들어요:

yarn create next-app --typescript

설치

애플리케이션에서 사용할 패키지를 선택하세요:

패키지 설명
@mantine/hooks 상태 및 UI 관리를 위한 훅
@mantine/core 핵심 컴포넌트 라이브러리: 입력, 버튼, 오버레이 등
@mantine/form 폼 관리 라이브러리
@mantine/dates 날짜 입력, 캘린더
@mantine/charts Recharts 기반 차트 라이브러리
@mantine/notifications 알림 시스템
@mantine/code-highlight 테마 색상과 스타일을 적용한 코드 하이라이트
@mantine/tiptap Tiptap 기반 리치 텍스트 에디터
@mantine/dropzone 드래그 앤 드롭으로 파일 받기
@mantine/carousel Embla 기반 캐러셀 컴포넌트
@mantine/lightbox 캐러셀 내비게이션이 있는 전체 화면 미디어 라이트박스
@mantine/spotlight 오버레이 커맨드 센터
@mantine/modals 중앙화된 모달 관리자
@mantine/nprogress 내비게이션 진행률

의존성을 설치해요:

yarn add @mantine/core @mantine/hooks

PostCSS 설정

PostCSS 플러그인과 postcss-preset-mantine을 설치해요:

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

애플리케이션 루트에 postcss.config.cjs 파일을 만들고 다음 내용을 넣어요:

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',
      },
    },
  },
};

pages router 설정

pages/_app.tsx 파일에 스타일 import와 MantineProvider를 추가해요:

// 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>
  );
}

ColorSchemeScript 컴포넌트로 pages/_document.tsx 파일을 만들어요. 애플리케이션에서 하나의 color scheme만 써도 필요하다는 점에 주의하세요:

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

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

모든 준비가 끝났어요. 개발 서버를 시작해요:

npm run dev

app router 설정

app/layout.tsx 파일에 MantineProvider, ColorSchemeScript, 스타일 import를 추가해요:

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

import { ColorSchemeScript, MantineProvider, mantineHtmlProps } 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" {...mantineHtmlProps}>
      <head>
        <ColorSchemeScript />
      </head>
      <body>
        <MantineProvider>{children}</MantineProvider>
      </body>
    </html>
  );
}

모든 준비가 끝났어요. 개발 서버를 시작해요:

npm run dev

app + pages router 함께 사용

하나의 애플리케이션에서 app과 pages router를 모두 사용한다면 위에서 설명한 대로 pages/_app.tsx와 app/layout.tsx 파일을 모두 설정해야 해요.

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

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

서버 컴포넌트

모든 Mantine 컴포넌트는 default props와 Styles API를 지원하기 위해 컨텍스트가 필요해요. Mantine 컴포넌트는 서버 컴포넌트로 사용할 수 없어요. 즉 컴포넌트가 서버와 클라이언트 양쪽에서 렌더링된다는 뜻이에요.

모든 @mantine/* 패키지의 진입점(index.js 파일)에는 파일 맨 위에 'use client'; 지시문이 있어서, 페이지/레이아웃/컴포넌트에 'use client';를 추가할 필요가 없어요.

서버 컴포넌트에서의 복합 컴포넌트

Popover 같은 일부 컴포넌트는 연관된 복합 컴포넌트(Component.XXX — XXX는 복합 컴포넌트 이름)를 가져요. 복합 컴포넌트는 서버 컴포넌트에서 사용할 수 없어요. 대신 ComponentXXX 문법을 사용하거나 파일 맨 위에 'use client'; 지시문을 추가하세요.

서버 컴포넌트에서 동작하지 않는 예시:

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>
  );
}

'use client'; 지시문이 있는 예시:

'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>
  );
}

ComponentXXX 문법 예시:

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

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

app router 트리 셰이킹

app router에서 트리 셰이킹을 활성화하려면 next.config.mjs에서 실험적 optimizePackageImports 기능을 켜세요:

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

트러블슈팅

Next.js 애플리케이션에서 Mantine에 문제가 있다면, app router와 서버 컴포넌트의 가장 흔한 문제를 다루는 Help Center 문서를 확인하세요.

더 알아보기 (Learn more)