Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to integrate Nextjs + styled-components with material-ui

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.

like image 472
Amet Alvirde Avatar asked Mar 11 '19 20:03

Amet Alvirde


People also ask

Can we use material UI in next JS?

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.

Can I use styled-components and material-UI with nextjs?

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.

How to fix material UI flickering issues in nextjs?

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.

What is material UI?

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.

How do I use styled-components with react next?

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:


2 Answers

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

like image 191
evgeni fotia Avatar answered Oct 12 '22 00:10

evgeni fotia


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 }) 
like image 41
emik Avatar answered Oct 12 '22 00:10

emik