1. To build a next.js app using styled components it's really easy. You just have to use their _document.js
snippet to enable SSR and prevent styles flickering on page load: https://github.com/zeit/next.js/blob/canary/examples/with-styled-components/pages/_document.js
2. To build a next.js app using material-ui is almost as simple. You just have to start with ther project base: https://github.com/mui-org/material-ui/tree/master/examples/nextjs, which has its own implementation on _document.js
: https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_document.js
3. Sadly, I couldn't figure out how to "merge" both implementations and get a next app where both styled-components and material-ui components can coexist, SSR and do not flicker on page load.
Can you help me? Is there someone on the internet with better abilities than mine whom already solved that problem but I do not know about?
Thanks in advance.
Material UI is a great UI library for a frontend developer. with the easy ways to add material UI in nextjs. The material UI is an excellent library for frontend developers. You can add material UI in nextjs with three easy steps.
Material-UI and styled-components perfectly work fine on all of the components. The goal of this article is to share how to use server-side rendering on the Next.js app with styled-components and Material-UI. You can view the final working example at: Nextjs + Styled-component + Material UI + SSR.
If you are using _app.js file already adapt it yours or create new file. The most important part here is the removing the server side injected CSS. // Remove the server-side injected CSS. Your application is ready to go! You can test it and now flickering issues are gone and you can able to use material UI properly on your nextjs applications.
Material UI offers React components for faster and easier web development. You can create your own design system, or start with Material Design. You can find much useful information on their websites and the components you would like to use in your project. You can check their templates and start using one of them as soon as possible.
styled-components support server-side rendering with stylesheet rehydration which allows you to use styled-components with React DOM’s every time you render an app on the server. In order to do that in Next.js, you need to follow some setups in its docs:
Give this a try
_document.js
import React from 'react'; import Document, { Head, Main, NextScript } from 'next/document'; import { ServerStyleSheet } from 'styled-components' import { ServerStyleSheets } from '@material-ui/styles'; import theme from '../src/theme'; class MyDocument extends Document { static async getInitialProps (ctx) { const styledComponentsSheet = new ServerStyleSheet() const materialSheets = new ServerStyleSheets() const originalRenderPage = ctx.renderPage; try { ctx.renderPage = () => originalRenderPage({ enhanceApp: App => props => styledComponentsSheet.collectStyles(materialSheets.collect(<App {...props} />)) }) const initialProps = await Document.getInitialProps(ctx) return { ...initialProps, styles: ( <React.Fragment> {initialProps.styles} {materialSheets.getStyleElement()} {styledComponentsSheet.getStyleElement()} </React.Fragment> ) } } finally { styledComponentsSheet.seal() } } render() { return ( <html lang="en" dir="ltr"> <Head> <meta charSet="utf-8" /> {/* Use minimum-scale=1 to enable GPU rasterization */} <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no" /> {/* PWA primary color */} <meta name="theme-color" content={theme.palette.primary.main} /> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" /> </Head> <body> <Main /> <NextScript /> </body> </html> ); } } export default MyDocument;
.babelrc
{ "presets": ["next/babel"], "plugins": [["styled-components", { "ssr": true }]] }
For update check https://github.com/nblthree/nextjs-with-material-ui-and-styled-components
This solution works fine for server-side, for client side you also need to change the injection order, as documented here: https://material-ui.com/customization/css-in-js/#css-injection-order
To make this work with next.js, you need to change the asignation of the jss constant like this:
const jss = create({ ...jssPreset(), insertionPoint: process.browser ? window.document.getElementById('jss-insertion-point') : null })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With