Loading remote React SPA module (mui theme object) into static props
Hey,
I have been struggling importing my remote MUI theme into my next js application for a while now. I managed to import it on the client side but this leads the HTML source code to only provide my loading indicator div. what i want is to load the theme as static prop and pass it into the whole application.
As far as i understood, i cant import the module in static props as it is a client side operation.
is there another way?
Thanks!
import { ThemeProvider } from '@mui/material';
import React, { useEffect } from 'react';
function MyApp({ Component, pageProps, remoteTheme }) {
const themeRef = React.useRef(false);
const [theme, setTheme] = React.useState(null);
console.log("remoteTheme")
console.log(remoteTheme)
useEffect(() => {
const loadTheme = async () => {
if (themeRef.current === false) {
try {
const sharedTheme = await import('theme/theme');
setTheme(sharedTheme.default);
} catch (error) {
console.error('Error loading shared theme', error);
}
}
themeRef.current = true;
};
loadTheme();
}, []);
if (!theme) {
// Return a loading indicator or any other UI element while waiting for the theme to load
return (
<div>
Loading theme...
</div>
);
}
return (
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
);
}
// !! this gives the following error
export default MyApp;
export async function getStaticProps() {
const { default: remoteTheme } = await import('theme/theme');
return {
props: {
remoteTheme
}
};
}
TypeError: __webpack_modules__[moduleId] is not a function
This error happened while generating the page. Any console logs will be displayed in the terminal window.
my package json
{
"name": "landing-page",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev -p 8084",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@module-federation/nextjs-mf": "5.2.1",
"@mui/icons-material": "^5.14.3",
"@mui/material": "^5.14.5",
"next": "12.3.4",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"eslint": "8.14.0",
"eslint-config-next": "12.1.5"
}
}
next config:
const NextFederationPlugin = require('@module-federation/nextjs-mf');
module.exports = {
webpack(config, options) {
const { isServer } = options;
config.plugins.push(
new NextFederationPlugin({
name: 'landing',
filename: 'static/chunks/remoteEntry.js',
exposes: {
'./NextApp': './pages/index.js',
"./BB8": "./components/BB8",
"./Button": "./components/Button",
"./ServicesCard": "./components/ServicesCard",
},
remotes: {
theme: 'theme@http://localhost:8085/remoteEntry.js',
},
shared: {
'@mui/material': {
singleton: true, // Ensure only one instance is loaded
},
react: {
requiredVersion: false,
singleton: true,
},
},
extraOptions: {
skipSharingNextInternals: true,
},
})
);
return config;
},
reactStrictMode: true,
};
Is remote online at compile time?
yes it is
Try sharing @mui/ with slash on end. To force anything starting with mui to share. It's usually internal module that needs to be singleton too as mui is large monorepo