Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5f7d573
styling
mapache-salvaje Mar 26, 2026
75ccab9
theming and design tokens
mapache-salvaje Mar 26, 2026
63ab9a6
restructure
mapache-salvaje Mar 26, 2026
4d613e2
cleanup
mapache-salvaje Mar 26, 2026
ad892a5
reduce noise'
mapache-salvaje Mar 30, 2026
17a758b
nextjs
mapache-salvaje Mar 31, 2026
7a797db
tailwind
mapache-salvaje Mar 31, 2026
28a4f1b
refine skills, refine nextjs docs
mapache-salvaje Apr 2, 2026
fa0131f
copyediting
mapache-salvaje Apr 2, 2026
9a1e703
more clear
mapache-salvaje Apr 2, 2026
38a4200
prettier
mapache-salvaje Apr 2, 2026
fbfd3cf
dimension-stable suspense fallback
mapache-salvaje Apr 6, 2026
8f992ac
consistent styling
mapache-salvaje Apr 6, 2026
8875899
one sentence per line
mapache-salvaje Apr 6, 2026
5728cc2
Make agent skills discoverable by all tools, not just Cursor
mapache-salvaje Apr 8, 2026
8a70325
prettier
mapache-salvaje Apr 8, 2026
932c032
Merge branch 'master' into agent-skills
mapache-salvaje Apr 8, 2026
e7420c3
fix markdownlint: table alignment and curly quotes
mapache-salvaje Apr 8, 2026
83b98bf
fix lint: brand name spacing, e.g usage, abbreviations
mapache-salvaje Apr 13, 2026
d05e004
fix YAML frontmatter: remove non-breaking spaces
mapache-salvaje Apr 13, 2026
ebff967
fix non-breaking spaces in SKILL.md frontmatter
mapache-salvaje Apr 13, 2026
52fba37
remove sed temp files
mapache-salvaje Apr 13, 2026
ea8262f
Merge branch 'master' into agent-skills
mapache-salvaje Apr 13, 2026
f769532
move skills out of .cursor, make tool-agnostic
mapache-salvaje Apr 13, 2026
4acd739
fix lint after Cursor cleanup
mapache-salvaje Apr 13, 2026
0dd1839
fix table alignment
mapache-salvaje Apr 13, 2026
78bee68
fix brand name spacing
mapache-salvaje Apr 13, 2026
634f180
prettier
mapache-salvaje Apr 14, 2026
da5bc14
convert links to md
Apr 21, 2026
1c1fad8
nbsps
Apr 21, 2026
930329f
table alignment
Apr 21, 2026
4882f2d
Merge branch 'master' into agent-skills
mapache-salvaje Apr 21, 2026
bce777c
fix all remaining links
Apr 22, 2026
c871483
more links
Apr 22, 2026
3fabb50
more links, nbsps
Apr 22, 2026
691fe62
table alignment
Apr 22, 2026
a6319cf
table, prettier
Apr 22, 2026
e3f0c07
claude evals
Apr 22, 2026
df5d313
nbsps'
Apr 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@ import Button from '@mui/material/Button'; // Good
import { Button } from '@mui/material'; // Avoid in packages
```

## Agent Skills

Packaged guidance for common integration topics lives under `skills/`. Each skill is a self-contained directory:

| Skill | Focus |
| :--------------------------------------------------------------------- | :---------------------------------------------------------- |
| [skills/material-ui-styling](./skills/material-ui-styling/AGENTS.md) | `sx`, `styled()`, theme overrides, slots, global CSS |
| [skills/material-ui-theming](./skills/material-ui-theming/AGENTS.md) | `createTheme`, design tokens, `colorSchemes`, CSS variables |
| [skills/material-ui-nextjs](./skills/material-ui-nextjs/AGENTS.md) | App/Pages Router, Emotion cache, `next/font`, `Link`, SSR |
| [skills/material-ui-tailwind](./skills/material-ui-tailwind/AGENTS.md) | Tailwind v4 `@layer`, `enableCssLayer`, v3 interop |

Read the relevant `AGENTS.md` when helping users with those topics.

## Pre-PR Checklist

1. `pnpm prettier` - Format code
Expand Down
54 changes: 54 additions & 0 deletions docs/data/material/integrations/nextjs/nextjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,60 @@ Then, replace the Next.js Link with the wrapper component:
</Button>
```

### URL-driven UI and the Suspense boundary

When client components use Next.js App Router hooks that read the URL—for example `useSearchParams()` from `next/navigation` for filters, tabs, or pagination—Next.js expects a `<Suspense>` boundary around that part of the React tree.
Without it, you may see build failures or runtime messages about a missing Suspense boundary (behavior depends on your Next.js version and static vs dynamic rendering).

This pattern is common with Material UI: `Table`, `Tabs`, `TextField`, and other controls are often implemented as client components that sync to the query string.

Recommended structure: keep `page.tsx` as a server component when possible, and wrap only the client subtree that calls `useSearchParams` in `<Suspense>`.

Avoid `fallback={null}` (or an empty fallback) for UI that reserves space in the layout (toolbars, filters, tab bars, and similar).
The server and the initial streamed HTML then omit that subtree, and the real content appears only after the client hydrates, which often causes layout shift and hurts CLS.
Prefer a fallback whose size and structure approximate the final UI, for example Material UI `Skeleton` inside `Stack` or `Box` with the same `minHeight`, flex direction, and breakpoints as the loaded component.

```tsx title="app/orders/page.tsx"
import { Suspense } from 'react';
import Box from '@mui/material/Box';
import Skeleton from '@mui/material/Skeleton';
import Stack from '@mui/material/Stack';
import OrdersToolbar from './OrdersToolbar';

function OrdersToolbarFallback() {
return (
<Stack
direction="row"
spacing={2}
useFlexGap
sx={{ flexWrap: 'wrap', alignItems: 'center', minHeight: 56 }}
>
<Skeleton
variant="rounded"
height={40}
sx={{ minWidth: 200, flexGrow: { xs: 1, sm: 0 } }}
/>
<Skeleton variant="rounded" width={120} height={40} />
<Box sx={{ flexGrow: 1 }} />
<Skeleton variant="rounded" width={100} height={40} />
</Stack>
);
}

export default function Page() {
return (
<Suspense fallback={<OrdersToolbarFallback />}>
<OrdersToolbar />
</Suspense>
);
}
```

`OrdersToolbar` would be a file marked with `'use client'` that calls `useSearchParams()` and renders Material UI components.
Adjust the fallback's layout and Skeleton sizes so they match your real toolbar (or filter row) as closely as possible.

For details and version-specific notes, see the Next.js documentation for [`useSearchParams`](https://nextjs.org/docs/app/api-reference/functions/use-search-params).

## Pages Router

This section walks through the Material UI integration with the Next.js [Pages Router](https://nextjs.org/docs/pages/building-your-application), for both [Server-side Rendering](https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering) (SSR) and [Static Site Generation](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) (SSG).
Expand Down
61 changes: 61 additions & 0 deletions skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Material UI agent skills

Packaged guidance for AI agents and humans. Each skill is a directory under `skills/` with this layout:

```text
skills/
├── README.md # this file
├── material-ui-styling/ # sx vs styled vs theme vs global CSS
│ ├── AGENTS.md # full guide (read for complete detail)
│ ├── SKILL.md # entry point + index
│ ├── README.md
│ ├── metadata.json
│ └── reference.md
├── material-ui-theming/ # createTheme, tokens, dark mode, CSS variables
│ ├── AGENTS.md
│ ├── SKILL.md
│ ├── README.md
│ ├── metadata.json
│ └── reference.md
├── material-ui-nextjs/ # Next.js App/Pages Router, cache, fonts, Link
│ ├── AGENTS.md
│ ├── SKILL.md
│ ├── README.md
│ ├── metadata.json
│ └── reference.md
└── material-ui-tailwind/ # Tailwind v4 layers + v3 interoperability
├── AGENTS.md
├── SKILL.md
├── README.md
├── metadata.json
└── reference.md
```

## Files in each skill

| File | Purpose |
| :-------------- | :------------------------------------------------------------------ |
| `AGENTS.md` | Full guide — the canonical source of truth for all agents and tools |
| `SKILL.md` | Entry point and index (frontmatter + section summary) |
| `README.md` | Human-readable overview |
| `metadata.json` | Machine-readable metadata (version, references) |
| `reference.md` | Quick-reference cheat sheet (imports, API shapes) |

## Discovery

The root `AGENTS.md` lists each skill and links directly to `skills/<name>/AGENTS.md`. Any agent that reads `AGENTS.md` files will find the skills from there.

## Adding a skill

1. Create `skills/<kebab-case-name>/` with `AGENTS.md`, `SKILL.md`, `README.md`, `metadata.json` (optional: `reference.md`).
2. Add an entry to the table in the root `AGENTS.md` linking to the new `AGENTS.md`.
3. List the new skill in the catalog below.

## Catalog

| Folder | Focus |
| :---------------------------------------------- | :------------------------------------------------------------------------------------------------------------- |
| [material-ui-styling](./material-ui-styling/) | Choosing styling scope: `sx`, `styled()`, theme overrides, global CSS; slots and state |
| [material-ui-theming](./material-ui-theming/) | Theme object, design tokens, `colorSchemes`, `cssVariables` / `theme.vars`, TypeScript augmentation |
| [material-ui-nextjs](./material-ui-nextjs/) | `@mui/material-nextjs`, App/Pages Router, Emotion cache, `next/font`, CSS layers, Next `Link` + MUI |
| [material-ui-tailwind](./material-ui-tailwind/) | Tailwind v4 `@layer` + `enableCssLayer`; `className` / `slotProps`; v3 preflight / `important` / `injectFirst` |
144 changes: 144 additions & 0 deletions skills/material-ui-nextjs/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Material UI and Next.js

Version 1.0.0

> 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.

---

## Abstract

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.

---

## Table of contents

1. [App Router (recommended)](#app-router-recommended)
2. [Pages Router](#pages-router)
3. [Fonts (`next/font`)](#fonts-nextfont)
4. [CSS theme variables and SSR](#css-theme-variables-and-ssr)
5. [Other styling stacks (CSS layers)](#other-styling-stacks-css-layers)
6. [Next.js Link and `component` prop](#nextjs-link-and-component-prop)
7. [Further reading](#further-reading)

---

## App Router (recommended)

### Dependencies

Have `@mui/material` and `next` installed, then add:

- `@mui/material-nextjs`
- `@emotion/cache`

Example: `pnpm add @mui/material-nextjs @emotion/cache`

### Root layout

In `app/layout.tsx`, wrap everything under `<body>` with `AppRouterCacheProvider` from the entry that matches your Next major, for example:

`import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';`

(Use the `v1X-appRouter` path that matches your Next.js version if not on v15.)

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).

### Optional cache `options`

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).

### URL hooks and Suspense

Dashboards and internal tools often combine MUI client components with URL-driven UI (filters, tabs, pagination) using `useSearchParams()` from `next/navigation`.

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.

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).

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).

---

## Pages Router

### Dependencies

Add `@mui/material-nextjs`, `@emotion/cache`, and `@emotion/server`.

Example: `pnpm add @mui/material-nextjs @emotion/cache @emotion/server`

### `_document.tsx`

- Import `DocumentHeadTags` and `documentGetInitialProps` from the `v15-pagesRouter` (or matching `v1X-pagesRouter`) entry.
- Render `<DocumentHeadTags {...props} />` inside `<Head>`.
- Assign `getInitialProps` to call `documentGetInitialProps`.

### `_app.tsx`

Wrap the app with `AppCacheProvider` from the same major entry (for example `v15-pagesRouter`).

### Optional: custom cache and cascade layers

- Pass a custom `emotionCache` into `documentGetInitialProps` options when needed.
- 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).

### TypeScript

Extend `Document` props with `DocumentHeadTagsProps` from the same import path. See [Next.js integration—TypeScript](https://mui.com/material-ui/integrations/nextjs.md#typescript).

---

## Fonts (`next/font`)

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.

Pages Router: similar pattern in `pages/_app.tsx` with `AppCacheProvider` and `ThemeProvider`.

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).

---

## CSS theme variables and SSR

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.

---

## Other styling stacks (CSS layers)

If you combine MUI with Tailwind CSS, CSS Modules, or other global CSS, set `enableCssLayer: true` on `AppRouterCacheProvider`:

`<AppRouterCacheProvider options={{ enableCssLayer: true }}>`

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).

---

## Next.js Link and `component` prop

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:

```tsx
'use client';
import Link, { LinkProps } from 'next/link';
export default Link;
```

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).

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).

---

## Further reading

| Topic | Link |
| :------------------------------- | :----------------------------------------------------------------------------------------------------- |
| Full integration guide | [Next.js integration](https://mui.com/material-ui/integrations/nextjs.md) |
| Example (App Router, TypeScript) | [material-ui-nextjs-ts](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts) |
| Routing + Link adapters | [Routing libraries](https://mui.com/material-ui/integrations/routing.md) |
| RSC vs SSR (terminology) | [React WG discussion](https://github.com/reactwg/server-components/discussions/4) |

Import path cheat sheet: [reference.md](reference.md).
12 changes: 12 additions & 0 deletions skills/material-ui-nextjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Material UI + Next.js (agent skill)

Integration guide for Material UI with the Next.js App Router and Pages Router: Emotion cache via `@mui/material-nextjs`, `ThemeProvider`, `next/font`, CSS layers with other tools, and `Link` usage.

## Files in this folder

| File | Purpose |
| :------------ | :----------------------------- |
| AGENTS.md | Full agent/LLM document |
| SKILL.md | Entry point and index |
| metadata.json | Version, abstract, references |
| reference.md | Import paths and layout sketch |
38 changes: 38 additions & 0 deletions skills/material-ui-nextjs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: material-ui-nextjs
description: Integrates Material UI with Next.js App and Pages routers using @mui/material-nextjs, Emotion cache providers, next/font, CSS layers with Tailwind/CSS Modules, Link component prop patterns, CSS theme variables SSR notes, and App Router useSearchParams + Suspense. Use when setting up or debugging MUI in a Next.js app.
license: MIT
metadata:
author: mui
version: '1.0.0'
---

# Material UI and Next.js

Agent skill for Next.js + Material UI wiring (SSR/streaming, cache providers, fonts, layers, Link, App Router URL state). SKILL.md is the entry; AGENTS.md is the full guide.

## When to apply

- New App Router or Pages Router app using `@mui/material`
- Styles missing, wrong order, or in `body` instead of `head`
- `next/font` + `ThemeProvider` / `createTheme`
- Tailwind or CSS Modules + MUI (`enableCssLayer`)
- `Button` + `component={Link}` or Next.js v16 client boundary errors
- `useSearchParams` / URL-driven MUI views and Suspense boundaries

## Sections in AGENTS.md

| Area | Topics |
| :------------ | :-------------------------------------------------------------------------------------- |
| App Router | `AppRouterCacheProvider`, `@emotion/cache`, `options`, `useSearchParams` + `<Suspense>` |
| Pages Router | `_document`, `_app`, `DocumentHeadTags`, `AppCacheProvider` |
| Fonts | `'use client'` theme, `next/font`, CSS variables on `html` |
| CSS variables | `cssVariables`, SSR flicker docs |
| CSS layers | `enableCssLayer`, Tailwind / other CSS |
| Link | Client wrapper, routing guide, examples repo |

## Full guide

Read [AGENTS.md](./AGENTS.md) for complete steps and doc links.

[reference.md](./reference.md) lists import paths and provider shape.
11 changes: 11 additions & 0 deletions skills/material-ui-nextjs/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "1.0.0",
"organization": "Material UI",
"abstract": "Documents Next.js integration for Material UI: AppRouterCacheProvider and Pages Router Document/App cache wiring, Emotion options, next/font with themes, CSS theme variables and SSR flicker pointers, enableCssLayer for Tailwind/CSS Modules, and Next.js Link client-wrapper patterns.",
"references": [
"https://mui.com/material-ui/integrations/nextjs.md",
"https://mui.com/material-ui/integrations/routing.md",
"https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts",
"https://nextjs.org/docs/app"
]
}
Loading
Loading