Next.js App Router
了解如何在 Next.js App Router 中使用 Joy UI。
範例
從新的基於 App Router 的專案開始?
透過這個範例:Joy UI - Next.js App Router with TypeScript,直接跳入程式碼。
Next.js 和 React Server Components
Next.js App Router 實作了 React Server Components,這是 React 即將推出的功能。
為了支援 App Router,Joy UI 中需要存取瀏覽器 API 的元件和 Hook 都使用 "use client"
指令匯出。
在 App Router 中使用 Joy UI
若要設定 Joy UI,請建立一個自訂的 ThemeRegistry
元件,將 Emotion 的 CacheProvider
、Joy UI 的 CssVarsProvider
和 next/navigation
中的 useServerInsertedHTML
Hook 結合起來,如下所示
// app/ThemeRegistry.tsx
'use client';
import createCache from '@emotion/cache';
import { useServerInsertedHTML } from 'next/navigation';
import { CacheProvider } from '@emotion/react';
import { CssVarsProvider } from '@mui/joy/styles';
import CssBaseline from '@mui/joy/CssBaseline';
import theme from '/path/to/custom/theme'; // OPTIONAL
// This implementation is from emotion-js
// https://github.com/emotion-js/emotion/issues/2928#issuecomment-1319747902
export default function ThemeRegistry(props) {
const { options, children } = props;
const [{ cache, flush }] = React.useState(() => {
const cache = createCache(options);
cache.compat = true;
const prevInsert = cache.insert;
let inserted: string[] = [];
cache.insert = (...args) => {
const serialized = args[1];
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name);
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const names = flush();
if (names.length === 0) {
return null;
}
let styles = '';
for (const name of names) {
styles += cache.inserted[name];
}
return (
<style
key={cache.key}
data-emotion={`${cache.key} ${names.join(' ')}`}
dangerouslySetInnerHTML={{
__html: styles,
}}
/>
);
});
return (
<CacheProvider value={cache}>
<CssVarsProvider theme={theme}>
{/* the custom theme is optional */}
<CssBaseline />
{children}
</CssVarsProvider>
</CacheProvider>
);
}
// app/layout.tsx
export default function RootLayout(props) {
return (
<html lang="en">
<body>
<ThemeRegistry options={{ key: 'joy' }}>{props.children}</ThemeRegistry>
</body>
</html>
);
}
Props 序列化
從伺服器元件傳遞的 Props,例如 page.js
或其他路由檔案,必須是可序列化的。