DEV Community

Cover image for Unlock Cross-Micro-Frontend State Sharing!
Trinmar Boado
Trinmar Boado

Posted on

Unlock Cross-Micro-Frontend State Sharing!

Sharing State Across Micro Frontends with MicroLocalStore

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.

MicroLocalStore Demo

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
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can use the unpkg CDN in your HTML file:

<script src="https://unpkg.com/micro-local-store"></script>
Enter fullscreen mode Exit fullscreen mode

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",
]);
Enter fullscreen mode Exit fullscreen mode

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" });
Enter fullscreen mode Exit fullscreen mode

To retrieve the current state, use the getState method.

const state = store.getState();
Enter fullscreen mode Exit fullscreen mode

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);
});
Enter fullscreen mode Exit fullscreen mode

You can remove a listener function by calling the offChange method.

store.offChange(listener);
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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");
});
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)