This document will take you step-by-step through the tasks required to set up a module federation module, with react app as host with NextJS and React Apps as remote apps. This document's how-to will show you the failing issues I encountered and how I solve them; I hope it will help others when they try to do the same.
* Disclaimer for NextJS apps you need the latest version of @module-federation/nextjs-mf that is a paid module, you can read more here
📦 Prerequisites
- Knowledge in Module Federation Concepts and miro-frontends
 - NodeJS installed (preferable > 14)
 - 
2 Running React App with access to
webpack.config.js- Preferable not created using CRA(create react app)
 - At least one React Component
 - One will be the host app
 - The other will a remote app
 
 - 
Running NextJS App
- At least one React Component
 - This will be the remote app
 
 Basic Knowledge in Webpack
License for
@module-federation/nextjs-mf
Terminology
⬇️ Host:  It is a top-level app that depends on modules exposed from a remote app
⬆️ Remote: Exposes components to another app called a host.
⬆️ Configuring Remote App - NextJS
- Use 
withFederatedSidecarin yournext.config.jsof the app that you wish to expose modules from. We'll call this "remote_nextjs_module". 
    const { withFederatedSidecar } = require("@module federation/nextjs-mf");
    module.exports = withFederatedSidecar({
        name: "remote_nextjs_module",
        filename: "static/chunks/remoteEntry.js",
        exposes: {
            "./BB8": "./components/BB8.js",
        },
        shared: {
        },
    })({
        // your original next.config.js export
        reactStrictMode: true,
    });
⬆️ Configuring Remote App - React
- Use 
ModuleFederationPluginin yourwebpack.config.jsof the app that you wish to expose modules from. We'll call this "remote_react_module". - I'm demonstrating here only the implementation of 
ModuleFederationPluginand not adding all the configuration ofwebpack.config.jsof the app 
    const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;
    plugins: [
        new ModuleFederationPlugin({
            name: 'remote_react_module',
            filename: 'RemoteEntry.js',
            exposes: {
                './Kylo': './src/components/Kylo',
            },
            shared: {
            },
        }),
⬇️ Configuring Host App Host - React
- Use 
ModuleFederationPluginin yourwebpack.config.jsof the app that you wish to consume modules. We'll call this "host_react_module". - I'm demonstrating here only the implementation of 
ModuleFederationPluginand not adding all the configuration ofwebpack.config.jsof the app 
    const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;
    // your original webpack.config.js configuration
    plugins: [
        new ModuleFederationPlugin({
            name: 'host_react_module',
            filename: 'remoteEntry.js',
            remotes: {
                remote_nextjs_module: 'remote_nextjs_module@http://localhost:8081/_next/static/chunks/remoteEntry.js',
                remote_react_module: 'remote_react_module@http://localhost:8082/remoteEntry.js',
            },
        shared: {
            react: {
            // Notice shared are NOT eager here.
               requiredVersion: false,
               singleton: true,
        },
    },
    }),
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],
- 
📝 Configure HTML
- Go to your 
HTMLfile and add the following 
<noscript id="__next_css__DO_NOT_USE__"></noscript>- By default NextJS adds a meta tag in its HTML called: 
__next_css__DO_NOT_USE__to their HTML files - We need this tag on our non next apps so the injector can find and load 
cssbelow that tag 
 - Go to your 
 Go to your component in the React Host App where you want to consume the remote components
Use
React.lazyor low level api to import remotes.
    import React, { Suspense } from 'react';
    const Kylo = React.lazy(() => import('remote_react_module/Kylo'));
    const BB8 = React.lazy(() => import('remote_nextjs_module/BB8'));
    function App() {
        return (
            <>
                <Suspense fallback={'loading...'}>
                    <BB8 />
                    <Kylo />
                </Suspense>
            </>
            );
    }
export default App;
🎉 Result
- I have a 
ReactHost App that consumes two remote components and one local component, here - One component from a 
NextJSRemote App, here - One component from a 
ReactRemote App, here - One component from the host App
 
⛑️ Troubleshooting
- Uncaught Error: Shared module is not available for eager consumption
Solution
For example, your entry looked like this:
- 
index.js 
    import App from './App';
    import React from 'react';
    import { createRoot } from 'react-dom/client';
    const container = document.getElementById('root');
    const root = createRoot(container);
    root.render(<App />);
- Let's create 
bootstrap.jsfile and move contents of the entry into it, and import that bootstrap into the entry: - 
index.js 
    import('./bootstrap');
- 
bootstrap.js 
    import App from './App';
    import React from 'react';
    import { createRoot } from 'react-dom/client';
    const container = document.getElementById('root');
    const root = createRoot(container);
    root.render(<App />);
- More in here
 
- Uncaught (in promise) TypeError: Cannot read properties of null (reading 'parentNode')
Solution
- By default 
NextJSadds a meta tag in itsHTMLcalled:__next_css__DO_NOT_USE__to theirHTMLfiles We need that tag on our non next apps so the injector can find and load
cssbelow that tagindex.html- non next app
    <!DOCTYPE html>
    <html lang="en">
        <head> </head>
        <noscript id="__next_css__DO_NOT_USE__"></noscript>
        <body>
            <div id="root"></div>
        </body>
    </html>
- Getting 404 for remotes Components
Solution
- 
webpackthinks public path is/which is wrong. You want it to calculate the path based ondocument.currentScript.src - Set 
publicPath:autoin yourwebpack.config.js - Not adding all the configuration of 
webpack.config.jsof the app 
    output: {
        publicPath: 'auto',
    },
🔗 Resources
- Github repo link
 - App
- Host: Link for React App Hosted at Vercel
 - Remote: For NextJS App Hosted at Vercel
 - Remote App: For React App Hosted at Vercel
 
 - Module Federation Examples
 
              




    
Top comments (8)
Hi, thank you for the article. The links are not working.
Thanks,
Links are working now
Thanks for your input
Hi, this article is a super nice work, thank you!
I'm trying to use this solution with single-spa with no success. Have you tried this with single-spa?
Any with the same idea can help me with this in this question?
Thanks, is there any other solution for module-federation/nextjs-mf?
Not that I'm aware, also myself was researching/looking, and in the end, all the solutions/forum sent me back to use the plugin.
Looks like this plugin is free now npmjs.com/package/@module-federati...
Hi Omher,
How to share Router from nextJS to React.
i.e.
React as host app
NextJS - Top level component exposed with router.
Getting error on Host -
router.js?31fc:146 Uncaught Error: NextRouter was not mounted. nextjs.org/docs/messages/next-rout...
at useRouter (router.js?31fc:146:15)
Any solution would be appreciated
Thanks
I am getting this error while consuming in host app in react app only.
How to resolve this?