How to config webpack or nextjs to create css file from material custom styles and then inject it into header

Viewed 212

I defined some material custom styles, e.g. as you can see below:

import {createStyles, makeStyles, Theme} from '@material-ui/core/styles';

export const useStyles = makeStyles((theme: Theme) =>
    createStyles({

        fab: {
            zIndex:101,
            position: 'fixed',
            bottom: theme.spacing(2),
            right: theme.spacing(2),
        },

    }),
);

and this _document.tsx:

import React from 'react';
import { ServerStyleSheets } from '@material-ui/core/styles';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import IndexFab from '../src/components/common/fab';
import Loader from "../src/components/loader";

export default class MyDocument extends Document {
    render() {
        return (
            <Html lang="fa" dir={"rtl"}>
                <Head><title>a</title></Head>
                <body>
                <Main/>
                <NextScript />
                </body>
            </Html>
        );
    }
}


MyDocument.getInitialProps = async (ctx) => {

    const sheets = new ServerStyleSheets();
    const originalRenderPage = ctx.renderPage;

    ctx.renderPage = () =>
        originalRenderPage({
            enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
        });

    const initialProps = await Document.getInitialProps(ctx);

    console.log( sheets.toString());
    return {
        ...initialProps,
        styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
    };
};

Now, when i run yarn build command (that run next build inside it), the css rendered as styles text in the head, e.g.:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .fab {
            z-index: 101;
            position: 'fixed';
            bottom: 16px;
            right: 16px;
        }
    </style>
</head>
<body>
</body>
</html>

Now, how can i config webpack or nextjs to make styles into css files and then add appropriate link tag into head.

I'm new to webpack and nextjs ;).

1 Answers

What we're doing and have had some success with is writing the CSS into a file that is referenced by the head:

const initialProps = await Document.getInitialProps(ctx)

// Creates and adds stylesheet to public folder
const css = sheets.toString()
const cssPath = path.join(process.cwd(), 'public/styles')
fs.mkdirSync(cssPath, { recursive: true })
fs.writeFileSync(path.join(cssPath, 'muistyles.css'), css)

return {
  ...initialProps,
  styles: [...Children.toArray(initialProps.styles)]
}

Then we added a link to this stylesheet in the <Head> of the _document. This works locally, but once I try to build remotely in a Linux environment, the CSS file that is written is completely empty. Will report back if a solution is found.

Related