-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Theme Mode] CssBaseline not working with Next.js App Router (with ThemeRegistry) #37935
Closed
2 tasks done
Labels
bug 🐛
Something doesn't work
component: CssBaseline
The React component
examples
Relating to /examples
package: system
Specific to @mui/system
Comments
mtr1990
added
the
status: waiting for maintainer
These issues haven't been looked at yet by a maintainer
label
Jul 12, 2023
zannager
added
package: system
Specific to @mui/system
component: CssBaseline
The React component
labels
Jul 12, 2023
I can make it work but without // ThemeRegistry.js
"use client";
import { CacheProvider } from "@emotion/react";
import createCache from "@emotion/cache";
import { useServerInsertedHTML } from "next/navigation";
import { useState } from "react";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import { useModeContext } from "@/app/context";
export default function RootStyleRegistry({ children }) {
const [{ cache, flush }] = useState(() => {
const cache = createCache({ key: "css" });
cache.compat = true;
const prevInsert = cache.insert;
let inserted = [];
cache.insert = (...args) => {
const serialized = args[1];
if (cache.inserted[serialized.name] === undefined) {
inserted.push({ name: serialized.name, global: !args[0] });
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const names = flush();
if (names.length === 0) return null;
const nonGlobalNames = [];
const globalStyles = [];
let styles = "";
for (const { name, global } of names) {
if (global) {
globalStyles.push({ name, css: cache.inserted[name] });
} else {
nonGlobalNames.push(name);
styles += cache.inserted[name];
}
}
return [
...globalStyles.map((style, i) => (
<style
key={style.name}
data-emotion={`${cache.key}-global`}
dangerouslySetInnerHTML={{
__html: style.css,
}}
/>
)),
<style
key="css"
data-emotion={`${cache.key} ${nonGlobalNames.join(" ")}`}
dangerouslySetInnerHTML={{
__html: styles,
}}
/>,
];
});
const { mode } = useModeContext();
const theme = createTheme({
palette: {
mode: mode,
},
});
return (
<CacheProvider value={cache}>
<ThemeProvider theme={theme}>
<CssBaseline />
{children}
</ThemeProvider>
</CacheProvider>
);
} |
1 task
mj12albert
removed
the
status: waiting for maintainer
These issues haven't been looked at yet by a maintainer
label
Jul 15, 2023
@mtr1990 This will be fixed by #37962. In the meanwhile, you can copy and paste this to 'use client';
import * as React from 'react';
import createCache from '@emotion/cache';
import { useServerInsertedHTML } from 'next/navigation';
import { CacheProvider as DefaultCacheProvider } from '@emotion/react';
import type { EmotionCache, Options as OptionsOfCreateCache } from '@emotion/cache';
export type NextAppDirEmotionCacheProviderProps = {
/** This is the options passed to createCache() from 'import createCache from "@emotion/cache"' */
options: Omit<OptionsOfCreateCache, 'insertionPoint'>;
/** By default <CacheProvider /> from 'import { CacheProvider } from "@emotion/react"' */
CacheProvider?: (props: {
value: EmotionCache;
children: React.ReactNode;
}) => React.JSX.Element | null;
children: React.ReactNode;
};
// Adatped from https://github.com/garronej/tss-react/blob/main/src/next/appDir.tsx
export default function NextAppDirEmotionCacheProvider(props: NextAppDirEmotionCacheProviderProps) {
const { options, CacheProvider = DefaultCacheProvider, children } = props;
const [registry] = React.useState(() => {
const cache = createCache(options);
cache.compat = true;
const prevInsert = cache.insert;
let inserted: { name: string; isGlobal: boolean }[] = [];
cache.insert = (...args) => {
const [selector, serialized] = args;
if (cache.inserted[serialized.name] === undefined) {
inserted.push({
name: serialized.name,
isGlobal: selector === '',
});
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const inserted = registry.flush();
if (inserted.length === 0) {
return null;
}
let styles = '';
let dataEmotionAttribute = registry.cache.key;
const globals: {
name: string;
style: string;
}[] = [];
inserted.forEach(({ name, isGlobal }) => {
const style = registry.cache.inserted[name];
if (typeof style !== 'boolean') {
if (isGlobal) {
globals.push({ name, style });
} else {
styles += style;
dataEmotionAttribute += ` ${name}`;
}
}
});
return (
<React.Fragment>
{globals.map(({ name, style }) => (
<style
key={name}
data-emotion={`${registry.cache.key}-global ${name}`}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style }}
/>
))}
{styles !== '' && (
<style
data-emotion={dataEmotionAttribute}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: styles }}
/>
)}
</React.Fragment>
);
});
return <CacheProvider value={registry.cache}>{children}</CacheProvider>;
} |
Thank you so much! It's worked |
oliviertassinari
added
bug 🐛
Something doesn't work
examples
Relating to /examples
labels
Jul 22, 2023
oliviertassinari
changed the title
[Theme Mode] CssBaseline not working with next-app-dir (with ThemeRegistry)
[Theme Mode] CssBaseline not working with Next.js App Router (with ThemeRegistry)
Jul 24, 2023
@siriwatknp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
bug 🐛
Something doesn't work
component: CssBaseline
The React component
examples
Relating to /examples
package: system
Specific to @mui/system
Duplicates
Latest version
Steps to reproduce 🕹
Referenced from the example
https://mui.com/material-ui/guides/next-js-app-router/
Link to live example: https://codesandbox.io/p/sandbox/inspiring-bush-l4jqyv?file=%2Fapp%2FThemeRegistry.tsx%3A21%2C25-21%2C38
Steps:
Current behavior 😯
body
tag not apply changecolor
andbackground-color
Expected behavior 🤔
body
tag apply changecolor
andbackground-color
Here is an example without
ThemeRegistry
https://codesandbox.io/p/sandbox/beautiful-carlos-6pn3k4?file=%2Fapp%2FThemeRegistry.tsx%3A76%2C17.And it works.
expect
CssBaseLine
to work when used withThemeRegistry
Context 🔦
No response
Your environment 🌎
No response
The text was updated successfully, but these errors were encountered: