# Communicate Between Micro Frontends

Recommended Learning

Entando supports communication between micro frontends (MFEs) using Custom Events (opens new window) and the entando-mfecommunication (opens new window) library. The MFEs can use either the same or different JavaScript frameworks.

In this tutorial, we build:

  • A React MFE that publishes an event
  • A React MFE that listens to an event

# Prerequisites

  • Two Entando Bundles based on the simple React tutorial, named publisher-mfe and subscriber-mfe as templates.

# Modify the Publisher MFE

# Create the Custom Event

  1. Add the mfecommunication library to the publisher-mfe by running this command within the microfrontends/publisher-mfe directory:
  npm install @entando/mfecommunication --save

Note: Direct CustomEvents could also be used, but this library requires less code and provides additional diagnostics when troubleshooting issues with MFE communications.

  1. To publish a custom event, modify the file publisher-mfe/src/custom-elements/WidgetElement.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from '../App';
import { mediatorInstance } from '@entando/mfecommunication';

const EVENTS = {
  greeting: 'greeting',
};

class WidgetElement extends HTMLElement {

  constructor() {
    super();
    this.onGreet = name => this.publishWidgetEvent(EVENTS.greeting, { name });
  }

  connectedCallback() {
    this.mountPoint = document.createElement('div');
    this.appendChild(this.mountPoint);
    this.render();
  }

  publishWidgetEvent(eventId, detail) {
    mediatorInstance.publish(eventId, detail);
  }

  render() {
    ReactDOM.render(<App onGreet={this.onGreet} />, this.mountPoint);
  }
}

customElements.define('publisher-mfe', WidgetElement);

export default WidgetElement;
  1. Confirm that the app renders in the browser:
ent bundle run publisher-mfe

# Dispatch the Custom Event

  1. Replace the contents of publisher-mfe/src/App.js to add an input field for use in the CustomEvent:
import React from 'react';
import './App.css';
   
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: ''};
  }

  handleNameChange(value) {
    this.setState(prevState => ({
      ...prevState,
      name: value,
    }));
  }

  render() {
    const { name } = this.state;
    const { onGreet } = this.props;
    return (
      <div>
        <h1>Send a greeting</h1>
        <label htmlFor="name">Name</label>
        <input id="name" onChange={e => this.handleNameChange(e.target.value)} value={name} />
        <button onClick={() => onGreet(name)}>Say hello!</button>
      </div>
    );
  }
}

export default App;
  1. In the JavaScript console of your browser, enter the following:
  window.entando.globals.mediator.subscribe("greeting", {
      callerId: "subscriberA",
      callback: (data) => console.log('Subscriber A received:', data),
  });
  1. To test the event dispatcher, write something in the text field and click the "Say hello!" button

  2. Confirm that the event message appears in the JS console

Congratulations!

You’ve now published a custom event.

# Modify the Subscriber MFE

# Create the Event Listener

  1. Add the mfecommunication library to the subscriber-mfe by running this command within the microfrontends/subscriber-mfe directory:
  npm install @entando/mfecommunication --save
  1. To add an event listener, create the file subscriber-mfe/src/custom-elements/WidgetElement.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from '../App';
import { mediatorInstance } from '@entando/mfecommunication';

const EVENTS = {
  greeting: 'greeting',
};

class WidgetElement extends HTMLElement {

  constructor() {
    super();
    this.name = null;

    this.subscribeToWidgetEvent(EVENTS.greeting, (evt) => this.onGreeting(evt.name));
  }

  connectedCallback() {
    this.mountPoint = document.createElement('div');
    this.appendChild(this.mountPoint);
    this.render();
  }

  subscribeToWidgetEvent(eventType, eventHandler) {
    mediatorInstance.subscribe(eventType, {
        callerId: "subscriber-mfe",
        callback: eventHandler
    });
  }

  onGreeting(name) {
    this.name = name;
    this.render();
  }

  render() {
    ReactDOM.render(<App name={this.name} />, this.mountPoint);
  }
}

customElements.define('subscriber-mfe', WidgetElement);

export default WidgetElement;
  1. Confirm the app renders in the browser by using ent bundle run subscriber-mfe

# Display the Custom Event

  1. Replace the contents of subscriber-mfe/src/App.js:
import React from 'react';
import './App.css';

function App({ name }) {
  return name ? (<h2>Just got a greeting from {name}</h2>)
    : (<h2>Waiting for a greeting...</h2>);
}

export default App;
  1. To test the event listener, enter the following code in the JavaScript console of your browser:
window.entando.globals.mediator.publish('greeting', {name:'Pippo'});
  1. Confirm the custom event is displayed in the subscriber-mfe

Congratulations!

You’ve now created a micro frontend that listens to custom events.

# Add Widgets to App Builder

To add the publisher and subscriber MFEs to Entando, run the following commands from the root folder of each:

ent bundle pack
ent bundle publish
ent bundle deploy
ent bundle install

Refer to the tutorial on how to publish a bundle project for more detailed instructions.

# View on a Page

Place the widgets on an existing page or create your own page. The following steps use the Home page simply as an example.

  1. Go to PagesManagement

  2. On the line item for the Home page, in the Actions column, click the icon

  3. Select Edit

  4. In the Settings section, select a Page Template with more than one frame

  5. Click Save and Design

  6. From the Widgets tab in the right sidebar, drag your publisher and subscriber widgets into Frame 1 and Frame 2

  7. Click Publish

  8. To view the Home page, click View Published Page at the top of the page

  9. Enter a name in the input field and click the "Say hello!" button

  10. Confirm that the subscriber widget updates to display the name

Congratulations!

You can now communicate between micro frontends using custom events!