概要
Next.js で Material-UI を利用しつつ、 styled-components でカスタマイズできる環境を構築した記録。
Next.js でプロジェクトを作る
$ npx create-next-app
Material-UI を install する
$ npm install @material-ui/core
styled-components を install する
$ npm install styled-components
babel-plugin-styled-components を install する
これを入れないと Warning: Prop className did not match.
とか言われる。
$ npm install --save-dev babel-plugin-styled-components
.babelrc
を(なければ)作成して、設定する。
{ "presets": ["next/babel"], "plugins": [["styled-components", { "ssr": true }]] }
_app.js で優先順位を調整する
styled-components が最後に当たるようにするには、CSS injection order を設定しておくらしい。
Style Library Interoperability - Material-UI
<StylesProvider injectFirst>
で Component ツリーを囲んでおく。
CssBaseline は reset.css 的なやつらしい。
import '../styles/globals.css' import {StylesProvider} from "@material-ui/core"; function MyApp({Component, pageProps}) { return ( <StylesProvider injectFirst> <CssBaseline/> <Component {...pageProps} /> </StylesProvider> ) } export default MyApp
_document.js を作成して修正する
material-ui や styled-components を Next.js で使うには、 pages/_document.js
をカスタマイズする必要がある。
(なければ)ファイルを新規に作成し、どちらも公式の example があるので、参考にしながらいい感じにマージする。
material-ui/_document.js at master · mui-org/material-ui · GitHub
next.js/_document.js at master · vercel/next.js · GitHub
import React from 'react'; import Document, {Html, Head, Main, NextScript} from 'next/document'; import {ServerStyleSheets as MaterialUIStyleSheets} from '@material-ui/core/styles'; import {ServerStyleSheet as StyledComponentsStyleSheets} from "styled-components"; export default class MyDocument extends Document { render() { return ( <Html lang="ja"> <Head/> <body> <Main/> <NextScript/> </body> </Html> ); } } MyDocument.getInitialProps = async (ctx) => { const materialUISheets = new MaterialUIStyleSheets() const styledComponentsSheets = new StyledComponentsStyleSheets() const originalRenderPage = ctx.renderPage try { ctx.renderPage = () => originalRenderPage({ enhanceApp: (App) => (props) => styledComponentsSheets.collectStyles( materialUISheets.collect(<App {...props} />) ), }) const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> {initialProps.styles} {styledComponentsSheets.getStyleElement()} </> ), } } finally { styledComponentsSheets.seal() } };
material-ui の Button を styled-component でカスタマイズしてみる
pages/sample.js
みたいなのを作って、カスタマイズしてみる。
styled()
に material-ui の Component を渡してあげれば style を上書きできる。
import React from 'react'; import styled from 'styled-components'; import Button from '@material-ui/core/Button'; const StyledButton = styled(Button)` background-color: red; `; const Sample = () => { return ( <div> <StyledButton>Customized</StyledButton> </div> ) } export default Sample