Mastering Microfrontends: Routing and Communication
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.
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.
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.
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.
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.
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.
The host
app contains a component that can mount the marketing
app and will also listen for changes to history.
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.
The Auth
contains the routes to each path and passes the callback functions as props.
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.
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.
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.