Mastering Microfrontends: Routing and Communication

Eric Bach
AMA Technology Blog
4 min readDec 12, 2022

One challenge with microfrontends is handling navigation and communication between the host and remote apps. In this post, we will explore how to route between authenticated and unauthenticated routes using react-router-dom and microfrontend communication practices.

This post will continue from the previous introductions to microfrontends found in my blog. The source code for this example app can be found in my GitHub repo here.

Photo by Ahmad Dirini on Unsplash

This sample microfrontend app will contain unauthenticated Landing and Pricing pages along with an authenticated Dashboard page. The Landing and Pricing pages are accessible even if a user is not signed in. The Dashboard is only accessible if a user is successfully signed in. Through the use of callbacks and controlling how each remote app is mounted, we can achieve this design using microfrontends.

Microfrontend routing between authenticated and unauthenticated parts of the application

In order to focus on microfrontend routing and communication, the authentication code, such as integration with AWS Cognito User Pools, has been excluded. This topic will be converted in the next blog post about microfrontend architectures.

Routing within the Unauthenticated App

The marketing app is the public home page that is accessible by any unauthenticated user. It contains a landing page with general information about the application and a pricing page that contains some detail about the different pricing plans. Both pages are built with a sample MUI v5 template. For details on how that was implemented please refer to the code in the repo.

From the remote app to the host app

The main part of the marketing app uses react-router-dom to manage the routing between the landing and pricing pages. This is fairly familiar to a traditional react app.

Marketing App — App.tsx

However, in order for the marketing app to signal to the host app that the route has changed, a callback function onNavigate is used. When the memory history changes from the marketing app, it makes a call to this callback function.

Marketing App — bootstrap.tsx

Upon receiving this callback, the host app updates the history if the path has changed. This allows both the host and remote apps to have the same state of the current path.

Host App — MarketingApp.tsx

From the host app to the remote app

To signal the marketing app that there is a change in the route from the host app, the onParentNavigate function updates the browser history whenever the path changes.

Marketing App — bootstrap.tsx

The host app contains a component that can mount the marketing app and will also listen for changes to history.

Host App — MarketingApp.tsx

Through the use of these callback functions we are able to update both the host and marketing app as the navigation changes.

Routing to the Authenticated App

The host app should manage the authentication and user session so that it can know which remote app to display and hide. When our user successfully authenticates to our app, we want to be able to display the dashboard app, which is only visible to authenticated users.

Creating the Auth App

To do this we first setup an Auth app that is responsible for managing the authentication components. This is found in the auth folder in the same project.

The Auth app contains several callback functions (onSignIn, onSignUp) to manage when a user has successfully signed in or signed up.

Auth App — bootrstrap.tsx

The Auth contains the routes to each path and passes the callback functions as props.

Auth App — App.tsx

Update the Host App Callback Functions

The AuthApp in the host app contains the callback functions that signal to that the user has successfully signed in or signed up.

Host App — AuthApp.tsx

The callback functions update the view in the host app to denote the authenticated user. The App component contains a React state hook to signal whether the user is authenticated or not.

If the user is authenticated the Header button changes to “Logout” instead of “Login” and the user is routed to the /home route containing the protected dashboard.

Host App — App.tsx

Conclusion

Communication between the host and remote apps within a microfrontend architecture is more complicated that a traditional monolithic frontend but with the use of callback functions it is easy to manage the routing and communication between each app.

In the next post, we will look at how we can leverage AWS Cognito User Pool to manage the authentication of users to this sample application.

References

Microfrontends with React: A Complete Developer’s Guide
https://www.udemy.com/course/microfrontend-course/

Eric Bach is a Senior Software Developer @ Alberta Motor Association who enjoys learning, reading, and writing about leadership principles, event-driven microservices, and all things AWS.

--

--

Eric Bach
AMA Technology Blog

Senior Software Developer @ amaabca | AWS Certified x 2 | Domain Driven Design | Event Driven Architecture | CQRS | Microservices