#1 Data Analytics Program in India
₹2,499₹1,499Enroll Now
11 min read
•Question 43 of 47hard

Micro-Frontends with Next.js

Implementing micro-frontend architecture.

Micro-Frontends

Module Federation

code.txtTSX
// next.config.js (host)
const NextFederationPlugin = require('@module-federation/nextjs-mf');

module.exports = {
  webpack(config, options) {
    config.plugins.push(
      new NextFederationPlugin({
        name: 'host',
        remotes: {
          shop: 'shop@http://localhost:3001/_next/static/chunks/remoteEntry.js',
          blog: 'blog@http://localhost:3002/_next/static/chunks/remoteEntry.js',
        },
        shared: {
          react: { singleton: true },
          'react-dom': { singleton: true },
        },
      })
    );
    return config;
  },
};

// Using remote component
const RemoteShop = dynamic(() => import('shop/ProductList'), {
  ssr: false,
});

export default function Page() {
  return <RemoteShop />;
}

Multi-Zone Deployment

code.txtTSX
// Main app - next.config.js
module.exports = {
  async rewrites() {
    return [
      {
        source: '/blog/:path*',
        destination: 'https://blog.example.com/:path*',
      },
      {
        source: '/shop/:path*',
        destination: 'https://shop.example.com/:path*',
      },
    ];
  },
};

// Each zone is a separate Next.js app
// with its own deployment

Iframe Isolation

code.txtTSX
// For complete isolation
export function MicroFrontend({ src }: { src: string }) {
  return (
    <iframe
      src={src}
      style={{ width: '100%', height: '100vh', border: 'none' }}
      sandbox="allow-scripts allow-same-origin allow-forms"
    />
  );
}

// Communication via postMessage
window.parent.postMessage({ type: 'navigate', url: '/checkout' }, '*');

Shared Component Library

code.txtTSX
// packages/ui/Button.tsx
export function Button({ children, ...props }) {
  return <button className="btn-primary" {...props}>{children}</button>;
}

// In each micro-frontend
import { Button } from '@company/ui';