Contents
In modern web development, the micro-frontend architecture has gained popularity due to its modularity, scalability, and ability to develop large applications as a composition of smaller, independent applications. However, one of the challenges with this approach is sharing state across these micro-frontends in an efficient and secure way.
Enter MicroLocalStore, a lightweight JavaScript library that provides a shared local storage solution across different origins. In this article, we’ll explore how to use MicroLocalStore to share state between micro-frontends, enabling seamless communication and state management.
What is MicroLocalStore?
MicroLocalStore is a JavaScript library that creates an isolated local storage for each instance, allowing you to store and retrieve data seamlessly across different origins. It’s designed specifically for micro-frontend architectures, enabling different micro-apps to share state without conflicts.
With MicroLocalStore, you can easily manage state listeners, send and receive messages between parent and child windows, and more. It’s compatible with both browser and Node.js environments.
Installation
You can install MicroLocalStore using npm:
npm install micro-local-store
Alternatively, you can use the unpkg CDN in your HTML file:
<script src="https://unpkg.com/micro-local-store"></script>
Usage
Let’s dive into a simple example to understand how MicroLocalStore works.
Setting Up MicroLocalStore
First, we need to create a new instance of MicroLocalStore and provide a unique identifier and an array of allowed URLs that can share the store’s state.
const store = new MicroLocalStore("myStore", [
"https://example.com",
"https://another-example.com",
]);
Setting and Getting State
You can set the state using the setState
method, which will merge the new state with the existing state.
store.setState({ key: "value" });
To retrieve the current state, use the getState
method.
const state = store.getState();
Listening for State Changes
MicroLocalStore allows you to listen for state changes by registering a listener function with the onChange
method.
store.onChange((newState) => {
console.log(newState);
});
You can remove a listener function by calling the offChange
method.
store.offChange(listener);
Example: Sharing State Between Micro Frontends
Let’s consider a scenario where we have two micro-frontends, App1.html
and App2.html
, hosted on the different domains (https://example.com
, https://another-example.com
). We want to share state between these two micro-frontends using MicroLocalStore.
App1.html
<!DOCTYPE html>
<html>
<body>
<button id="trigger">Trigger State Change</button>
<div id="state"></div>
<script src="https://unpkg.com/micro-local-store"></script>
<script>
const store = new MicroLocalStore("myStore", [
"https://example.com/App1.html",
"https://another-example.com/App2.html"
]);
// Get state
const state = store.getState();
document.getElementById("state").innerHTML = JSON.stringify(state);
// Listen for state changes
store.onChange((newState) => {
document.getElementById("state").innerHTML = JSON.stringify(newState);
});
// Set state on button click
document.getElementById("trigger").addEventListener("click", () => {
store.setState({ key: "value from App1" });
});
</script>
</body>
</html>
App2.html
<!DOCTYPE html>
<html>
<body>
<button id="trigger">Trigger State Change</button>
<div id="state"></div>
<script src="https://unpkg.com/micro-local-store"></script>
<script>
const store = new MicroLocalStore("myStore", [
"https://example.com/App1.html",
"https://another-example.com/App2.html"
]);
// Get state
const state = store.getState();
document.getElementById("state").innerHTML = JSON.stringify(state);
// Listen for state changes
store.onChange((newState) => {
document.getElementById("state").innerHTML = JSON.stringify(newState);
});
// Set state on button click
document.getElementById("trigger").addEventListener("click", () => {
store.setState({ key: "value from App2" });
});
</script>
</body>
</html>
In this example, both App1.html
and App2.html
create a new instance of MicroLocalStore with the same identifier ("myStore"
). They also specify the URLs of the other micro-frontend that is allowed to share the state.
Each micro-frontend listens for state changes using the onChange
method and updates its UI accordingly. When the “Trigger State Change” button is clicked, it sets a new state using the setState
method, which will be reflected in both micro-frontends.
Cross-Origin Resource Sharing (CORS)
MicroLocalStore uses the postMessage
API to communicate between different windows. This requires that the server hosting your application allows the URLs of the other applications to access your application. This is controlled by the server’s CORS policy.
When creating a new MicroLocalStore instance, you must provide an array of URLs that are allowed to share the store’s state. These URLs must be allowed by the server’s CORS policy.
If you’re using Express.js, you can use the cors
middleware to set up your CORS policy. Here’s an example:
const express = require("express");
const cors = require("cors");
const app = express();
const corsOptions = {
origin: ["https://example.com", "https://another-example.com"],
};
app.use(cors(corsOptions));
// Your routes here
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
In this example, https://example.com
and https://another-example.com
are allowed to access your application.
Conclusion
MicroLocalStore provides a simple and efficient way to share state across micro-frontends, enabling seamless communication and state management. By creating an isolated local storage for each instance and allowing cross-origin communication, MicroLocalStore makes it easy to build modular and scalable web applications using the micro-frontend architecture.
Give MicroLocalStore a try in your next micro-frontend project and experience the power of shared state management across independent applications.
[fluentform id="8"]