I'm trying to use some variables exported from global .scss
file to create Material-UI theme. Problems occurs because those variables are undefined
on server (I'm using next.js
so pages are pre-rendered). How to make this work?
Error that I get (beacuse all colors are undefined
):
Error: Material-UI: The color provided to augmentColor(color) is invalid.
The color object needs to have a `main` property or a `500` property.
Here are the important parts of my application.
_app.jsx
// General imports
import React from 'react';
// Components import
import App from 'next/app';
import { createMuiTheme, ThemeProvider, CssBaseline, StylesProvider, jssPreset } from '@material-ui/core';
import { create } from 'jss';
// Global styles and colors import
import '../styles/global.scss';
import colors from '../styles/colors.scss';
if (typeof document !== 'undefined') {
const styleNode = document.createComment('jss-insertion-point');
document.head.insertBefore(styleNode, document.head.firstChild);
}
/**
* Material-UI theme.
*
* @type {Object}
*/
const theme = createMuiTheme({
palette: {
primary: {
main: colors.primary,
contrastText: colors.primaryText
},
secondary: {
main: colors.secondary,
contrastText: colors.secondaryText
}
}
});
class CustomApp extends App {
/**
* Handles the componentDidMount lifecycle event.
*
* @memberof MyApp
*/
componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}
/**
* Renders the component.
*
* @returns component's elements
* @memberof CustomApp
*/
render() {
const {
Component,
pageProps
} = this.props;
return (
<>
<StylesProvider
jss={
create({
...jssPreset(),
// Define a custom insertion point that JSS will look for when injecting the styles into the DOM.
insertionPoint: 'jss-insertion-point'
})
}
>
<ThemeProvider theme={theme}>
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
</StylesProvider>
</>
);
}
}
export default CustomApp;
_document.jsx
// General imports
import React from 'react';
// Components import
import Document, { Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core';
/**
*
*
* @class CustomDocument
* @extends {Document}
*/
class CustomDocument extends Document {
render() {
return (
<html lang="en">
<Head>
<meta charSet="utf-8" />
<link rel="icon" href="/favicon.ico" />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
);
}
}
CustomDocument.getInitialProps = async (ctx) => {
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () => originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App isServer {...props} />)
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
isServer: false
};
};
export default CustomDocument;
colors.scss
$color-primary: #2aa876;
$color-primary-text: #ffffff;
$color-secondary: #ffd265;
$color-secondary-text: #7e621d;
:export {
primary: $color-primary;
primaryText: $color-primary-text;
secondary: $color-secondary;
secondaryText: $color-secondary-text;
}
Material UI uses a javascript based style solution (JSS) instead of a CSS pre-processor like SCSS ( see style solution ).
This means it's not possible to customize the Material UI theme via SCSS variables. Nor is it possible to access the theme in your CSS/SCSS styles.
If you want to use SCSS for styling/theming, you might consider Material Web Components instead .
In colors.scss modify as below:
$theme-colors: (
'primary': #2aa876,
'primaryText': #ffffff,
'secondary': #ffd265,
'secondaryText': #7e621d,
);
@each $color, $value in $theme-colors {
:export{
$color: $value;
}
}
import it as you're doing.
import colors from '../styles/colors.scss';
# colors.primary and other variable should work now.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.