Material-UI Theme : How to manage order or priority the .MuiXXX classes are applied? - styles

[EDIT April 19th]
I have created a CODESANDBOX to show the problem, of course, that doesn't occur in sandbox.
The only difference between this code and mine is that I have duplicated the code of the Button component in the SANDBOX example, whereas in my App the Button component is imported from a library (that belongs to the same yarn workspace as the app). The library is built with webpack and babel, excluding React and Material-UI
externals: {
react: "react",
"react-dom": "react-dom",
"react-router": "react-router",
"react-router-dom": "react-router-dom",
"#material-ui/core": "#material-ui/core",
"#material-ui/icons": "#material-ui/icons",
"#material-ui/lab": "#material-ui/lab",
"#material-ui/styles": "#material-ui/styles",
formik: "formik",
},
Inspecting the components in the Browser shows the difference when styling, between sandbox and my app :
on both sides, the class are applied to the component the same way:
in sandbox
in my app
but on sandBox, the MuiButtonBase-root background-color is overridden by the MuiButton-root background-color
whereas it is the opposite in my app. The MuiButton-root backGroundColor seems to be overriden bu the MuiButtonBase-root background-color
However, if I create a component RecreatedButton in the App by just importing the Button component of my UI Library, and re-exported it without changing anything (just passing a specific props the component is requested), then the styling is applied correctly, as in the sandbox example.
this is kind of weird to me...
Why such a behavior ?
just importing and rexporting as is the component
import {
Button as LibraryButton,
EButtonTypes,
IButtonProps,
} from "#mylibrairy/reactcomponentscommon"; <---- importing the button
import React from "react";
const RecreatedButton: React.FC<IButtonProps> = (
props: IButtonProps
): JSX.Element => {
return (
<LibraryButton type={EButtonTypes.BUTTON}>
{props.children}
</LibraryButton>
);
};
export { RecreatedButton };
Using both in app.ts. One got the theme, the other not
import { ThemeProvider } from "#material-ui/core/styles";
import {
Button as LibraryButton,
EButtonTypes,
IButtonProps,
} from "#mylibrairy/reactcomponentscommon"
import React from "react";
import AppBar from "../../UIComponents/AppBar";
import { RecreatedButton } from "../../UIComponents/Button";
import { MUITheme } from "./../../Theming/defaultTheme";
export const MainApp: React.FC = (): JSX.Element => {
return (
<ThemeProvider theme={MUITheme}>
<>
<AppBar />
<LibraryButton type={EButtonTypes.BUTTON}> I'm the library component, directly used as is, and background color is NOT CORRECT ></LibraryButton>
<RecreatedButton>
I'm recreated button, just rexporting the library component, and the backgroundcolor is correct !?!?{" "}
</RecreatedButton>
</>
</ThemeProvider>
);
};

finally I found one solution (not sure that it fixes the root cause as I still do not understand where it comes from).
I Guess it may helps some people here that are facing a similar issue with global theming in Material-Ui.
It turned out that I had to change the way to build my react/material-Ui components library #mylibrairy/reactcomponentscommon.
1- Make sure that in the library, all imports where such as import { Button} from "#material-ui/core" and not for example import Button from "#material-ui/core/Button"
2- Remove the usage of file-loader plugin in the .babelrc to make sure it doesn't change the way to import material-ui components
3- Push #material-ui/core and #material-ui/icons as a dev and peer dependencies in the package.json of the library.
4- Rebuilt the library using webpack and babel to compile typescript tsx to js.
All issues of priority seems to disappear (have done a lot of tests and checked in the chrome dev tools). In the example above, the .MuiButton-root class is well applied after the .MuiButtonBase-root one, thus overriding as expected the backgroundColor.
Would admit that I'm a little bit confused why this fixed the issue...
Rgds

For me, i just had to import "makeStyles" and "createStyles" from "#material-ui/core" not from "#material-ui/core/styles". i just did this and it fixed the issue but took me a lot of time to figure this out.
so import them like this:
import { makeStyles, createStyles } from "#material-ui/core";
not like this:
import { makeStyles, createStyles } from "#material-ui/core/styles";

You may try overriding default globals for MuiButtonBase
const theme = createMuiTheme({
props: {
// Name of the component ⚛️
MuiButtonBase: {
// The default props to change
root:{
backgroundColor: 'red'
}
},
},
});
function DefaultProps() {
return (
<ThemeProvider theme={theme}>
<Button>Change default props</Button>
</ThemeProvider>
);
}
Working sandbox here - https://codesandbox.io/s/override-button-base-7qwd5

Related

Line 5: 'React' must be in scope when using JSX react/react-in-jsx-scope [duplicate]

I am an Angular Developer and new to React , This is simple react Component but not working
import react , { Component} from 'react';
import { render } from 'react-dom';
class TechView extends Component {
constructor(props){
super(props);
this.state = {
name:'Gopinath'
}
}
render(){
return(
<span>hello Tech View</span>
);
}
}
export default TechView;
Error :
'React' must be in scope when using JSX react/react-in-jsx-scope
The import line should be:
import React, { Component } from 'react';
Note the uppercase R for React.
Add below setting to .eslintrc.js / .eslintrc.json to ignore these errors:
rules: {
// suppress errors for missing 'import React' in files
"react/react-in-jsx-scope": "off",
// allow jsx syntax in js files (for next.js project)
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], //should add ".ts" if typescript project
}
Why?
If you're using NEXT.js then you do not require to import React at top of files, nextjs does that for you.
Ref: https://gourav.io/blog/nextjs-cheatsheet (Next.js cheatsheet)
If you're using React v17, you can safely disable the rule in your eslint configuration file:
"rules": {
...
"react/react-in-jsx-scope": "off"
...
}
For those who still don't get the accepted solution :
Add
import React from 'react'
import ReactDOM from 'react-dom'
at the top of the file.
If you are running React 17+ (and in 2022, I assume, that you are) - you need to add the following line to your .eslintrc:
{
"extends": ["plugin:react/jsx-runtime"]
}
Then only import React once in your top-level file, like App.jsx - and no need to import it anywhere else, unless you need an api like useEffect etc.
import React, { Component } from 'react';
This is a spelling error, you need to type React instead of react.
add "plugin:react/jsx-runtime" to extends in your eslint config file, refer react-in-jsx-scope
If you'd like to automate the inclusion of import React from 'react' for all files that use jsx syntax, install the react-require babel plugin:
npm install babel-plugin-react-require --save-dev
Add react-require into .babelrc. This plugin should be defined before transform-es2015-modules-commonjs plugin because it's using ES2015 modules syntax to import React into scope.
{
"plugins": [
"react-require"
]
}
Source: https://www.npmjs.com/package/babel-plugin-react-require
I had the similar issue.
Got fixed after i added the code below in the main component: App.js
If you have other components, make sure to import react in those files too.
import React from "react";
The error is very straight forward, you imported react instead of React.
In my case, I had to include this two-line in my index.js file from the src folder.
import React from 'react'
import ReactDOM from 'react-dom'
In your case, this might be different.
You may need to include components if you're using class-based components.
import React, { Component } from 'react';
Alternatively, If you are using eslint you can get some solutions from the above comments.
know more
When using the react framework, you first need to import the react from react and always keep the first letter of react in uppercase after import.
import React, {Component} from 'react'`
import React, { Component} from 'react';
import { render } from 'react-dom';
class TechView extends Component {
constructor(props){
super(props);
this.state = {
name:'Gopinath'
}
}
render(){
return(
<span>hello Tech View</span>
);
}
}
export default TechView;
for me I got this issue once I used npm audit fix --force so it downgrade react-scripts to version 2 and it forces me to install eslint versions 5 and issues started to flood, to fix this I have update it again react-scripts and things worked out.
Also make sure that your eslint contains those rules
module.exports = {
extends: ['react-app', 'react-app/jest', 'airbnb', 'prettier'],
plugins: ['prettier'],
rules: {
...
// React scope no longer necessary with new JSX transform
'react/react-in-jsx-scope': 'off',
// Allow .js files to use JSX syntax
'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],
...
},
}
Whenever we make a custom component in React using JSX, it is transformed into backward-compatible JS code with the help of Babel.
Since the JSX compiles into React.createElement, the React library must also always be in scope.
Example:
This custom component:
<MyButton color="blue" shadowSize={2}> Click Me </MyButton>
is transformed into:
React.createElement(MyButton, {color: 'blue', shadowSize: 2}, 'Click Me')
^^^^^
Since the converted code needs the React library, we need to import it into the scope.
React Docs Reference
Fix: Import React
import React from 'react';
// or
import * as React from 'react';
Pick one, it depends on the user!
NOTE:
As of React 17+, we are free from doing such import, but it's better to add the imports just to be on the safe side because errors can be generated because of ESLint!
One can disable the rule in the ESLint config file (.eslintrc.json) to ignore these errors:
"rules": {
"react/react-in-jsx-scope": "off"
}
This is an error caused by importing the wrong module react from 'react' how about you try this:
1st
import React , { Component} from 'react';
2nd Or you can try this as well:
import React from 'react';
import { render } from 'react-dom';
class TechView extends React.Component {
constructor(props){
super(props);
this.state = {
name:'Gopinath',
}
}
render(){
return(
<span>hello Tech View</span>
);
}
}
export default TechView;
Upgrading the react-scripts version to latest solved my problem.
I was using the react-scripts version 0.9.5 and upgrading it to 5.0.1 did the job.
One thing that I noticed is that import React from "react"; should be there instead of import react , { Component} from 'react';
Other Things I have done is,
(1) added below lines to index.js file.
import React from 'react'
import ReactDOM from 'react-dom'
if not worked add this line for ReactDOM import ReactDOM from "react-dom/client"; instead of import ReactDOM from 'react-dom'
(2) change following properties for eslint configuration file.
rules: {
"react/react-in-jsx-scope": "off",
}
But Starting from React 17,Dont need to add import React from 'react' and next js as well
The line below solved this problem for me.
/** #jsx jsx */
import {css, jsx} from "#emotion/react";
hope this help you.
Follow as in picture for removing that lint error and adding automatic fix by addin g--fix in package.json
in babel, add "runtime": "automatic" option
{
"presets": [
[
"#babel/preset-react",
{
"runtime": "automatic"
}
],
"#babel/preset-env"
],
"plugins": [
]
}

Custom Teams theming with fluentui/-react-northstar

Docs for fluentui-react-northstar theming can be found here.
I am struggling to understand how to make use of a custom theme. It seems I need one provider for the Teams base theme, and then a nested one for my own theme (which may well be wrong)
<Provider theme={teamsTheme}>
<Provider theme={myTheme}>
But I only want to make a few changes to the base theme, for example making the brand colour red. The documentation doesn't really explain how to make use of it.
For example, the docs show this:
const theme = {
siteVariables: {
brand: 'darkred',
...
but this does nothing to change the primary colour in the app...
Any pointers would be greatly appreciated.
NOTE: I originally went to post this question on the github page, but it said questions should be asked here
After a bit of trial and error, I found that this works:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Button, Provider, mergeThemes, teamsTheme } from '#fluentui/react-northstar';
const customTheme = {
siteVariables: {
colorScheme: {
brand: {
'background': 'darkred',
}
}
}
}
ReactDOM.render(
<Provider theme={mergeThemes(teamsTheme, customTheme)}>
<Button primary content="Hello" />
</Provider>
,
document.getElementById('app'),
)
Gives this:

mwc-icon 0.7.1 not rendering (with lit-element/pwa-starter-kit)?

Has any one got mwc-icon (0.7.1) to work with lit-element (pwa-starter-kit)?
mwc-button renders OK but mwc-icon does not render the icon just the icon index text.
import { html } from 'lit-element';
import { PageViewElement } from './page-view-element.js';
import {Icon} from "#material/mwc-icon" //does not work
import {Button} from "#material/mwc-button"
import { SharedStyles } from './shared-styles.js';
class MyView1 extends PageViewElement {
static get styles() {
return [
SharedStyles
];
}
render() {
return html`
<section>
<h2>Example</h2>
<mwc-icon>bookmark</mwc-icon>
<mwc-button outlined label="outlined"></mwc-button>
`;
}
}
window.customElements.define('my-view1', MyView1);
I think you encounter the same problem I did.
It happens because Chrome process the #font-face attribute only once at first page load.
when you import the mwc styles you expect them to enable in the lit-element render - after the first initial load of the page. that will work, you'll see the new styles except for the #font-face attribute.
That's why you don't see the icon.
A quick workaround is to append the link both on the head section in
index.html and in the lit-element as you did.
you can see example that don't work
and example that work
The difference is the added link in index.html head section.
More details here: github thread
Hope I helped you with this.
I was stuck on it myself for quite some time

React + Material-UI - Warning: Prop className did not match

I'm having difficulty with differences between client-side and server-side rendering of styles in Material-UI components due to classNames being assigned differently.
The classNames are assigned correctly on first loading the page, but after refreshing the page, the classNames no longer match so the component loses its styling. This is the error message I am receiving on the Console:
Warning: Prop className did not match.
Server: "MuiFormControl-root-3 MuiFormControl-marginNormal-4
SearchBar-textField-31"
Client: "MuiFormControl-root-3 MuiFormControl-marginNormal-4
SearchBar-textField-2"
I've followed the Material-UI TextField example docs, and their accompanying Code Sandbox example, but I can't seem to figure out what is causing the difference between the server and client classNames.
I experienced a similar issue when adding Material-UI Chips with a delete 'x' icon. The 'x' icon rendered with a monstrous 1024px width after refreshing. The same underlying issue being that icon was not receiving the correct class for styling.
There are a few questions on Stack Overflow addressing why the client and server might render classNames differently (e.g. need to upgrade to #Material-UI/core version ^1.0.0, using a custom server.js, and using Math.random in setState), but none of these apply in my case.
I don't know enough to tell whether this Github discussion might help, but likely not since they were using a beta version of Material-UI.
Minimal steps to reproduce:
Create project folder and start Node server:
mkdir app
cd app
npm init -y
npm install react react-dom next #material-ui/core
npm run dev
edit package.json:
Add to 'scripts': "dev": "next",
app/pages/index.jsx:
import Head from "next/head"
import CssBaseline from "#material-ui/core/CssBaseline"
import SearchBar from "../components/SearchBar"
const Index = () => (
<React.Fragment>
<Head>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charSet="utf-8" />
</Head>
<CssBaseline />
<SearchBar />
</React.Fragment>
)
export default Index
app/components/SearchBar.jsx:
import PropTypes from "prop-types"
import { withStyles } from "#material-ui/core/styles"
import TextField from "#material-ui/core/TextField"
const styles = (theme) => ({
container: {
display: "flex",
flexWrap: "wrap",
},
textField: {
margin: theme.spacing.unit / 2,
width: 200,
border: "2px solid red",
},
})
class SearchBar extends React.Component {
constructor(props) {
super(props)
this.state = { value: "" }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({ value: event.target.value })
}
handleSubmit(event) {
event.preventDefault()
}
render() {
const { classes } = this.props
return (
<form
className={classes.container}
noValidate
autoComplete="off"
onSubmit={this.handleSubmit}
>
<TextField
id="search"
label="Search"
type="search"
placeholder="Search..."
className={classes.textField}
value={this.state.value}
onChange={this.handleChange}
margin="normal"
/>
</form>
)
}
}
SearchBar.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(SearchBar)
Visit page in browser localhost:3000 and see this:
red border around TextField component
Refresh the browser and see this:
TextField component's styles are gone
Notice that the red border around TextField disappears.
Relevant Libs:
"react": 16.4.0
"react-dom": 16.4.0
"next": 6.0.3
"#material-ui/core": 1.2.0
The problem is the SSR rendering in Next.js, which produces the style fragment before the page is rendered.
Using Material UI and Next.js (as the author is using), adding a file called _document.js solved the problem.
Adjusted _document.js (as suggested here):
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '#material-ui/styles'; // works with #material-ui/core/styles, if you prefer to use it.
import theme from '../src/theme'; // Adjust here as well
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
{/* Not exactly required, but this is the PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with server-side generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// 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 {...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()],
};
};
This problem is related to MUI using dynamic class name which contain an ID. The IDs from the server side rendered CSS are not the same as the client side CSS, hence the mismatch error. A good start is to read the MUI SSR documentation
If you have this problem with nextjs (as I did) follow the example provided by the MUI team, which can be found here: material-ui/examples/nextjs
The most important part is in "examples/nextjs/pages/_app.js":
componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}
the related ticket can be found here: mui-org/material-ui/issues/15073
what it does, is remove the server side rendered stylesheet and replace it by a new client side rendered one
The issue is the server side generates the class names but style sheets are not automatically included in the HTML. You need to explicitly extract the CSS and append it to the UI for the server side rendered components. The whole process is explained here: https://material-ui.com/guides/server-rendering/
There is one other important, separate issue here: Material UI V4 is not React Strict Mode compatible. Strict mode compatibility is slated for version 5 with the adoption of the Emotion style engine.
Until then, be sure you disable React Strict Mode. If you're using Next.js, this is turned on by default if you've created your app using create-next-app.
// next.config.js
module.exports = {
reactStrictMode: false, // or remove this line completely
}
I had the same problem with Next.js and styled component, with the transpilation by Babel. Actually, the class names are different on the client and the server side.
Fix it in writing this in your .babelrc :
{
"presets": ["next/babel"],
"plugins": [
[
"styled-components",
{ "ssr": true, "displayName": true, "preprocess": false }
]
]
}
I met this problem on Material-ui V5. The solution to fix this problem is to make sure that class name generator needs to behave identically on the server and on the client.
so adding the code below in your _app.js:
import { StylesProvider, createGenerateClassName } from '#mui/styles';
const generateClassName = createGenerateClassName({
productionPrefix: 'c',
});
export default function MyApp(props) {
return <StylesProvider generateClassName={generateClassName}>...</StylesProvider>;
}
// 1 . Warning: prop classname did not match. Material ui with React Next.js
// 2 . Use your customization css here
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
title: {
flexGrow: 1,
},
my_examle_classssss: {
with: "100%"
}
}));
// 3 . Here my Component
const My_Example_Function = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<Container>
<Examle_Component> {/* !!! Examle_Component --> MuiExamle_Component*/}
</Examle_Component>
</Container>
</div>
);
}
export default My_Example_Function
// 4. Add name parameter to the makeStyles function
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
title: {
flexGrow: 1,
},
my_examle_classssss: {
with: "100%"
},
}), { name: "MuiExamle_ComponentiAppBar" });
{/* this is the parameter you need to add { name: "MuiExamle_ComponentiAppBar" } */ }
{/* The problem will probably be resolved if the name parameter matches the first className in the Warning: you recive..
EXAMPLE :
Warning: Prop `className` did not match.
Server: "MuiSvgIcon-root makeStyles-root-98"
Client: "MuiSvgIcon-root makeStyles-root-1"
The name parameter will be like this { name: "MuiSvgIcon" }
*/ }
I like to share this mismatching case:
next-dev.js?3515:32 Warning: Prop className did not match. Server:
"MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-12
MuiSwitch-switchBase MuiSwitch-colorSecondary" Client:
"MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-12
MuiSwitch-switchBase MuiSwitch-colorSecondary
PrivateSwitchBase-checked-13 Mui-checked"
On client there are two more classes which means that the behavior on client-side is different. In this case, this component shouldn't render on server-side. The solution is to dynamically render this component:
export default dynamic(() => Promise.resolve(TheComponent), { ssr: false });
I had a problem with different classNames for client and server. I was using React, Material-UI, makeStyles and SSR (server-side rendering).
The error was:
Warning: Prop `className` did not match. Server: "jss3" Client: "App-colNav-3"
I spent several hours before I figured out that I had discrepancy in webpack mode for client and server. The scripts in package.json were:
"devServer": "webpack --config webpack.server.config.js --mode=production --watch",
"devClient": "webpack --mode=development --watch",
After I changed both to have development mode, the problem was solved :)
"devServer": "webpack --config webpack.server.config.js --mode=development --watch",
"devClient": "webpack --mode=development --watch",
If somebody is still struggling even after trying above solutions, Try this
If you have used noSsr prop in any of your components or theme, then remove it.
I had the following config in mui theme object, which was causing this problem.
import { createTheme, responsiveFontSizes } from "#mui/material/styles";
let theme = createTheme({
components: {
MuiUseMediaQuery: {
defaultProps: {
noSsr: true,
},
},
},
palette: {
mode: "light",
common: {
black: "#000",
white: "#fff",
},
primary: {
main: "#131921",
contrastText: "#fff",
},
secondary: {
main: "#fb6a02",
contrastText: "#fff",
}
}
})
RemovingnoSSr fixed all of the issues in my app including style mismatch between client and server.
The problem is cause by Nextjs server side rendering. In order to solve I do as following:
Make a component to detect whether is it from Client side
import { useState, useEffect } from "react";
interface ClientOnlyProps {}
// #ts-ignore
const ClientOnly = ({ children }) => {
const [mounted, setMounted] = useState<boolean>(false);
useEffect(() => {
setMounted(true);
}, []);
return mounted ? children : null;
};
export default ClientOnly;
Wrap my page component using ClientOnly component
export default function App() {
return (
<ClientOnly>
<MyOwnPageComponent>
</ClientOnly>
);
}
So the idea is, if it is client side then only render the component on the page. Therefore if current rendering is from Client side, render <MyOwnPageComponent>, else render nothing
In my case the issue happened because of different compilation modes of webpack for client-side code and server-side: client's bundle was generated by webpack using "production" mode, while server ran some SSR code from a package optimized for "development". This created a different "className" hash in styled-components in generateAndInjectStyles():
if (process.env.NODE_ENV !== 'production') dynamicHash = phash(dynamicHash, partRule + i);
So my fix was just to align the webpack modes.
You can add the name in anywhere you use makeStyles, like this:
const useStyles = makeStyles({
card: {
backgroundColor: "#f7f7f7",
width: "33%",
},
title: {
color: "#0ab5db",
fontWeight: "bold",
},
description: {
fontSize: "1em"
}
}, { name: "MuiExample_Component" });
I am not sure how it works, but I found it here: Warning: Prop `className` did not match ~ Material UI css arbitrarily breaks on reload
I'm also using NextJS + MUI v5 and I ran into this exact error right after merging Git branches. I suspect the merge corrupted something in the cache. I deleted the contents of .next/ and restarted the dev server and the error went away.
#Leonel Sanches da Silva's answer didn't work for me, as #material-ui/styles is deprecated, but using a snippet I found for another (non-material UI) project seems to have worked just fine for me:
Hat tip to Raul Sanchez on dev.to for the answer to this one.
Next doesn't fetch styled-components styles on the server, to do that you need to add this page to pages/_document.js:
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
}
This code may update, so check Next's styled-components example for the latest.

How to bootstrap two Modules using bootstrapModule() in Angular2?

Normally this is how a Module is integrated or bootstrapped with the main.ts.
import {platformBrowserDynamic} from'#angular/platform-browser-dynamic'
import {AppModule} from './app.module'
platformBrowserDynamic().bootstrapModule(AppModule)
But in case we have tow modules say :
AppModule- which works with the UI related changes/ modificaitons
DataModule- which works to communicate/modify/display data related interfaces
Both AppModule and DataModule handle the UI modificaitons but being concerned with respective UI modification objectives, I want to work with two modules but at the same time.
How shall I begin with?
Will this approach be able to render both modules and perform independent operations?
at index.html
...
...
<body class="container">
<!--Listing Selectors for loading App-Module -->
<events-app></events-app>
<events-list></events-list>
<!-- listing Selectors for loading Data-Module -->
<events-data></events-data>
<filter-data></filter-data>
</body>
...
...
at main.ts
import {platformBrowserDynamic} from'#angular/platform-browser-dynamic'
import {AppModule} from './app.module'
import {DataModule} from './data.module'
platformBrowserDynamic().bootstrapModule(AppModule, DataModule)
Well I've did something like in my Angular 4 app by just doing some configuration in main.ts and tsconfig.json and its working perfectly fine. You can follow the below steps and can try.
Step 1: Create your module and declare root components which you want to load when you bootstrap that module.
Ex. Here I've created user.module.ts
import { NgModule } from '#angular/core';
// root component of usermodule
import { UserAppComponent } from './userapp.component';
#NgModule({
imports:[FormsModule,HttpModule],
declarations:[UserAppComponent],
providers:[],
bootstrap:[UserAppComponent]
})
export class UserModule { }
Step 2: Go to main.ts
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
import { UserModule } from './user.module';
window.platform = platformBrowserDynamic();
window.AppModule = AppModule;
window.UserModule = UserModule;
Step 3: Go to tsconfig.json and insert your newly created module and component in "files" array
"files":[
//....your other components ...//
"myapp/user.module.ts",
"myapp/userapp.component.ts",
]
Step 4: Now you are ready to bootstrap angular module wherever you want from your .js file. Like I've bootstrap like this from my .js file. Bootstrapping may differ based on your requirement but step 1 to 3 should be same.
window.platform.bootstrapModule(window.UserModule);

Resources