Closed ankitpatelinitio closed 5 years ago
Please take a look at https://github.com/mui-org/material-ui/tree/HEAD/examples/nextjs and follow this example to make styles work.
Yes, for v4, or https://github.com/mui-org/material-ui/tree/v3.x/examples/nextjs for v3.
We are well aware of the problem. We have recently introduced a SSR API, it creates more constraints, it's easier to use, it should reduce the probability of such issues. While you have to configure _document.js and _app.js in v3, configuring _document.js is enough with v4.
The examples were removed?
The examples were removed?
Nothing was removed. It's in the git repository.
Nothing was removed. It's in the git repository.
it may be a typo, try https://github.com/mui-org/material-ui/tree/master/examples/nextjs
For anyone still facing this issue use NoSsr API for your components after the page has rendered.
Using this example: https://github.com/mui-org/material-ui/tree/master/examples/nextjs
in v4 breaks my entire layout. Its also not clear how to do it without emotion cache as theres a note that emotion could cause issues.
@gregg-cbs I have the same thing happening. Initially my app renders ok, but as soon as I refresh or browse to another page it breaks. I used this implementation: https://github.com/mui-org/material-ui/tree/v4.x/examples/nextjs-with-typescript
For me this started after upgrading to Next 11. It seems to be a known issue, but looks like most are focussing on MUI 5, but I can confirm this is also an issue with MUI 4. Maybe this will be fixed in one of these:
Yeah thats what i noticed, navigating breaks it.
I went back to my old implementation which was working until something happened. I realised it was an issue with nested html causing an inconsistent closing tag which caused this error.
For using Material UI with Next.js. The issue is deeper and related to server-side VS client-side rendering. It is explained well here: Rehydration
This helped resolve my issue: vercel/next.js#7322 (comment)
Basically, I wrapped components that need to be rendering on the client side, but creating this file ClientOnly.js:
import React from "react";
const ClientOnly = ({ children, ...delegated }) => {
const [hasMounted, setHasMounted] = React.useState(false);
React.useEffect(() => {
setHasMounted(true);
}, []);
if (!hasMounted) return null
return (
<React.Fragment {...delegated}>
{children}
</React.Fragment>
);
}
export default ClientOnly
I wrapped my _app.js file like this:
import UserProvider from "../context/user";
import Layout from "../components/Layout";
import ClientOnly from "./ClientOnly";
function MyApp({ Component, pageProps }) {
return (
<UserProvider>
<ClientOnly>
<Layout />
<Component {...pageProps} />
</ClientOnly>
</UserProvider>
);
}
export default MyApp;
@hdoshi2
can't tell what I faced, and how many combinations I've used to fix this issue....even I downgraded my MUI v5 to material-ui v4, but still no luck....but yes this ClientOnly hasMounted strategy fixed my issue, thanks.
@hdoshi2
After trying a dozen of solutions, this finally helped me. Thanks a lot.
Are there any side effects of using this?
For using Material UI with Next.js. The issue is deeper and related to server-side VS client-side rendering. It is explained well here: Rehydration
This helped resolve my issue: vercel/next.js#7322 (comment)
Basically, I wrapped components that need to be rendering on the client side, but creating this file ClientOnly.js:
import React from "react"; const ClientOnly = ({ children, ...delegated }) => { const [hasMounted, setHasMounted] = React.useState(false); React.useEffect(() => { setHasMounted(true); }, []); if (!hasMounted) return null return ( <React.Fragment {...delegated}> {children} </React.Fragment> ); } export default ClientOnly
I wrapped my _app.js file like this:
import UserProvider from "../context/user"; import Layout from "../components/Layout"; import ClientOnly from "./ClientOnly"; function MyApp({ Component, pageProps }) { return ( <UserProvider> <ClientOnly> <Layout /> <Component {...pageProps} /> </ClientOnly> </UserProvider> ); } export default MyApp;
Wouldn't this prevent search engines to see the HTML?
One point the link mentions (https://www.joshwcomeau.com/react/the-perils-of-rehydration/) is that you don't need to wrap that <ClientOnly>
around your whole App like that.
In our case, it was only a single (though often used) component that used styled-components which was causing the warning. Tracking that down and wrapping just that in <ClientOnly>
helped silence the warning, while leaving the rest of the app's server side rendering (presumably) intact.
But great solution, and the explanatory link was super insightful.
I have spent nearly 5-6 hours on it and now you saved me. Thanks a lot.
I spend close to 4 hours on this issue and to find your hint for NextJS13. Thank you so much!
I used the below code to use AppBar, Toolbar, IconButton, Typography and some other elements of material UI and I applied classes to that element from props but classes not applied. e.g. root, menuButton, grow classes not applied. Also, I get some error in console.
Warning: Prop className did not match. Server: "MuiButtonBase-root-51 MuiIconButton-root-45 MuiIconButton-colorInherit-46 ButtonAppBar-menuButton-127" Client: "MuiButtonBase-root-51 MuiIconButton-root-45 MuiIconButton-colorInherit-46 ButtonAppBar-menuButton-3".
import React from "react"; import PropTypes from "prop-types"; import { withStyles } from "@material-ui/core/styles"; import AppBar from "@material-ui/core/AppBar"; import Toolbar from "@material-ui/core/Toolbar"; import Typography from "@material-ui/core/Typography"; import Button from "@material-ui/core/Button"; import IconButton from "@material-ui/core/IconButton"; import MenuIcon from "@material-ui/icons/Menu";