概要
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