RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/mui/material-ui/diff

Two files, one repository

mui/material-ui ships 1 format across 5 indexed files. The question worth asking is whether the second one says anything the first does not.

A · AGENTS.md · 1084 wordsB · skills/material-ui-nextjs/AGENTS.md · 890 words
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections120173%
Commands02320%
Section tags58136%

What each file covers

Sections

1 shared · 20 only in A · 17 only in B
  • − AGENTS.md
  • − Package Manager
  • − Common Commands
  • − Development
  • − Building
  • − Testing
  • − Code Quality
  • − API Documentation
  • − Docs demos
  • − Architecture
  • − Code Conventions
  • − Errors
  • − Component Structure
  • − Accessibility Testing
  • − in one terminal
  • − in another — note no `--`, pnpm forwards args directly
  • − Imports
  • − Agent Skills
  • − Pre-PR Checklist
  • − PR Title Format
  • + Material UI and Next.js
  • + Abstract
  • + Table of contents
  • + App Router (recommended)
  • + Dependencies
  • + Root layout
  • + Optional cache `options`
  • + URL hooks and Suspense
  • + Pages Router
  • + `_document.tsx`
  • + `_app.tsx`
  • + Optional: custom cache and cascade layers
  • + Fonts (`next/font`)
  • + CSS theme variables and SSR
  • + Other styling stacks (CSS layers)
  • + Next.js Link and `component` prop
  • + Further reading
  •   TypeScript

Commands

0 shared · 23 only in A · 2 only in B
  • − pnpm -F @mui/material add some-package
  • − pnpm -F @mui/material build
  • − pnpm install
  • − pnpm docs:dev
  • − pnpm release:build
  • − pnpm docs:build
  • − pnpm test:unit
  • − pnpm test:unit ComponentName
  • − pnpm test:unit -t "test name"
  • − pnpm test:browser
  • − pnpm test:e2e
  • − pnpm test:regressions
  • − pnpm prettier
  • − pnpm eslint
  • − pnpm typescript
  • − pnpm proptypes && pnpm docs:api
  • − pnpm docs:typescript:formatted
  • − pnpm test:regressions:server
  • − pnpm test:regressions:run -t '/docs-components-buttons/'
  • − pnpm test:regressions:run -t '/docs-components-buttons/BasicButtons$'
  • − pnpm test:regressions:run -t '/docs-components-(buttons|chips)/'
  • − pnpm extract-error-codes
  • − pnpm vale <file1> <file2> ...
  • + pnpm add @mui/material-nextjs @emotion/cache
  • + pnpm add @mui/material-nextjs @emotion/cache @emotion/server

Section tags

5 shared · 8 only in A · 1 only in B
  • − build
  • − test
  • − lint-format
  • − git-pr
  • − api
  • − do-not
  • − agent-behaviour
  • − docs
  • + dependencies
  •   setup
  •   code-style
  •   architecture
  •   types
  •   ui

Line diff

+82 added−177 removed65 unchanged26.9% identical
mui/material-ui · AGENTS.md
@@ −1 @@
1# AGENTS.md
2 
3This file provides guidance for AI agents working with code in this repository.
4 
5## Package Manager
6 
7**Only pnpm is supported** (yarn/npm will fail). Use the `-F` flag for workspace operations:
8 
9```bash
10pnpm -F @mui/material add some-package # Add dependency to a package
11pnpm -F @mui/material build # Build a specific package
12```
13 
14Never use `cd` to navigate into package directories for commands.
15 
16## Common Commands
17 
18### Development
19 
20```bash
21pnpm install # Install deps if necessary
22pnpm docs:dev # Start docs dev server only
23```
24 
25### Building
 
 
 
 
 
 
26 
27```bash
28pnpm release:build # Build all packages (except docs)
29pnpm docs:build # Build documentation site
30```
31 
32### Testing
33 
34```bash
35pnpm test:unit # Run all unit tests (jsdom)
36pnpm test:unit ComponentName # Run tests matching pattern
37pnpm test:unit -t "test name" # Grep for specific test name
38pnpm test:browser # Run tests in real browsers (Chrome, Firefox, WebKit)
39pnpm test:e2e # End-to-end tests
40pnpm test:regressions # Visual regression tests
41```
42 
43### Code Quality
44 
45```bash
46pnpm prettier # Format staged changes
47pnpm eslint # Lint with cache
48pnpm typescript # Type check all packages
49```
50 
51### API Documentation
52 
53After changing component props or TypeScript declarations:
54 
55```bash
56pnpm proptypes && pnpm docs:api
57```
58 
59### Docs demos
60 
61Always author the TypeScript version of the demos. To generate the JavaScript variant, run:
62 
63```bash
64pnpm docs:typescript:formatted
65```
66 
67## Architecture
68 
69This is a monorepo managed by Lerna with Nx for caching. Key packages:
70 
71- `@mui/material` - Core Material UI components
72- `@mui/system` - Styling system (sx prop, styled, theme)
73- `@mui/lab` - Experimental components (new components go here first)
74- `@mui/icons-material` - Material Design icons
75- `@mui/utils` - Internal utilities
76- `@mui/styled-engine` - CSS-in-JS abstraction (Emotion by default)
77 
78Internal packages (not published): `@mui-internal/*`, `@mui/internal-*`
79 
80## Code Conventions
81 
82### TypeScript
83 
84- Use `interface` (not `type`) for component props
85- Export `{ComponentName}Props` interface from component files
86- Path aliases available: `@mui/material` → `./packages/mui-material/src`
87 
88### Errors
89 
90These guidelines only apply for errors thrown from public packages.
91 
92Every error message must:
93 
941. **Say what happened** - Describe the problem clearly
952. **Say why it's a problem** - Explain the consequence
963. **Point toward how to solve it** - Give actionable guidance
97 
98Format:
99 
100- Prefix with `MUI: `
101- Use string concatenation for readability
102- Include a documentation link when applicable (`https://mui.com/r/...`)
103 
104#### Error Minifier
 
 
105 
106Use the `/* minify-error */` comment to activate the babel plugin:
107 
108```tsx
109throw /* minify-error */ new Error(
110 'MUI: Expected valid input target. ' +
111 'Did you use a custom `inputComponent` and forget to forward refs? ' +
112 'See https://mui.com/r/input-component-ref-interface for more info.',
113);
114```
115 
116The minifier works with both `Error` and `TypeError` constructors.
117 
118#### After Adding/Updating Errors
 
119 
120Run `pnpm extract-error-codes` to update `docs/public/static/error-codes.json`.
121 
122**Important:** If the update created a new error code, but the new and original message have the same number of arguments and semantics haven't changed, update the original error in `error-codes.json` instead of creating a new code.
123 
124### Component Structure
125 
126```text
127packages/mui-material/src/Button/
128├── Button.tsx # Component implementation
129├── Button.d.ts # TypeScript declarations (for JSDoc API docs)
130├── Button.test.js # Unit tests
131├── buttonClasses.ts # CSS classes
132└── index.ts # Public exports
133```
134 
135### Testing
136 
137- Use `createRenderer()` from `@mui/internal-test-utils`
138- Use Chai BDD-style assertions (`expect(x).to.equal(y)`)
139- Custom matchers: `toErrorDev()`, `toWarnDev()` for console assertions
140- Prefer testing components with full interactions using `user.*` methods. Avoid `fireEvent` and `setProps` if possible.
141- If tests require the browser because, for example, they require layout measurements, restrict it to the Chromium env by using `it.skipIf(isJsdom())` or `describe.skipIf(isJsdom())` (search other tests for example usage if unsure).
142 
143```js
144import { createRenderer } from '@mui/internal-test-utils';
145 
146describe('Button', () => {
147 const { render } = createRenderer();
148 
149 it('renders children', async () => {
150 const handleClick = vi.fn();
151 const { getByRole, user } = render(<Button onClick={handleClick}>Hello</Button>);
152 
153 const button = getByRole('button');
154 expect(button).to.have.text('Hello');
155 
156 await user.click(button);
157 expect(handleClick).toHaveBeenCalledTimes(1);
158 });
159});
160```
161 
162### Accessibility Testing
163 
164axe-core runs inside the visual-regression Playwright loop (`test/regressions/index.test.js`) — no separate browser session. Screenshots and a11y are independent: a demo can opt out of one and still run the other.
165 
166Key files:
167 
168- `test/regressions/demoMeta.ts` — `SCREENSHOT_RULES` and `A11Y_RULES` arrays, matched last-wins (no inheritance: overrides restate every field) against `docs/data/material/components/{slug}/{Demo}` (minimatch globs).
169- `test/regressions/a11y/axe.ts` — asserts `color-contrast` and `link-in-text-block` unless listed in `skipAssertions`.
170- `test/regressions/a11y/a11yReporter.ts` — writes one file per slug at `docs/data/material/components/{slug}/{slug}.a11y.json`. Each file is keyed by demo name, then by axe rule ID. Each rule records a `status` (`pass`, `fail`, or `incomplete`) and WCAG tags.
171 
172Enroll a component (slug-wide, or narrow with brace-glob):
173 
174```ts
175// test/regressions/demoMeta.ts
176{ test: 'docs/data/material/components/alert/*', enabled: true, skipAssertions: ['color-contrast'] },
177{ test: 'docs/data/material/components/buttons/{BasicButtons,ColorButtons}', enabled: true },
178```
179 
180Override a specific demo: append a per-demo rule _after_ the slug-wide rule (last-match-wins; the override must restate every field it wants):
181 
182```ts
183{ test: 'docs/data/material/components/popover/AnchorPlayground', enabled: false }, // Redux isolation
 
 
184```
185 
186Run `pnpm test:regressions` to refresh the `*.a11y.json` files. CI fails if any are stale.
187 
188For local iteration, scope the run with vitest's `-t` test-name filter (matched against the `it()` strings, which contain the route). Non-matching tests are skipped — their bodies don't execute, so the browser never navigates to those routes.
189 
190```bash
191# in one terminal
192pnpm test:regressions:server
193 
194# in another — note no `--`, pnpm forwards args directly
195pnpm test:regressions:run -t '/docs-components-buttons/' # one slug
196pnpm test:regressions:run -t '/docs-components-buttons/BasicButtons$' # one demo
197pnpm test:regressions:run -t '/docs-components-(buttons|chips)/' # multiple slugs
198```
199 
200Filtered runs only refresh the matched slugs' `*.a11y.json`. Run the unfiltered `pnpm test:regressions` before pushing.
 
 
 
 
 
201 
202### Imports
203 
204Use one-level deep imports to avoid bundling entire packages:
205 
206```js
207import Button from '@mui/material/Button'; // Good
208import { Button } from '@mui/material'; // Avoid in packages
209```
210 
211## Agent Skills
212 
213Packaged guidance for common integration topics lives under `skills/`. Each skill is a self-contained directory:
214 
215| Skill | Focus |
216| :--------------------------------------------------------------------- | :---------------------------------------------------------- |
217| [skills/material-ui-styling](./skills/material-ui-styling/AGENTS.md) | `sx`, `styled()`, theme overrides, slots, global CSS |
218| [skills/material-ui-theming](./skills/material-ui-theming/AGENTS.md) | `createTheme`, design tokens, `colorSchemes`, CSS variables |
219| [skills/material-ui-nextjs](./skills/material-ui-nextjs/AGENTS.md) | App/Pages Router, Emotion cache, `next/font`, `Link`, SSR |
220| [skills/material-ui-tailwind](./skills/material-ui-tailwind/AGENTS.md) | Tailwind v4 `@layer`, `enableCssLayer`, v3 interop |
221 
222Read the relevant `AGENTS.md` when helping users with those topics.
223 
224## Pre-PR Checklist
225 
2261. `pnpm prettier` - Format code
2272. `pnpm eslint` - Pass linting
2283. `pnpm typescript` - Pass type checking
2294. `pnpm test:unit` - Pass unit tests
2305. If API changed: `pnpm proptypes && pnpm docs:api`
2316. If demos changed: `pnpm docs:typescript:formatted`
2327. If `.md` files changed: `pnpm vale <file1> <file2> ...` - Check prose style and grammar
233 
234## PR Title Format
235 
236`[component] Imperative description`
237 
238Examples:
239 
240- `[button] Add loading state`
241- `[docs] Fix typo in Grid documentation`
242 
mui/material-ui · skills/material-ui-nextjs/AGENTS.md
@@ +1 @@
1# Material UI and Next.js
2 
3Version 1.0.0 (Material UI v9)
4 
5> **Version notice:** This skill targets Material UI v9 (`>=9.0.0 <10.0.0`). If you are using a different major version, verify the API details before following this guidance.
6 
7> Note: This document is for agents and LLMs integrating Material UI with Next.js. Source: `docs/data/material/integrations/nextjs/nextjs.md` and related integration docs in this repository.
8 
9---
 
 
 
10 
11## Abstract
12 
13Material UI uses Emotion for styles. On Next.js you must wire an Emotion cache so SSR and streaming produce correct CSS (prefer injecting styles into `head` instead of only `body`). The `@mui/material-nextjs` package supplies `AppRouterCacheProvider` (App Router) and `AppCacheProvider` / `DocumentHeadTags` (Pages Router). Material UI components ship as client components (`"use client"`); they still SSR but are not React Server Components. Match the package import suffix (for example `v15-appRouter`) to your Next.js major version.
14 
15---
16 
17## Table of contents
 
 
 
18 
191. [App Router (recommended)](#app-router-recommended)
202. [Pages Router](#pages-router)
213. [Fonts (`next/font`)](#fonts-nextfont)
224. [CSS theme variables and SSR](#css-theme-variables-and-ssr)
235. [Other styling stacks (CSS layers)](#other-styling-stacks-css-layers)
246. [Next.js Link and `component` prop](#nextjs-link-and-component-prop)
257. [Further reading](#further-reading)
26 
27---
 
 
 
28 
29## App Router (recommended)
30 
31### Dependencies
 
 
 
 
 
 
 
32 
33Have `@mui/material` and `next` installed, then add:
34 
35- `@mui/material-nextjs`
36- `@emotion/cache`
 
 
 
37 
38Example: `pnpm add @mui/material-nextjs @emotion/cache`
39 
40### Root layout
41 
42In `app/layout.tsx`, wrap everything under `<body>` with `AppRouterCacheProvider` from the entry that matches your Next major, for example:
 
 
43 
44`import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';`
45 
46(Use the `v1X-appRouter` path that matches your Next.js version if not on v15.)
47 
48Why: it collects CSS from MUI System during server rendering and streaming so styles attach predictably; it is recommended so styles go to `<head>` instead of only `<body>`. See [Next.js integration—Configuration](https://mui.com/material-ui/integrations/nextjs.md#configuration).
 
 
49 
50### Optional cache `options`
51 
52Pass `options` to `AppRouterCacheProvider` to override [Emotion cache options](https://emotion.sh/docs/@emotion/cache#options), for example `key: 'css'` (the default MUI key is `mui`). See [Next.js integration—Custom cache (optional)](https://mui.com/material-ui/integrations/nextjs.md#custom-cache-optional).
53 
54### URL hooks and Suspense
 
 
 
 
 
55 
56Dashboards and internal tools often combine MUI client components with URL-driven UI (filters, tabs, pagination) using `useSearchParams()` from `next/navigation`.
57 
58Next.js expects a `<Suspense>` boundary around the part of the tree that uses `useSearchParams` (and similar patterns that opt the route into client-side rendering), otherwise you can get build failures or runtime errors about a missing Suspense boundary.
59 
60Practical pattern: keep `app/.../page.tsx` as a server component when possible; render a client subtree that uses components such as `Table`, `Tabs`, or `TextField` and is tied to the query string inside `<Suspense>` from that server page. Do not use `fallback={null}` for UI that occupies layout space (toolbars, filters, and similar); it tends to cause layout shift when the client mounts. Use a fallback that matches the real layout (for example `Skeleton` with `Stack` or `Box` and the same `minHeight` and rough dimensions as the final UI). Full example: [Next.js integration—URL-driven UI and the Suspense boundary](https://mui.com/material-ui/integrations/nextjs.md#url-driven-ui-and-the-suspense-boundary).
61 
62Official reference: [Next.js—`useSearchParams`](https://nextjs.org/docs/app/api-reference/functions/use-search-params) (static rendering and Suspense notes vary by major version).
 
 
63 
64---
65 
66## Pages Router
67 
68### Dependencies
69 
70Add `@mui/material-nextjs`, `@emotion/cache`, and `@emotion/server`.
 
 
71 
72Example: `pnpm add @mui/material-nextjs @emotion/cache @emotion/server`
73 
74### `_document.tsx`
 
 
75 
76- Import `DocumentHeadTags` and `documentGetInitialProps` from the `v15-pagesRouter` (or matching `v1X-pagesRouter`) entry.
77- Render `<DocumentHeadTags {...props} />` inside `<Head>`.
78- Assign `getInitialProps` to call `documentGetInitialProps`.
79 
80### `_app.tsx`
81 
82Wrap the app with `AppCacheProvider` from the same major entry (for example `v15-pagesRouter`).
 
 
 
 
 
 
83 
84### Optional: custom cache and cascade layers
85 
86- Pass a custom `emotionCache` into `documentGetInitialProps` options when needed.
87- For `@layer`, use `createEmotionCache({ enableCssLayer: true })` from `@mui/material-nextjs`, pass it from `_document` and align `_app` with the same cache pattern. See [Next.js integration—Cascade layers (optional)](https://mui.com/material-ui/integrations/nextjs.md#cascade-layers-optional).
88 
89### TypeScript
90 
91Extend `Document` props with `DocumentHeadTagsProps` from the same import path. See [Next.js integration—TypeScript](https://mui.com/material-ui/integrations/nextjs.md#typescript).
92 
93---
94 
95## Fonts (`next/font`)
 
 
 
 
 
 
 
96 
97App Router: theme modules that call `createTheme` need `'use client'` when they are consumed from server components. Use `next/font/google` (or local fonts), set `variable: '--font-…'`, put `className={font.variable}` on `<html>` (or as in docs), and set `typography.fontFamily` to `'var(--font-…)'`. Wrap with `ThemeProvider` inside `AppRouterCacheProvider` as needed.
98 
99Pages Router: similar pattern in `pages/_app.tsx` with `AppCacheProvider` and `ThemeProvider`.
 
 
 
 
100 
101Details: [Next.js integration—Font optimization](https://mui.com/material-ui/integrations/nextjs.md#font-optimization) (App) and [Next.js integration—Font optimization](https://mui.com/material-ui/integrations/nextjs.md#font-optimization-1) (Pages).
 
102 
103---
 
104 
105## CSS theme variables and SSR
 
 
106 
107Enable `cssVariables: true` in `createTheme` when using [CSS theme variables](https://mui.com/material-ui/customization/css-theme-variables/overview.md). For SSR flicker and `InitColorSchemeScript`, follow [CSS theme variables—Preventing SSR flickering](https://mui.com/material-ui/customization/css-theme-variables/configuration.md#preventing-ssr-flickering) and [CSS theme variables overview—Advantages](https://mui.com/material-ui/customization/css-theme-variables/overview.md#advantages). Add `suppressHydrationWarning` to `<html>` when using `colorSchemes` — the color scheme attribute is written client-side on first render and will otherwise produce a React hydration mismatch.
 
108 
109---
 
 
 
 
110 
111## Other styling stacks (CSS layers)
112 
113If you combine MUI with Tailwind CSS, CSS Modules, or other global CSS, set `enableCssLayer: true` on `AppRouterCacheProvider`:
114 
115`<AppRouterCacheProvider options={{ enableCssLayer: true }}>`
116 
117That wraps MUI output in `@layer mui` so anonymous layers can override as intended. See [Next.js integration—Using other styling solutions](https://mui.com/material-ui/integrations/nextjs.md#using-other-styling-solutions) and [MDN—@layer](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@layer).
 
 
118 
119---
120 
121## Next.js Link and `component` prop
 
 
 
 
122 
123Next.js v16: passing `next/link` directly into `component` can trigger "Functions cannot be passed directly to Client Components". Fix: a small client re-export:
124 
125```tsx
126'use client';
127import Link, { LinkProps } from 'next/link';
128export default Link;
129```
130 
131Import that wrapper and use `component={Link}` on `Button` and similar. See [Next.js integration—Next.js v16 Client Component restriction](https://mui.com/material-ui/integrations/nextjs.md#nextjs-v16-client-component-restriction).
132 
133Pages Router and theme-wide patterns: see [Routing libraries—Next.js Pages Router](https://mui.com/material-ui/integrations/routing.md#nextjs-pages-router) and the [material-ui-nextjs-pages-router-ts example](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-pages-router-ts).
134 
135---
 
 
136 
137## Further reading
 
 
 
 
138 
139| Topic | Link |
140| :------------------------------- | :----------------------------------------------------------------------------------------------------- |
141| Full integration guide | [Next.js integration](https://mui.com/material-ui/integrations/nextjs.md) |
142| Example (App Router, TypeScript) | [material-ui-nextjs-ts](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts) |
143| Routing + Link adapters | [Routing libraries](https://mui.com/material-ui/integrations/routing.md) |
144| RSC vs SSR (terminology) | [React WG discussion](https://github.com/reactwg/server-components/discussions/4) |
145 
146Import path cheat sheet: [reference.md](reference.md).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147 
@@ −1 +1 @@
1−# AGENTS.md
1+# Material UI and Next.js
22  
3−This file provides guidance for AI agents working with code in this repository.
3+Version 1.0.0 (Material UI v9)
44  
5−## Package Manager
5+> **Version notice:** This skill targets Material UI v9 (`>=9.0.0 <10.0.0`). If you are using a different major version, verify the API details before following this guidance.
66  
7−**Only pnpm is supported** (yarn/npm will fail). Use the `-F` flag for workspace operations:
7+> Note: This document is for agents and LLMs integrating Material UI with Next.js. Source: `docs/data/material/integrations/nextjs/nextjs.md` and related integration docs in this repository.
88  
9−```bash
10−pnpm -F @mui/material add some-package # Add dependency to a package
11−pnpm -F @mui/material build # Build a specific package
12−```
9+---
1310  
14−Never use `cd` to navigate into package directories for commands.
11+## Abstract
1512  
16−## Common Commands
13+Material UI uses Emotion for styles. On Next.js you must wire an Emotion cache so SSR and streaming produce correct CSS (prefer injecting styles into `head` instead of only `body`). The `@mui/material-nextjs` package supplies `AppRouterCacheProvider` (App Router) and `AppCacheProvider` / `DocumentHeadTags` (Pages Router). Material UI components ship as client components (`"use client"`); they still SSR but are not React Server Components. Match the package import suffix (for example `v15-appRouter`) to your Next.js major version.
1714  
18−### Development
15+---
1916  
20−```bash
21−pnpm install # Install deps if necessary
22−pnpm docs:dev # Start docs dev server only
23−```
17+## Table of contents
2418  
25−### Building
19+1. [App Router (recommended)](#app-router-recommended)
20+2. [Pages Router](#pages-router)
21+3. [Fonts (`next/font`)](#fonts-nextfont)
22+4. [CSS theme variables and SSR](#css-theme-variables-and-ssr)
23+5. [Other styling stacks (CSS layers)](#other-styling-stacks-css-layers)
24+6. [Next.js Link and `component` prop](#nextjs-link-and-component-prop)
25+7. [Further reading](#further-reading)
2626  
27−```bash
28−pnpm release:build # Build all packages (except docs)
29−pnpm docs:build # Build documentation site
30−```
27+---
3128  
32−### Testing
29+## App Router (recommended)
3330  
34−```bash
35−pnpm test:unit # Run all unit tests (jsdom)
36−pnpm test:unit ComponentName # Run tests matching pattern
37−pnpm test:unit -t "test name" # Grep for specific test name
38−pnpm test:browser # Run tests in real browsers (Chrome, Firefox, WebKit)
39−pnpm test:e2e # End-to-end tests
40−pnpm test:regressions # Visual regression tests
41−```
31+### Dependencies
4232  
43−### Code Quality
33+Have `@mui/material` and `next` installed, then add:
4434  
45−```bash
46−pnpm prettier # Format staged changes
47−pnpm eslint # Lint with cache
48−pnpm typescript # Type check all packages
49−```
35+- `@mui/material-nextjs`
36+- `@emotion/cache`
5037  
51−### API Documentation
38+Example: `pnpm add @mui/material-nextjs @emotion/cache`
5239  
53−After changing component props or TypeScript declarations:
40+### Root layout
5441  
55−```bash
56−pnpm proptypes && pnpm docs:api
57−```
42+In `app/layout.tsx`, wrap everything under `<body>` with `AppRouterCacheProvider` from the entry that matches your Next major, for example:
5843  
59−### Docs demos
44+`import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';`
6045  
61−Always author the TypeScript version of the demos. To generate the JavaScript variant, run:
46+(Use the `v1X-appRouter` path that matches your Next.js version if not on v15.)
6247  
63−```bash
64−pnpm docs:typescript:formatted
65−```
48+Why: it collects CSS from MUI System during server rendering and streaming so styles attach predictably; it is recommended so styles go to `<head>` instead of only `<body>`. See [Next.js integration—Configuration](https://mui.com/material-ui/integrations/nextjs.md#configuration).
6649  
67−## Architecture
50+### Optional cache `options`
6851  
69−This is a monorepo managed by Lerna with Nx for caching. Key packages:
52+Pass `options` to `AppRouterCacheProvider` to override [Emotion cache options](https://emotion.sh/docs/@emotion/cache#options), for example `key: 'css'` (the default MUI key is `mui`). See [Next.js integration—Custom cache (optional)](https://mui.com/material-ui/integrations/nextjs.md#custom-cache-optional).
7053  
71−- `@mui/material` - Core Material UI components
72−- `@mui/system` - Styling system (sx prop, styled, theme)
73−- `@mui/lab` - Experimental components (new components go here first)
74−- `@mui/icons-material` - Material Design icons
75−- `@mui/utils` - Internal utilities
76−- `@mui/styled-engine` - CSS-in-JS abstraction (Emotion by default)
54+### URL hooks and Suspense
7755  
78−Internal packages (not published): `@mui-internal/*`, `@mui/internal-*`
56+Dashboards and internal tools often combine MUI client components with URL-driven UI (filters, tabs, pagination) using `useSearchParams()` from `next/navigation`.
7957  
80−## Code Conventions
58+Next.js expects a `<Suspense>` boundary around the part of the tree that uses `useSearchParams` (and similar patterns that opt the route into client-side rendering), otherwise you can get build failures or runtime errors about a missing Suspense boundary.
8159  
82−### TypeScript
60+Practical pattern: keep `app/.../page.tsx` as a server component when possible; render a client subtree that uses components such as `Table`, `Tabs`, or `TextField` and is tied to the query string inside `<Suspense>` from that server page. Do not use `fallback={null}` for UI that occupies layout space (toolbars, filters, and similar); it tends to cause layout shift when the client mounts. Use a fallback that matches the real layout (for example `Skeleton` with `Stack` or `Box` and the same `minHeight` and rough dimensions as the final UI). Full example: [Next.js integration—URL-driven UI and the Suspense boundary](https://mui.com/material-ui/integrations/nextjs.md#url-driven-ui-and-the-suspense-boundary).
8361  
84−- Use `interface` (not `type`) for component props
85−- Export `{ComponentName}Props` interface from component files
86−- Path aliases available: `@mui/material` → `./packages/mui-material/src`
62+Official reference: [Next.js—`useSearchParams`](https://nextjs.org/docs/app/api-reference/functions/use-search-params) (static rendering and Suspense notes vary by major version).
8763  
88−### Errors
64+---
8965  
90−These guidelines only apply for errors thrown from public packages.
66+## Pages Router
9167  
92−Every error message must:
68+### Dependencies
9369  
94−1. **Say what happened** - Describe the problem clearly
95−2. **Say why it's a problem** - Explain the consequence
96−3. **Point toward how to solve it** - Give actionable guidance
70+Add `@mui/material-nextjs`, `@emotion/cache`, and `@emotion/server`.
9771  
98−Format:
72+Example: `pnpm add @mui/material-nextjs @emotion/cache @emotion/server`
9973  
100−- Prefix with `MUI: `
101−- Use string concatenation for readability
102−- Include a documentation link when applicable (`https://mui.com/r/...`)
74+### `_document.tsx`
10375  
104−#### Error Minifier
76+- Import `DocumentHeadTags` and `documentGetInitialProps` from the `v15-pagesRouter` (or matching `v1X-pagesRouter`) entry.
77+- Render `<DocumentHeadTags {...props} />` inside `<Head>`.
78+- Assign `getInitialProps` to call `documentGetInitialProps`.
10579  
106−Use the `/* minify-error */` comment to activate the babel plugin:
80+### `_app.tsx`
10781  
108−```tsx
109−throw /* minify-error */ new Error(
110− 'MUI: Expected valid input target. ' +
111− 'Did you use a custom `inputComponent` and forget to forward refs? ' +
112− 'See https://mui.com/r/input-component-ref-interface for more info.',
113−);
114−```
82+Wrap the app with `AppCacheProvider` from the same major entry (for example `v15-pagesRouter`).
11583  
116−The minifier works with both `Error` and `TypeError` constructors.
84+### Optional: custom cache and cascade layers
11785  
118−#### After Adding/Updating Errors
86+- Pass a custom `emotionCache` into `documentGetInitialProps` options when needed.
87+- For `@layer`, use `createEmotionCache({ enableCssLayer: true })` from `@mui/material-nextjs`, pass it from `_document` and align `_app` with the same cache pattern. See [Next.js integration—Cascade layers (optional)](https://mui.com/material-ui/integrations/nextjs.md#cascade-layers-optional).
11988  
120−Run `pnpm extract-error-codes` to update `docs/public/static/error-codes.json`.
89+### TypeScript
12190  
122−**Important:** If the update created a new error code, but the new and original message have the same number of arguments and semantics haven't changed, update the original error in `error-codes.json` instead of creating a new code.
91+Extend `Document` props with `DocumentHeadTagsProps` from the same import path. See [Next.js integration—TypeScript](https://mui.com/material-ui/integrations/nextjs.md#typescript).
12392  
124−### Component Structure
93+---
12594  
126−```text
127−packages/mui-material/src/Button/
128−├── Button.tsx # Component implementation
129−├── Button.d.ts # TypeScript declarations (for JSDoc API docs)
130−├── Button.test.js # Unit tests
131−├── buttonClasses.ts # CSS classes
132−└── index.ts # Public exports
133−```
95+## Fonts (`next/font`)
13496  
135−### Testing
97+App Router: theme modules that call `createTheme` need `'use client'` when they are consumed from server components. Use `next/font/google` (or local fonts), set `variable: '--font-…'`, put `className={font.variable}` on `<html>` (or as in docs), and set `typography.fontFamily` to `'var(--font-…)'`. Wrap with `ThemeProvider` inside `AppRouterCacheProvider` as needed.
13698  
137−- Use `createRenderer()` from `@mui/internal-test-utils`
138−- Use Chai BDD-style assertions (`expect(x).to.equal(y)`)
139−- Custom matchers: `toErrorDev()`, `toWarnDev()` for console assertions
140−- Prefer testing components with full interactions using `user.*` methods. Avoid `fireEvent` and `setProps` if possible.
141−- If tests require the browser because, for example, they require layout measurements, restrict it to the Chromium env by using `it.skipIf(isJsdom())` or `describe.skipIf(isJsdom())` (search other tests for example usage if unsure).
99+Pages Router: similar pattern in `pages/_app.tsx` with `AppCacheProvider` and `ThemeProvider`.
142100  
143−```js
144−import { createRenderer } from '@mui/internal-test-utils';
101+Details: [Next.js integration—Font optimization](https://mui.com/material-ui/integrations/nextjs.md#font-optimization) (App) and [Next.js integration—Font optimization](https://mui.com/material-ui/integrations/nextjs.md#font-optimization-1) (Pages).
145102  
146−describe('Button', () => {
147− const { render } = createRenderer();
103+---
148104  
149− it('renders children', async () => {
150− const handleClick = vi.fn();
151− const { getByRole, user } = render(<Button onClick={handleClick}>Hello</Button>);
105+## CSS theme variables and SSR
152106  
153− const button = getByRole('button');
154− expect(button).to.have.text('Hello');
107+Enable `cssVariables: true` in `createTheme` when using [CSS theme variables](https://mui.com/material-ui/customization/css-theme-variables/overview.md). For SSR flicker and `InitColorSchemeScript`, follow [CSS theme variables—Preventing SSR flickering](https://mui.com/material-ui/customization/css-theme-variables/configuration.md#preventing-ssr-flickering) and [CSS theme variables overview—Advantages](https://mui.com/material-ui/customization/css-theme-variables/overview.md#advantages). Add `suppressHydrationWarning` to `<html>` when using `colorSchemes` — the color scheme attribute is written client-side on first render and will otherwise produce a React hydration mismatch.
155108  
156− await user.click(button);
157− expect(handleClick).toHaveBeenCalledTimes(1);
158− });
159−});
160−```
109+---
161110  
162−### Accessibility Testing
111+## Other styling stacks (CSS layers)
163112  
164−axe-core runs inside the visual-regression Playwright loop (`test/regressions/index.test.js`) — no separate browser session. Screenshots and a11y are independent: a demo can opt out of one and still run the other.
113+If you combine MUI with Tailwind CSS, CSS Modules, or other global CSS, set `enableCssLayer: true` on `AppRouterCacheProvider`:
165114  
166−Key files:
115+`<AppRouterCacheProvider options={{ enableCssLayer: true }}>`
167116  
168−- `test/regressions/demoMeta.ts` — `SCREENSHOT_RULES` and `A11Y_RULES` arrays, matched last-wins (no inheritance: overrides restate every field) against `docs/data/material/components/{slug}/{Demo}` (minimatch globs).
169−- `test/regressions/a11y/axe.ts` — asserts `color-contrast` and `link-in-text-block` unless listed in `skipAssertions`.
170−- `test/regressions/a11y/a11yReporter.ts` — writes one file per slug at `docs/data/material/components/{slug}/{slug}.a11y.json`. Each file is keyed by demo name, then by axe rule ID. Each rule records a `status` (`pass`, `fail`, or `incomplete`) and WCAG tags.
117+That wraps MUI output in `@layer mui` so anonymous layers can override as intended. See [Next.js integration—Using other styling solutions](https://mui.com/material-ui/integrations/nextjs.md#using-other-styling-solutions) and [MDN—@layer](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@layer).
171118  
172−Enroll a component (slug-wide, or narrow with brace-glob):
119+---
173120  
174−```ts
175−// test/regressions/demoMeta.ts
176−{ test: 'docs/data/material/components/alert/*', enabled: true, skipAssertions: ['color-contrast'] },
177−{ test: 'docs/data/material/components/buttons/{BasicButtons,ColorButtons}', enabled: true },
178−```
121+## Next.js Link and `component` prop
179122  
180−Override a specific demo: append a per-demo rule _after_ the slug-wide rule (last-match-wins; the override must restate every field it wants):
123+Next.js v16: passing `next/link` directly into `component` can trigger "Functions cannot be passed directly to Client Components". Fix: a small client re-export:
181124  
182−```ts
183−{ test: 'docs/data/material/components/popover/AnchorPlayground', enabled: false }, // Redux isolation
125+```tsx
126+'use client';
127+import Link, { LinkProps } from 'next/link';
128+export default Link;
184129 ```
185130  
186−Run `pnpm test:regressions` to refresh the `*.a11y.json` files. CI fails if any are stale.
131+Import that wrapper and use `component={Link}` on `Button` and similar. See [Next.js integration—Next.js v16 Client Component restriction](https://mui.com/material-ui/integrations/nextjs.md#nextjs-v16-client-component-restriction).
187132  
188−For local iteration, scope the run with vitest's `-t` test-name filter (matched against the `it()` strings, which contain the route). Non-matching tests are skipped — their bodies don't execute, so the browser never navigates to those routes.
133+Pages Router and theme-wide patterns: see [Routing libraries—Next.js Pages Router](https://mui.com/material-ui/integrations/routing.md#nextjs-pages-router) and the [material-ui-nextjs-pages-router-ts example](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-pages-router-ts).
189134  
190−```bash
191−# in one terminal
192−pnpm test:regressions:server
135+---
193136  
194−# in another — note no `--`, pnpm forwards args directly
195−pnpm test:regressions:run -t '/docs-components-buttons/' # one slug
196−pnpm test:regressions:run -t '/docs-components-buttons/BasicButtons$' # one demo
197−pnpm test:regressions:run -t '/docs-components-(buttons|chips)/' # multiple slugs
198−```
137+## Further reading
199138  
200−Filtered runs only refresh the matched slugs' `*.a11y.json`. Run the unfiltered `pnpm test:regressions` before pushing.
139+| Topic | Link |
140+| :------------------------------- | :----------------------------------------------------------------------------------------------------- |
141+| Full integration guide | [Next.js integration](https://mui.com/material-ui/integrations/nextjs.md) |
142+| Example (App Router, TypeScript) | [material-ui-nextjs-ts](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts) |
143+| Routing + Link adapters | [Routing libraries](https://mui.com/material-ui/integrations/routing.md) |
144+| RSC vs SSR (terminology) | [React WG discussion](https://github.com/reactwg/server-components/discussions/4) |
201145  
202−### Imports
203− 
204−Use one-level deep imports to avoid bundling entire packages:
205− 
206−```js
207−import Button from '@mui/material/Button'; // Good
208−import { Button } from '@mui/material'; // Avoid in packages
209−```
210− 
211−## Agent Skills
212− 
213−Packaged guidance for common integration topics lives under `skills/`. Each skill is a self-contained directory:
214− 
215−| Skill | Focus |
216−| :--------------------------------------------------------------------- | :---------------------------------------------------------- |
217−| [skills/material-ui-styling](./skills/material-ui-styling/AGENTS.md) | `sx`, `styled()`, theme overrides, slots, global CSS |
218−| [skills/material-ui-theming](./skills/material-ui-theming/AGENTS.md) | `createTheme`, design tokens, `colorSchemes`, CSS variables |
219−| [skills/material-ui-nextjs](./skills/material-ui-nextjs/AGENTS.md) | App/Pages Router, Emotion cache, `next/font`, `Link`, SSR |
220−| [skills/material-ui-tailwind](./skills/material-ui-tailwind/AGENTS.md) | Tailwind v4 `@layer`, `enableCssLayer`, v3 interop |
221− 
222−Read the relevant `AGENTS.md` when helping users with those topics.
223− 
224−## Pre-PR Checklist
225− 
226−1. `pnpm prettier` - Format code
227−2. `pnpm eslint` - Pass linting
228−3. `pnpm typescript` - Pass type checking
229−4. `pnpm test:unit` - Pass unit tests
230−5. If API changed: `pnpm proptypes && pnpm docs:api`
231−6. If demos changed: `pnpm docs:typescript:formatted`
232−7. If `.md` files changed: `pnpm vale <file1> <file2> ...` - Check prose style and grammar
233− 
234−## PR Title Format
235− 
236−`[component] Imperative description`
237− 
238−Examples:
239− 
240−- `[button] Add loading state`
241−- `[docs] Fix typo in Grid documentation`
146+Import path cheat sheet: [reference.md](reference.md).
242147  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack