【Next.js】Next.js 13 の App Router に Mantine の v7 ベータ版を導入する

Next.js 13 の App Router に Mantine の v7 ベータ版を導入した時のメモ。
※尚、自分は普段サーバーサイドがメイン領域のため Next.js の経験は浅いです。認識が誤っている可能性もありますので、ご了承ください。

Next.js 13 に Mantine を導入したい

2023年8月21日時点の Mantine 最新版(v6)では Next.js 13 の App Router には対応しておらず、v7 で対応予定とのこと。v7 のベータ版は既にリリースされているので、暫定的に Next.js にインストールしてみる。

v7 リリースまでの流れ

まず、公式サイトの導入方法は従来版の Page Router 向けの記載であるため、ルーティングの仕様が大きく変更された App Router に適用するとビルド時にエラーが発生する。Mantine の Github 上では、この問題について issue が起票されており、2023年8月においても現在進行系で議論が展開されている。この議論の中で、公式はリリース予定の v7 の全体像を以下のように提示している。

Will I be able to use mantine v7 as server component? No, all Mantine components support default props feature – you can define props on MantineProvider and these props will be added to every component inside your application. I find this feature useful, and it is not going away to support server components.
Will I be able to use mantine v7 in edge functions? Yes, v7 does not depend on emotion and does not require any additional Node.js logic
What is the purpose of migration to native CSS if Mantine components cannot be used as server components? The purposes of migration are to simplify project maintenance, improve styles performance, address long-standing ssr related issues (see FOUC, Remix and Next.js issues in this repo) and provide a better API for integration with third-party styling libraries.
Will I be able to use v7 with Next.js app router? Yes, you will be able to use Mantine components with app router. All Mantine components have 'use client'; prefix in index.js file – you do not have to add it on top of your files.

大きな変更点としては、v7 では Emotion の依存をなくすことにある。その背景には CSS-in-JS を脱却しネイティブ CSS に移行することにあるようだ。尚、CSS-in-JS については以前よりパフォーマンスの問題が指摘されており、現在 React の公式ドキュメントでは非推奨とされている。そのため、今後 Next.js で Emotion を使い続けるか否かで対応が異なってくる。

Emotion を使い続ける場合

訳あって Emotion を使い続ける必要がある場合も、公式が実装例を Github に置いてくれている。Next プロジェクト作成時に自動生成されるlayout.tsx とは別に emotion.tsx を作成し、カスタムキャッシュを行うといったアプローチになっている。ベータ版の公式サイトを見る限りは、v7 のベータ版でも適用可能のように見受けられるが、今後いつ互換性が打ち切られてもいいように、恒久的には脱 Emotion を図るべきと言えるだろう。

Emotion を使わない場合

Emotion を使わない場合は Mantine をバージョンアップする方向で考える。今回は暫定的にベータ版を導入するので、安定版としてリリースされた際は別途アップデートが必要になる。

パッケージをインストール

npm install @mantine/core@7.0.0-beta.0 @mantine/hooks@7.0.0-beta.0

Post CSS をインストール

npm install --save-dev postcss postcss-preset-mantine postcss-simple-vars

ファイルの書き換え

postcss.config.js tsconfig.json layout.tsx ファイルを以下に置き換える。

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    "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",
      },
    },
  },
};
    "paths": {
-     "@/*": ["./src/*"]
+     "@/*": ["./src/*", "./components/*"]
    }
import '@mantine/core/styles.css';
import React from 'react';
import { MantineProvider, ColorSchemeScript } from '@mantine/core';

export const metadata = {
  title: 'Mantine Next.js template',
  description: 'I am using Mantine with Next.js!',
};

export default function RootLayout({ children }: { children: any }) {
  return (
    <html lang="en">
      <head>
        <ColorSchemeScript />
        <link rel="shortcut icon" href="/favicon.svg" />
      </head>
      <body>
        <MantineProvider>{children}</MantineProvider>
      </body>
    </html>
  );
}

参考サイト